dreamcontext 0.8.3 → 0.8.5

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 (127) hide show
  1. package/README.md +2 -1
  2. package/agents/sleep-product.md +23 -0
  3. package/agents/sleep-tasks.md +31 -12
  4. package/dist/agents/sleep-product.md +23 -0
  5. package/dist/agents/sleep-tasks.md +31 -12
  6. package/dist/dashboard/assets/{BrainCanvas3D-CoTzHqzT.js → BrainCanvas3D-D8PjCqhM.js} +1 -1
  7. package/dist/dashboard/assets/{_baseUniq-BlQ6XWxs.js → _baseUniq-Bh1FtvZ1.js} +1 -1
  8. package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-C4qyHe9L.js → ar-SA-G6X2FPQ2-B2U2zDyG.js} +1 -1
  9. package/dist/dashboard/assets/{arc-uGukQNxI.js → arc-CjP2r6kV.js} +1 -1
  10. package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-BhtWTFvf.js → architectureDiagram-Q4EWVU46-NKSTolLw.js} +1 -1
  11. package/dist/dashboard/assets/{az-AZ-76LH7QW2-HfK2pIVQ.js → az-AZ-76LH7QW2-DVg6avJ2.js} +1 -1
  12. package/dist/dashboard/assets/{bg-BG-XCXSNQG7-L7TlhXli.js → bg-BG-XCXSNQG7-DGe9j5k-.js} +1 -1
  13. package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-BmPhQEp6.js → blockDiagram-DXYQGD6D-9TIN16so.js} +1 -1
  14. package/dist/dashboard/assets/{bn-BD-2XOGV67Q-DE0uNoU6.js → bn-BD-2XOGV67Q-gu4ZPvYK.js} +1 -1
  15. package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-DtQKYrmP.js → c4Diagram-AHTNJAMY-CnCRm_Qw.js} +1 -1
  16. package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-7JHCTA6b.js → ca-ES-6MX7JW3Y-DkBWO2rb.js} +1 -1
  17. package/dist/dashboard/assets/channel-CvynutAQ.js +1 -0
  18. package/dist/dashboard/assets/{chunk-4BX2VUAB-BvnLY9qE.js → chunk-4BX2VUAB-DWsjDEg5.js} +1 -1
  19. package/dist/dashboard/assets/{chunk-4TB4RGXK--piiFXgS.js → chunk-4TB4RGXK-BsxBp2-h.js} +1 -1
  20. package/dist/dashboard/assets/{chunk-55IACEB6-C7uvmawY.js → chunk-55IACEB6-DSTYhHTs.js} +1 -1
  21. package/dist/dashboard/assets/{chunk-EDXVE4YY-BuWBKOPY.js → chunk-EDXVE4YY-9RDG5so7.js} +1 -1
  22. package/dist/dashboard/assets/{chunk-FMBD7UC4-C1Le6hxh.js → chunk-FMBD7UC4-BQQGv7tV.js} +1 -1
  23. package/dist/dashboard/assets/{chunk-OYMX7WX6-B8JE8Wz4.js → chunk-OYMX7WX6-B62jTGjc.js} +1 -1
  24. package/dist/dashboard/assets/{chunk-QZHKN3VN-U9FJi59p.js → chunk-QZHKN3VN-CgTBTZrW.js} +1 -1
  25. package/dist/dashboard/assets/{chunk-YZCP3GAM-BNc94uy1.js → chunk-YZCP3GAM-3Dg1saYb.js} +1 -1
  26. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DWhdz8wj.js +1 -0
  27. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DWhdz8wj.js +1 -0
  28. package/dist/dashboard/assets/clone-DJK7V3ll.js +1 -0
  29. package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-D0hUzBCj.js → cose-bilkent-S5V4N54A-B3idOsw5.js} +1 -1
  30. package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-B0rWHDIi.js → cs-CZ-2BRQDIVT-xyFkB9a5.js} +1 -1
  31. package/dist/dashboard/assets/{da-DK-5WZEPLOC-D_PQO_T0.js → da-DK-5WZEPLOC-B3hFYjJY.js} +1 -1
  32. package/dist/dashboard/assets/{dagre-KV5264BT-B_bjkEDQ.js → dagre-KV5264BT-BoSSN-hv.js} +1 -1
  33. package/dist/dashboard/assets/{de-DE-XR44H4JA-D1G4J6Mz.js → de-DE-XR44H4JA-Bkx00nEq.js} +1 -1
  34. package/dist/dashboard/assets/{diagram-5BDNPKRD-B63uEoiS.js → diagram-5BDNPKRD-Buj8iksu.js} +1 -1
  35. package/dist/dashboard/assets/{diagram-G4DWMVQ6-DShdwm3D.js → diagram-G4DWMVQ6-DRBYjDWl.js} +1 -1
  36. package/dist/dashboard/assets/{diagram-MMDJMWI5-DdVsHQ-l.js → diagram-MMDJMWI5-DdlofmeO.js} +1 -1
  37. package/dist/dashboard/assets/{diagram-TYMM5635-BdHifyqU.js → diagram-TYMM5635-C8y8IvnA.js} +1 -1
  38. package/dist/dashboard/assets/{el-GR-BZB4AONW-a0CO4RfB.js → el-GR-BZB4AONW-SsFgxQNu.js} +1 -1
  39. package/dist/dashboard/assets/{erDiagram-SMLLAGMA-CYxdxNcb.js → erDiagram-SMLLAGMA-OZ3J3PG9.js} +1 -1
  40. package/dist/dashboard/assets/{es-ES-U4NZUMDT-ejRYVYRf.js → es-ES-U4NZUMDT-BInO41Bx.js} +1 -1
  41. package/dist/dashboard/assets/{eu-ES-A7QVB2H4-B-4OXJLd.js → eu-ES-A7QVB2H4-DjjnJ8cU.js} +1 -1
  42. package/dist/dashboard/assets/{fa-IR-HGAKTJCU-DhOcLy7v.js → fa-IR-HGAKTJCU-BjCsO05-.js} +1 -1
  43. package/dist/dashboard/assets/{fi-FI-Z5N7JZ37-CKQF9xKf.js → fi-FI-Z5N7JZ37-kAJ6_O9R.js} +1 -1
  44. package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-azQUtREP.js → flowDiagram-DWJPFMVM-BvvULyyH.js} +1 -1
  45. package/dist/dashboard/assets/{fr-FR-RHASNOE6-CsGekBXq.js → fr-FR-RHASNOE6-CrZukXCy.js} +1 -1
  46. package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-DjXmGcb4.js → ganttDiagram-T4ZO3ILL-Sv7sneaT.js} +1 -1
  47. package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-Dz87wo6e.js → gitGraphDiagram-UUTBAWPF-BWplv5am.js} +1 -1
  48. package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-NRfsjlmW.js → gl-ES-HMX3MZ6V-CY3NLwyQ.js} +1 -1
  49. package/dist/dashboard/assets/{graph-BMW3t-Jz.js → graph-DU5PqGxo.js} +1 -1
  50. package/dist/dashboard/assets/{he-IL-6SHJWFNN-CK4gfEss.js → he-IL-6SHJWFNN-DcuQngSU.js} +1 -1
  51. package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-CqyBl1jA.js → hi-IN-IWLTKZ5I-DKr_uuss.js} +1 -1
  52. package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-BO0SthvO.js → hu-HU-A5ZG7DT2-CgZklxQN.js} +1 -1
  53. package/dist/dashboard/assets/{id-ID-SAP4L64H-CrHxJe1s.js → id-ID-SAP4L64H-BFYAclqc.js} +1 -1
  54. package/dist/dashboard/assets/index-CPZ-rEGO.js +480 -0
  55. package/dist/dashboard/assets/{index-B0pCDfL8.js → index-DhbH7HLB.js} +1 -1
  56. package/dist/dashboard/assets/index-DrwAz5zg.css +1 -0
  57. package/dist/dashboard/assets/{infoDiagram-42DDH7IO-zG-8q9HR.js → infoDiagram-42DDH7IO-DcL21hYD.js} +1 -1
  58. package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-5OzPmL1c.js → ishikawaDiagram-UXIWVN3A-CP4-Ha6a.js} +1 -1
  59. package/dist/dashboard/assets/{it-IT-JPQ66NNP-CW6fpZrT.js → it-IT-JPQ66NNP-DgbO8z_0.js} +1 -1
  60. package/dist/dashboard/assets/{ja-JP-DBVTYXUO-DMJRiMhd.js → ja-JP-DBVTYXUO-2nM4bVbo.js} +1 -1
  61. package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-f8lbDQ22.js → journeyDiagram-VCZTEJTY-CZV9JSbl.js} +1 -1
  62. package/dist/dashboard/assets/{kaa-6HZHGXH3-C4yr2X6j.js → kaa-6HZHGXH3-DyVkacqp.js} +1 -1
  63. package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-BtwhZ5Ak.js → kab-KAB-ZGHBKWFO-CqnQNV46.js} +1 -1
  64. package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-BJtF1llZ.js → kanban-definition-6JOO6SKY-CMFYpVon.js} +1 -1
  65. package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-BiS5ISFw.js → kk-KZ-P5N5QNE5-CKaF_obh.js} +1 -1
  66. package/dist/dashboard/assets/{km-KH-HSX4SM5Z-CJcAjj0D.js → km-KH-HSX4SM5Z-DX5TUZuC.js} +1 -1
  67. package/dist/dashboard/assets/{ko-KR-MTYHY66A-yw6XRj7m.js → ko-KR-MTYHY66A-DX2Igsee.js} +1 -1
  68. package/dist/dashboard/assets/{ku-TR-6OUDTVRD-nAwdHGyN.js → ku-TR-6OUDTVRD-B0tZGs6G.js} +1 -1
  69. package/dist/dashboard/assets/{layout-guqP2e-e.js → layout-3g_7BoW1.js} +1 -1
  70. package/dist/dashboard/assets/{linear-W2_Ct9N6.js → linear-CXZ_mpWm.js} +1 -1
  71. package/dist/dashboard/assets/{lt-LT-XHIRWOB4-D7h1NJrv.js → lt-LT-XHIRWOB4-BzCZwLwu.js} +1 -1
  72. package/dist/dashboard/assets/{lv-LV-5QDEKY6T-DJfUJgRc.js → lv-LV-5QDEKY6T-Dn-Fj6_V.js} +1 -1
  73. package/dist/dashboard/assets/{min-BlLHklQU.js → min-bJtV9AiD.js} +1 -1
  74. package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-Ch2AO4mc.js → mindmap-definition-QFDTVHPH-Dz61NELW.js} +1 -1
  75. package/dist/dashboard/assets/{mr-IN-CRQNXWMA-BV3znx0p.js → mr-IN-CRQNXWMA-D8KTtR8X.js} +1 -1
  76. package/dist/dashboard/assets/{my-MM-5M5IBNSE-IjUN-e5U.js → my-MM-5M5IBNSE-BbCYwFaj.js} +1 -1
  77. package/dist/dashboard/assets/{nb-NO-T6EIAALU-MMsvbc2a.js → nb-NO-T6EIAALU-DEJxZlzk.js} +1 -1
  78. package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-ByYTJGOK.js → nl-NL-IS3SIHDZ-DTQekKhh.js} +1 -1
  79. package/dist/dashboard/assets/{nn-NO-6E72VCQL-Bgbgzvhm.js → nn-NO-6E72VCQL-Otz1_Q7Y.js} +1 -1
  80. package/dist/dashboard/assets/{oc-FR-POXYY2M6-BMBbvfQp.js → oc-FR-POXYY2M6-BO1pOtcy.js} +1 -1
  81. package/dist/dashboard/assets/{pa-IN-N4M65BXN-CgcUC9Zd.js → pa-IN-N4M65BXN-o_zcafD8.js} +1 -1
  82. package/dist/dashboard/assets/{percentages-BXMCSKIN-AuedyVVS.js → percentages-BXMCSKIN-C9aZbplb.js} +7 -7
  83. package/dist/dashboard/assets/{pica-DxO5y0j_.js → pica-B0_4dS6Q.js} +1 -1
  84. package/dist/dashboard/assets/{pieDiagram-DEJITSTG-q-J8tI3B.js → pieDiagram-DEJITSTG-CMwhT31D.js} +1 -1
  85. package/dist/dashboard/assets/{pl-PL-T2D74RX3-BaZSYTKJ.js → pl-PL-T2D74RX3-CvJKdZLx.js} +1 -1
  86. package/dist/dashboard/assets/{pt-BR-5N22H2LF-DSPF7aLm.js → pt-BR-5N22H2LF-DH69aomh.js} +1 -1
  87. package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-aoPTHC3m.js → pt-PT-UZXXM6DQ-Bt_HMT7S.js} +1 -1
  88. package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-CGbfFson.js → quadrantDiagram-34T5L4WZ-BdXgbSGH.js} +1 -1
  89. package/dist/dashboard/assets/{requirementDiagram-MS252O5E-ThxVmoCe.js → requirementDiagram-MS252O5E-Bq0YQege.js} +1 -1
  90. package/dist/dashboard/assets/{ro-RO-JPDTUUEW-YfCwiIS2.js → ro-RO-JPDTUUEW-DetQ1m4p.js} +1 -1
  91. package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-zIVsVhsz.js → ru-RU-B4JR7IUQ-B744z7Cd.js} +1 -1
  92. package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-BvEv917s.js → sankeyDiagram-XADWPNL6-CTYt5Kku.js} +1 -1
  93. package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-JrhjN3MG.js → sequenceDiagram-FGHM5R23-BbPhy9K6.js} +1 -1
  94. package/dist/dashboard/assets/{si-LK-N5RQ5JYF-CegSAwip.js → si-LK-N5RQ5JYF-DueeMRG5.js} +1 -1
  95. package/dist/dashboard/assets/{sk-SK-C5VTKIMK-C_K-Uoai.js → sk-SK-C5VTKIMK-BivWC8UI.js} +1 -1
  96. package/dist/dashboard/assets/{sl-SI-NN7IZMDC-DHGXOoZl.js → sl-SI-NN7IZMDC-CHxsSSJQ.js} +1 -1
  97. package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-BzOtZESp.js → stateDiagram-FHFEXIEX-DAPXkQkR.js} +1 -1
  98. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-ZA5uLv7f.js +1 -0
  99. package/dist/dashboard/assets/{subset-shared.chunk-BWfXaC19.js → subset-shared.chunk-CxWeBga7.js} +1 -1
  100. package/dist/dashboard/assets/{subset-worker.chunk-DHcqLDUZ.js → subset-worker.chunk-V3gpxiYs.js} +1 -1
  101. package/dist/dashboard/assets/{sv-SE-XGPEYMSR-BoNob2y3.js → sv-SE-XGPEYMSR-C-EJgqb-.js} +1 -1
  102. package/dist/dashboard/assets/{ta-IN-2NMHFXQM-C8UHJYct.js → ta-IN-2NMHFXQM-DAjiKKkH.js} +1 -1
  103. package/dist/dashboard/assets/{th-TH-HPSO5L25-D7wP1iSi.js → th-TH-HPSO5L25-Bq7BADtY.js} +1 -1
  104. package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-Gwb0w7bX.js → timeline-definition-GMOUNBTQ-BJhY_iVV.js} +1 -1
  105. package/dist/dashboard/assets/{tr-TR-DEFEU3FU-He51QB-L.js → tr-TR-DEFEU3FU--adx_Tct.js} +1 -1
  106. package/dist/dashboard/assets/{uk-UA-QMV73CPH-Blg5n9CR.js → uk-UA-QMV73CPH-DfnkGhht.js} +1 -1
  107. package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-y2S0dZjp.js → vennDiagram-DHZGUBPP-BpuWdXIB.js} +1 -1
  108. package/dist/dashboard/assets/{vi-VN-M7AON7JQ-2z-4xcM3.js → vi-VN-M7AON7JQ-RQSwYL0s.js} +1 -1
  109. package/dist/dashboard/assets/{wardley-RL74JXVD-BNThyuCt.js → wardley-RL74JXVD-BuB77QmE.js} +1 -1
  110. package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-Sljri5hz.js → wardleyDiagram-NUSXRM2D-BomUXaGE.js} +1 -1
  111. package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-BIFYd4_d.js → xychartDiagram-5P7HB3ND-BueWOzBo.js} +1 -1
  112. package/dist/dashboard/assets/{zh-CN-LNUGB5OW-DZ8sfmlq.js → zh-CN-LNUGB5OW-Bq_CyCdn.js} +1 -1
  113. package/dist/dashboard/assets/{zh-HK-E62DVLB3-Zvqwoloz.js → zh-HK-E62DVLB3-dhMk2wl1.js} +1 -1
  114. package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-Ck_uDtMQ.js → zh-TW-RAJ6MFWO-BTBKc5WB.js} +1 -1
  115. package/dist/dashboard/index.html +2 -2
  116. package/dist/index.js +851 -633
  117. package/dist/skill-packs/goal-skill/SKILL.md +8 -6
  118. package/package.json +1 -1
  119. package/skill/SKILL.md +3 -3
  120. package/skill-packs/goal-skill/SKILL.md +8 -6
  121. package/dist/dashboard/assets/channel-3OfE-PZ3.js +0 -1
  122. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-Dpt9qwZI.js +0 -1
  123. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-Dpt9qwZI.js +0 -1
  124. package/dist/dashboard/assets/clone-CZ-InUnR.js +0 -1
  125. package/dist/dashboard/assets/index-rIZLhbl7.js +0 -480
  126. package/dist/dashboard/assets/index-sax--nf3.css +0 -1
  127. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-CjcHIbj7.js +0 -1
package/dist/index.js CHANGED
@@ -36869,6 +36869,44 @@ var init_setup_drift = __esm({
36869
36869
  }
36870
36870
  });
36871
36871
 
36872
+ // src/lib/asset-drift-cache.ts
36873
+ import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync29, mkdirSync as mkdirSync22 } from "fs";
36874
+ import { join as join45, dirname as dirname22 } from "path";
36875
+ function assetDriftCachePath(contextRoot) {
36876
+ return join45(contextRoot, "state", ".asset-drift.json");
36877
+ }
36878
+ function readAssetDriftCache(contextRoot) {
36879
+ try {
36880
+ const p = assetDriftCachePath(contextRoot);
36881
+ if (!existsSync45(p)) return null;
36882
+ const parsed = JSON.parse(readFileSync34(p, "utf-8"));
36883
+ if (!parsed || typeof parsed.cliVersion !== "string" || typeof parsed.setupVersion !== "string" || typeof parsed.usedAssetsChanged !== "boolean") {
36884
+ return null;
36885
+ }
36886
+ return {
36887
+ cliVersion: parsed.cliVersion,
36888
+ setupVersion: parsed.setupVersion,
36889
+ usedAssetsChanged: parsed.usedAssetsChanged,
36890
+ checkedAt: typeof parsed.checkedAt === "number" ? parsed.checkedAt : 0
36891
+ };
36892
+ } catch {
36893
+ return null;
36894
+ }
36895
+ }
36896
+ function writeAssetDriftCache(contextRoot, cache) {
36897
+ const p = assetDriftCachePath(contextRoot);
36898
+ mkdirSync22(dirname22(p), { recursive: true });
36899
+ writeFileSync29(p, JSON.stringify(cache, null, 2) + "\n", "utf-8");
36900
+ }
36901
+ function cacheConfidentlyClean(cache, cliVersion, setupVersion) {
36902
+ return cache !== null && cache.cliVersion === cliVersion && cache.setupVersion === setupVersion && cache.usedAssetsChanged === false;
36903
+ }
36904
+ var init_asset_drift_cache = __esm({
36905
+ "src/lib/asset-drift-cache.ts"() {
36906
+ "use strict";
36907
+ }
36908
+ });
36909
+
36872
36910
  // src/lib/snapshot-budget.ts
36873
36911
  function estimateTokens(s) {
36874
36912
  return Math.ceil(s.length / 4);
@@ -36974,8 +37012,8 @@ var init_snapshot_budget = __esm({
36974
37012
  });
36975
37013
 
36976
37014
  // src/cli/commands/snapshot.ts
36977
- import { readFileSync as readFileSync34, existsSync as existsSync45, statSync as statSync5 } from "fs";
36978
- import { join as join45, basename as basename12, dirname as dirname22 } from "path";
37015
+ import { readFileSync as readFileSync35, existsSync as existsSync46, statSync as statSync5 } from "fs";
37016
+ import { join as join46, basename as basename12, dirname as dirname23 } from "path";
36979
37017
  function extractFirstParagraph(content) {
36980
37018
  const lines = content.split("\n");
36981
37019
  const paragraphLines = [];
@@ -37009,8 +37047,8 @@ function sortTaskEntriesByActivity(entries) {
37009
37047
  return [...entries].sort((a, b) => statusRank(a.status) - statusRank(b.status) || prioRank(a.priority) - prioRank(b.priority) || b.updated.localeCompare(a.updated));
37010
37048
  }
37011
37049
  function getActiveTaskEntries(root) {
37012
- const stateDir = join45(root, "state");
37013
- if (!existsSync45(stateDir)) return [];
37050
+ const stateDir = join46(root, "state");
37051
+ if (!existsSync46(stateDir)) return [];
37014
37052
  const taskFiles = import_fast_glob11.default.sync("*.md", { cwd: stateDir, absolute: true });
37015
37053
  const entries = [];
37016
37054
  for (const file of taskFiles) {
@@ -37042,15 +37080,15 @@ function getActiveTaskEntries(root) {
37042
37080
  return entries;
37043
37081
  }
37044
37082
  function resolveActiveTaskPath(root) {
37045
- const stateDir = join45(root, "state");
37046
- if (!existsSync45(stateDir)) return null;
37047
- const overridePath = join45(stateDir, ".active-task");
37048
- if (existsSync45(overridePath)) {
37083
+ const stateDir = join46(root, "state");
37084
+ if (!existsSync46(stateDir)) return null;
37085
+ const overridePath = join46(stateDir, ".active-task");
37086
+ if (existsSync46(overridePath)) {
37049
37087
  try {
37050
- const slug = readFileSync34(overridePath, "utf-8").trim();
37088
+ const slug = readFileSync35(overridePath, "utf-8").trim();
37051
37089
  if (slug) {
37052
- const taskPath = join45(stateDir, `${slug}.md`);
37053
- if (existsSync45(taskPath)) return taskPath;
37090
+ const taskPath = join46(stateDir, `${slug}.md`);
37091
+ if (existsSync46(taskPath)) return taskPath;
37054
37092
  }
37055
37093
  } catch {
37056
37094
  }
@@ -37076,7 +37114,7 @@ function resolveActiveTaskPath(root) {
37076
37114
  return candidates[0].path;
37077
37115
  }
37078
37116
  function getActiveProductKnowledge(root) {
37079
- const config = readSetupConfig(dirname22(root));
37117
+ const config = readSetupConfig(dirname23(root));
37080
37118
  if (!config || !Array.isArray(config.multiProduct) || config.multiProduct.length === 0) {
37081
37119
  return [];
37082
37120
  }
@@ -37093,11 +37131,11 @@ function getActiveProductKnowledge(root) {
37093
37131
  }
37094
37132
  if (!product) return [];
37095
37133
  if (!config.multiProduct.includes(product)) return [];
37096
- const productKnowledgePath = join45(root, "knowledge", "products", `${product}.md`);
37097
- if (!existsSync45(productKnowledgePath)) return [];
37134
+ const productKnowledgePath = join46(root, "knowledge", "products", `${product}.md`);
37135
+ if (!existsSync46(productKnowledgePath)) return [];
37098
37136
  let raw;
37099
37137
  try {
37100
- raw = readFileSync34(productKnowledgePath, "utf-8");
37138
+ raw = readFileSync35(productKnowledgePath, "utf-8");
37101
37139
  } catch {
37102
37140
  return [];
37103
37141
  }
@@ -37132,7 +37170,7 @@ function getActiveProductKnowledge(root) {
37132
37170
  }
37133
37171
  function getVersionNudge(root) {
37134
37172
  try {
37135
- const projectRoot = dirname22(root);
37173
+ const projectRoot = dirname23(root);
37136
37174
  const cache = readVersionCache(projectRoot);
37137
37175
  if (!cache || !isCacheFresh(cache)) return "";
37138
37176
  const installedCli = dreamcontextVersion();
@@ -37148,9 +37186,9 @@ function getVersionNudge(root) {
37148
37186
  }
37149
37187
  function getMigrationNote(root) {
37150
37188
  try {
37151
- const sleepPath = join45(root, "state", ".sleep.json");
37152
- if (!existsSync45(sleepPath)) return "";
37153
- const raw = readFileSync34(sleepPath, "utf-8");
37189
+ const sleepPath = join46(root, "state", ".sleep.json");
37190
+ if (!existsSync46(sleepPath)) return "";
37191
+ const raw = readFileSync35(sleepPath, "utf-8");
37154
37192
  const parsed = JSON.parse(raw);
37155
37193
  if (!parsed || !Array.isArray(parsed.pendingMigrationNotices) || parsed.pendingMigrationNotices.length === 0) {
37156
37194
  return "";
@@ -37168,14 +37206,21 @@ Migrations applied since last session: ${notices.join("; ")}`;
37168
37206
  }
37169
37207
  function getDriftDirective(root) {
37170
37208
  try {
37171
- const projectRoot = dirname22(root);
37209
+ const projectRoot = dirname23(root);
37172
37210
  const config = readSetupConfig(projectRoot);
37173
37211
  if (!config) return "";
37174
- return buildDriftDirective({
37175
- cliVersion: dreamcontextVersion(),
37212
+ const cliVersion = dreamcontextVersion();
37213
+ const driftInput = {
37214
+ cliVersion,
37176
37215
  setupVersion: config.setupVersion,
37177
37216
  driftCheckEnv: process.env.DREAMCONTEXT_DRIFT_CHECK
37178
- }) ?? "";
37217
+ };
37218
+ const state = resolveDriftState(driftInput);
37219
+ if (state === "stale" || state === "bootstrap") {
37220
+ const cache = readAssetDriftCache(root);
37221
+ if (cacheConfidentlyClean(cache, cliVersion, config.setupVersion)) return "";
37222
+ }
37223
+ return buildDriftDirective(driftInput) ?? "";
37179
37224
  } catch {
37180
37225
  return "";
37181
37226
  }
@@ -37191,24 +37236,24 @@ function generateSnapshot(rootOverride) {
37191
37236
  parts = [];
37192
37237
  }
37193
37238
  };
37194
- const soulPath = join45(root, "core", "0.soul.md");
37195
- if (existsSync45(soulPath)) {
37196
- const content = readFileSync34(soulPath, "utf-8").trim();
37239
+ const soulPath = join46(root, "core", "0.soul.md");
37240
+ if (existsSync46(soulPath)) {
37241
+ const content = readFileSync35(soulPath, "utf-8").trim();
37197
37242
  parts.push("## Soul (Agent Identity, Principles, Rules)\n");
37198
37243
  parts.push(content);
37199
37244
  parts.push("");
37200
37245
  }
37201
- const userPath = join45(root, "core", "1.user.md");
37202
- if (existsSync45(userPath)) {
37203
- const content = readFileSync34(userPath, "utf-8").trim();
37246
+ const userPath = join46(root, "core", "1.user.md");
37247
+ if (existsSync46(userPath)) {
37248
+ const content = readFileSync35(userPath, "utf-8").trim();
37204
37249
  parts.push("## User (Preferences, Project Details, Rules)\n");
37205
37250
  parts.push(content);
37206
37251
  parts.push("");
37207
37252
  }
37208
37253
  flush("identity", { neverEvict: true });
37209
- const memoryPath = join45(root, "core", "2.memory.md");
37210
- if (existsSync45(memoryPath)) {
37211
- const content = readFileSync34(memoryPath, "utf-8").trim();
37254
+ const memoryPath = join46(root, "core", "2.memory.md");
37255
+ if (existsSync46(memoryPath)) {
37256
+ const content = readFileSync35(memoryPath, "utf-8").trim();
37212
37257
  if (content) {
37213
37258
  parts.push("## Memory (Technical Decisions, Known Issues, Session Log)\n");
37214
37259
  parts.push(content);
@@ -37273,8 +37318,8 @@ function generateSnapshot(rootOverride) {
37273
37318
  if (sleepState.triggers.length > 0) {
37274
37319
  const taskNames = [];
37275
37320
  const taskTags = [];
37276
- const stateDir = join45(root, "state");
37277
- if (existsSync45(stateDir)) {
37321
+ const stateDir = join46(root, "state");
37322
+ if (existsSync46(stateDir)) {
37278
37323
  const taskFiles = import_fast_glob11.default.sync("*.md", { cwd: stateDir, absolute: true });
37279
37324
  for (const file of taskFiles) {
37280
37325
  try {
@@ -37310,14 +37355,14 @@ function generateSnapshot(rootOverride) {
37310
37355
  const CHANGELOG_TIER2 = 10;
37311
37356
  const TIER1_BODY_CHARS = 300;
37312
37357
  const TIER2_LINE_CHARS = 140;
37313
- const multiPerson = isMultiPerson(readSetupConfig(dirname22(root)));
37358
+ const multiPerson = isMultiPerson(readSetupConfig(dirname23(root)));
37314
37359
  const authorSuffix = (e) => {
37315
37360
  if (!multiPerson) return "";
37316
37361
  const authors = Array.isArray(e.authors) ? e.authors.filter((a) => typeof a === "string") : [];
37317
37362
  return authors.length > 0 ? ` \u2014 by ${authors.join(", ")}` : "";
37318
37363
  };
37319
- const changelogPath = join45(root, "core", "CHANGELOG.json");
37320
- if (existsSync45(changelogPath)) {
37364
+ const changelogPath = join46(root, "core", "CHANGELOG.json");
37365
+ if (existsSync46(changelogPath)) {
37321
37366
  try {
37322
37367
  const entries = readJsonArray(changelogPath);
37323
37368
  const tier1 = entries.slice(0, CHANGELOG_TIER1);
@@ -37373,8 +37418,8 @@ function generateSnapshot(rootOverride) {
37373
37418
  } catch {
37374
37419
  }
37375
37420
  }
37376
- const releasesPath = join45(root, "core", "RELEASES.json");
37377
- if (existsSync45(releasesPath)) {
37421
+ const releasesPath = join46(root, "core", "RELEASES.json");
37422
+ if (existsSync46(releasesPath)) {
37378
37423
  try {
37379
37424
  const releases = readJsonArray(releasesPath);
37380
37425
  if (releases.length > 0) {
@@ -37410,8 +37455,8 @@ function generateSnapshot(rootOverride) {
37410
37455
  }
37411
37456
  }
37412
37457
  flush("releases", { neverEvict: true });
37413
- const featuresDir = join45(root, "core", "features");
37414
- if (existsSync45(featuresDir)) {
37458
+ const featuresDir = join46(root, "core", "features");
37459
+ if (existsSync46(featuresDir)) {
37415
37460
  const featureFiles = import_fast_glob11.default.sync("*.md", { cwd: featuresDir, absolute: true });
37416
37461
  const features = [];
37417
37462
  const featureMeta = [];
@@ -37499,8 +37544,8 @@ function generateSnapshot(rootOverride) {
37499
37544
  const pinnedEntries = [];
37500
37545
  const warmEntries = [];
37501
37546
  const activeTaskTags = [];
37502
- const stDir = join45(root, "state");
37503
- if (existsSync45(stDir)) {
37547
+ const stDir = join46(root, "state");
37548
+ if (existsSync46(stDir)) {
37504
37549
  const tFiles = import_fast_glob11.default.sync("*.md", { cwd: stDir, absolute: true });
37505
37550
  for (const file of tFiles) {
37506
37551
  try {
@@ -37634,8 +37679,8 @@ function generateSubagentBriefing() {
37634
37679
  parts.push('`dreamcontext memory recall "<keywords>"` (BM25 over knowledge/features/tasks/');
37635
37680
  parts.push("memory/changelog, <100ms, zero token overhead) BEFORE Glob/Grep \u2014 it frequently");
37636
37681
  parts.push("beats blind exploration outright.\n");
37637
- const soulPath = join45(root, "core", "0.soul.md");
37638
- if (existsSync45(soulPath)) {
37682
+ const soulPath = join46(root, "core", "0.soul.md");
37683
+ if (existsSync46(soulPath)) {
37639
37684
  const { data, content } = readFrontmatter(soulPath);
37640
37685
  const projectName = typeof data.name === "string" ? data.name : "";
37641
37686
  const lines = content.split("\n");
@@ -37654,8 +37699,8 @@ function generateSubagentBriefing() {
37654
37699
  `);
37655
37700
  }
37656
37701
  }
37657
- const featuresDir = join45(root, "core", "features");
37658
- if (existsSync45(featuresDir)) {
37702
+ const featuresDir = join46(root, "core", "features");
37703
+ if (existsSync46(featuresDir)) {
37659
37704
  const featureFiles = import_fast_glob11.default.sync("*.md", { cwd: featuresDir, absolute: true });
37660
37705
  const features = [];
37661
37706
  for (const file of featureFiles) {
@@ -37722,8 +37767,8 @@ function generateSubagentBriefing() {
37722
37767
  }
37723
37768
  parts.push("");
37724
37769
  }
37725
- const coreDir = join45(root, "core");
37726
- if (existsSync45(coreDir)) {
37770
+ const coreDir = join46(root, "core");
37771
+ if (existsSync46(coreDir)) {
37727
37772
  const allCoreFiles = import_fast_glob11.default.sync(["[0-9]*"], { cwd: coreDir, absolute: true });
37728
37773
  allCoreFiles.sort((a, b) => basename12(a).localeCompare(basename12(b), void 0, { numeric: true }));
37729
37774
  if (allCoreFiles.length > 0) {
@@ -37811,6 +37856,7 @@ var init_snapshot2 = __esm({
37811
37856
  init_version_check();
37812
37857
  init_manifest();
37813
37858
  init_setup_drift();
37859
+ init_asset_drift_cache();
37814
37860
  init_feature_freshness();
37815
37861
  init_federation_inbox();
37816
37862
  init_snapshot_budget();
@@ -37865,7 +37911,7 @@ var init_salience = __esm({
37865
37911
  });
37866
37912
 
37867
37913
  // src/cli/commands/transcript.ts
37868
- import { readFileSync as readFileSync35, existsSync as existsSync46, statSync as statSync6 } from "fs";
37914
+ import { readFileSync as readFileSync36, existsSync as existsSync47, statSync as statSync6 } from "fs";
37869
37915
  function distillTranscript(transcriptPath, sinceTimestamp) {
37870
37916
  const result = {
37871
37917
  userMessages: [],
@@ -37874,11 +37920,11 @@ function distillTranscript(transcriptPath, sinceTimestamp) {
37874
37920
  errors: [],
37875
37921
  bookmarks: []
37876
37922
  };
37877
- if (!existsSync46(transcriptPath)) return result;
37923
+ if (!existsSync47(transcriptPath)) return result;
37878
37924
  try {
37879
37925
  const stat = statSync6(transcriptPath);
37880
37926
  if (stat.size === 0 || stat.size > MAX_TRANSCRIPT_BYTES) return result;
37881
- const content = readFileSync35(transcriptPath, "utf-8");
37927
+ const content = readFileSync36(transcriptPath, "utf-8");
37882
37928
  const lines = content.split("\n").filter((l) => l.trim());
37883
37929
  for (const line of lines) {
37884
37930
  let entry;
@@ -38062,7 +38108,7 @@ function registerTranscriptCommand(program2) {
38062
38108
  error(`No transcript path for session: ${sessionId}`);
38063
38109
  return;
38064
38110
  }
38065
- if (!existsSync46(session.transcript_path)) {
38111
+ if (!existsSync47(session.transcript_path)) {
38066
38112
  error(`Transcript file not found: ${session.transcript_path}`);
38067
38113
  return;
38068
38114
  }
@@ -38239,8 +38285,8 @@ var init_recall_synonyms = __esm({
38239
38285
  });
38240
38286
 
38241
38287
  // src/lib/recall.ts
38242
- import { existsSync as existsSync47, readFileSync as readFileSync36 } from "fs";
38243
- import { join as join46, basename as basename13, dirname as dirname23, relative as relative3 } from "path";
38288
+ import { existsSync as existsSync48, readFileSync as readFileSync37 } from "fs";
38289
+ import { join as join47, basename as basename13, dirname as dirname24, relative as relative3 } from "path";
38244
38290
  function isFederated(doc) {
38245
38291
  return doc.federated === true;
38246
38292
  }
@@ -38329,7 +38375,7 @@ function productFromRelPath(relPath) {
38329
38375
  return m ? m[1] : void 0;
38330
38376
  }
38331
38377
  function loadMarkdownDocs(dir, type, contextRoot) {
38332
- if (!existsSync47(dir)) return [];
38378
+ if (!existsSync48(dir)) return [];
38333
38379
  const files = import_fast_glob12.default.sync("**/*.md", { cwd: dir, absolute: true });
38334
38380
  const boardDirs = diagramFolderDirs(files);
38335
38381
  const out = [];
@@ -38372,11 +38418,11 @@ function loadMarkdownDocs(dir, type, contextRoot) {
38372
38418
  return out;
38373
38419
  }
38374
38420
  function loadChangelogEntries(contextRoot) {
38375
- const path2 = join46(contextRoot, "core", "CHANGELOG.json");
38376
- if (!existsSync47(path2)) return [];
38421
+ const path2 = join47(contextRoot, "core", "CHANGELOG.json");
38422
+ if (!existsSync48(path2)) return [];
38377
38423
  let entries = [];
38378
38424
  try {
38379
- const raw = readFileSync36(path2, "utf-8");
38425
+ const raw = readFileSync37(path2, "utf-8");
38380
38426
  const parsed = JSON.parse(raw);
38381
38427
  if (Array.isArray(parsed)) entries = parsed;
38382
38428
  } catch {
@@ -38424,9 +38470,9 @@ function loadChangelogEntries(contextRoot) {
38424
38470
  return out;
38425
38471
  }
38426
38472
  function loadMemoryFile(contextRoot) {
38427
- const path2 = join46(contextRoot, "core", "2.memory.md");
38428
- if (!existsSync47(path2)) return [];
38429
- const raw = readFileSync36(path2, "utf-8");
38473
+ const path2 = join47(contextRoot, "core", "2.memory.md");
38474
+ if (!existsSync48(path2)) return [];
38475
+ const raw = readFileSync37(path2, "utf-8");
38430
38476
  const sections = raw.split(/^##\s+/m).slice(1);
38431
38477
  const out = [];
38432
38478
  for (let i = 0; i < sections.length; i++) {
@@ -38458,11 +38504,11 @@ function loadMemoryFile(contextRoot) {
38458
38504
  return out;
38459
38505
  }
38460
38506
  function loadBookmarkDocs(contextRoot) {
38461
- const path2 = join46(contextRoot, "state", ".sleep.json");
38462
- if (!existsSync47(path2)) return [];
38507
+ const path2 = join47(contextRoot, "state", ".sleep.json");
38508
+ if (!existsSync48(path2)) return [];
38463
38509
  let bookmarks = [];
38464
38510
  try {
38465
- const parsed = JSON.parse(readFileSync36(path2, "utf-8"));
38511
+ const parsed = JSON.parse(readFileSync37(path2, "utf-8"));
38466
38512
  if (parsed && typeof parsed === "object" && Array.isArray(parsed.bookmarks)) {
38467
38513
  bookmarks = parsed.bookmarks;
38468
38514
  }
@@ -38504,14 +38550,14 @@ function loadBookmarkDocs(contextRoot) {
38504
38550
  return out;
38505
38551
  }
38506
38552
  function loadSkillDocs(skillsRoot) {
38507
- if (!existsSync47(skillsRoot)) return [];
38553
+ if (!existsSync48(skillsRoot)) return [];
38508
38554
  const files = import_fast_glob12.default.sync("*/SKILL.md", { cwd: skillsRoot, absolute: true });
38509
38555
  const out = [];
38510
38556
  for (const file of files) {
38511
38557
  try {
38512
38558
  const { data, content } = readFrontmatter(file);
38513
38559
  if (data.alwaysApply === true) continue;
38514
- const slug = typeof data.name === "string" && data.name ? data.name : basename13(dirname23(file));
38560
+ const slug = typeof data.name === "string" && data.name ? data.name : basename13(dirname24(file));
38515
38561
  const title = slug;
38516
38562
  const description = typeof data.description === "string" ? data.description : "";
38517
38563
  const tags = Array.isArray(data.tags) ? data.tags.map(String) : [];
@@ -38543,13 +38589,13 @@ function buildCorpus(contextRoot, opts = {}) {
38543
38589
  const types = new Set(opts.types ?? ["knowledge", "feature", "task", "memory", "changelog"]);
38544
38590
  const docs = [];
38545
38591
  if (types.has("knowledge")) {
38546
- docs.push(...loadMarkdownDocs(join46(contextRoot, "knowledge"), "knowledge", contextRoot));
38592
+ docs.push(...loadMarkdownDocs(join47(contextRoot, "knowledge"), "knowledge", contextRoot));
38547
38593
  }
38548
38594
  if (types.has("feature")) {
38549
- docs.push(...loadMarkdownDocs(join46(contextRoot, "core", "features"), "feature", contextRoot));
38595
+ docs.push(...loadMarkdownDocs(join47(contextRoot, "core", "features"), "feature", contextRoot));
38550
38596
  }
38551
38597
  if (types.has("task")) {
38552
- docs.push(...loadMarkdownDocs(join46(contextRoot, "state"), "task", contextRoot));
38598
+ docs.push(...loadMarkdownDocs(join47(contextRoot, "state"), "task", contextRoot));
38553
38599
  docs.push(...loadDigestDocs(contextRoot));
38554
38600
  }
38555
38601
  if (types.has("memory")) {
@@ -38899,8 +38945,8 @@ var init_recall = __esm({
38899
38945
  });
38900
38946
 
38901
38947
  // src/lib/session-digest.ts
38902
- import { existsSync as existsSync48, mkdirSync as mkdirSync22, writeFileSync as writeFileSync29 } from "fs";
38903
- import { join as join47 } from "path";
38948
+ import { existsSync as existsSync49, mkdirSync as mkdirSync23, writeFileSync as writeFileSync30 } from "fs";
38949
+ import { join as join48 } from "path";
38904
38950
  function coerceCreatedAt(value) {
38905
38951
  if (typeof value === "string" && value.trim()) return value.trim();
38906
38952
  if (value instanceof Date && !Number.isNaN(value.getTime())) return value.toISOString();
@@ -38958,18 +39004,18 @@ function enforceByteCap(lines, maxBytes) {
38958
39004
  return out.trimEnd() + "\n";
38959
39005
  }
38960
39006
  function digestsDir(root) {
38961
- return join47(root, "state", DIGESTS_DIRNAME);
39007
+ return join48(root, "state", DIGESTS_DIRNAME);
38962
39008
  }
38963
39009
  function digestPath(root, sessionId) {
38964
39010
  const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
38965
- return join47(digestsDir(root), `${safe}.md`);
39011
+ return join48(digestsDir(root), `${safe}.md`);
38966
39012
  }
38967
39013
  function digestExists(root, sessionId) {
38968
- return existsSync48(digestPath(root, sessionId));
39014
+ return existsSync49(digestPath(root, sessionId));
38969
39015
  }
38970
39016
  function digestIsPartial(root, sessionId) {
38971
39017
  const file = digestPath(root, sessionId);
38972
- if (!existsSync48(file)) return false;
39018
+ if (!existsSync49(file)) return false;
38973
39019
  try {
38974
39020
  const { data } = readFrontmatter(file);
38975
39021
  return data.partial === true;
@@ -38979,7 +39025,7 @@ function digestIsPartial(root, sessionId) {
38979
39025
  }
38980
39026
  function writeDigest(root, sessionId, md, opts = {}) {
38981
39027
  const dir = digestsDir(root);
38982
- mkdirSync22(dir, { recursive: true });
39028
+ mkdirSync23(dir, { recursive: true });
38983
39029
  const file = digestPath(root, sessionId);
38984
39030
  const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
38985
39031
  const frontmatter = [
@@ -38991,12 +39037,12 @@ function writeDigest(root, sessionId, md, opts = {}) {
38991
39037
  "---",
38992
39038
  ""
38993
39039
  ].join("\n");
38994
- writeFileSync29(file, frontmatter + md, "utf-8");
39040
+ writeFileSync30(file, frontmatter + md, "utf-8");
38995
39041
  return file;
38996
39042
  }
38997
39043
  function loadDigestDocs(root) {
38998
39044
  const dir = digestsDir(root);
38999
- if (!existsSync48(dir)) return [];
39045
+ if (!existsSync49(dir)) return [];
39000
39046
  const files = import_fast_glob13.default.sync("*.md", { cwd: dir, absolute: true });
39001
39047
  const parsed = [];
39002
39048
  for (const file of files) {
@@ -39007,7 +39053,7 @@ function loadDigestDocs(root) {
39007
39053
  const title = `Session digest ${sessionId}`;
39008
39054
  const body = content.trim();
39009
39055
  if (!body) continue;
39010
- const relPath = join47("state", DIGESTS_DIRNAME, `${sessionId}.md`);
39056
+ const relPath = join48("state", DIGESTS_DIRNAME, `${sessionId}.md`);
39011
39057
  const createdAt = coerceCreatedAt(data.created_at);
39012
39058
  const fields = buildFields({ slug, title, description: "", tags: [], body });
39013
39059
  const ms = createdAt ? Date.parse(createdAt) : NaN;
@@ -39059,8 +39105,8 @@ var init_session_digest = __esm({
39059
39105
  });
39060
39106
 
39061
39107
  // src/lib/marketing/path-guards.ts
39062
- import { existsSync as existsSync49, realpathSync } from "fs";
39063
- import { basename as basename14, dirname as dirname24, resolve as resolve8, sep as sep5 } from "path";
39108
+ import { existsSync as existsSync50, realpathSync } from "fs";
39109
+ import { basename as basename14, dirname as dirname25, resolve as resolve8, sep as sep5 } from "path";
39064
39110
  function isMarketingEnvPath(filePath, from) {
39065
39111
  if (!filePath) return false;
39066
39112
  const root = resolveContextRoot(from);
@@ -39074,7 +39120,7 @@ function isMarketingEnvPath(filePath, from) {
39074
39120
  }
39075
39121
  function realpathOrSelf(p) {
39076
39122
  try {
39077
- return existsSync49(p) ? realpathSync(p) : p;
39123
+ return existsSync50(p) ? realpathSync(p) : p;
39078
39124
  } catch {
39079
39125
  return p;
39080
39126
  }
@@ -39082,9 +39128,9 @@ function realpathOrSelf(p) {
39082
39128
  function realpathOfNearestAncestor(p) {
39083
39129
  let current = p;
39084
39130
  const tail = [];
39085
- while (current && current !== sep5 && !existsSync49(current)) {
39131
+ while (current && current !== sep5 && !existsSync50(current)) {
39086
39132
  tail.unshift(basename14(current));
39087
- current = dirname24(current);
39133
+ current = dirname25(current);
39088
39134
  }
39089
39135
  if (!current || current === sep5) return p;
39090
39136
  try {
@@ -39226,17 +39272,17 @@ If pure greeting: {"skip":true}`;
39226
39272
  // src/cli/commands/app.ts
39227
39273
  import { execFileSync as execFileSync3, spawn as spawnProcess } from "child_process";
39228
39274
  import {
39229
- existsSync as existsSync50,
39230
- mkdirSync as mkdirSync23,
39275
+ existsSync as existsSync51,
39276
+ mkdirSync as mkdirSync24,
39231
39277
  mkdtempSync,
39232
- readFileSync as readFileSync38,
39233
- writeFileSync as writeFileSync30,
39278
+ readFileSync as readFileSync39,
39279
+ writeFileSync as writeFileSync31,
39234
39280
  rmSync as rmSync6,
39235
39281
  renameSync as renameSync7,
39236
39282
  readdirSync as readdirSync12
39237
39283
  } from "fs";
39238
39284
  import { homedir as homedir2, tmpdir } from "os";
39239
- import { join as join48, resolve as resolve9, dirname as dirname25 } from "path";
39285
+ import { join as join49, resolve as resolve9, dirname as dirname26 } from "path";
39240
39286
  import { createHash as createHash2 } from "crypto";
39241
39287
  function detectPlatform(platform2 = process.platform, arch2 = process.arch) {
39242
39288
  const os3 = platform2 === "darwin" ? "darwin" : platform2 === "win32" ? "win32" : platform2 === "linux" ? "linux" : "other";
@@ -39249,16 +39295,16 @@ function pickAssetForArch(assetNames, arch2) {
39249
39295
  return exact ?? null;
39250
39296
  }
39251
39297
  function defaultInstallDir(home = homedir2()) {
39252
- return join48(home, "Applications");
39298
+ return join49(home, "Applications");
39253
39299
  }
39254
39300
  function appManifestPath(home = homedir2()) {
39255
- return join48(home, ".dreamcontext", "app.json");
39301
+ return join49(home, ".dreamcontext", "app.json");
39256
39302
  }
39257
39303
  function readAppManifest(home = homedir2()) {
39258
39304
  const p = appManifestPath(home);
39259
- if (!existsSync50(p)) return null;
39305
+ if (!existsSync51(p)) return null;
39260
39306
  try {
39261
- const parsed = JSON.parse(readFileSync38(p, "utf-8"));
39307
+ const parsed = JSON.parse(readFileSync39(p, "utf-8"));
39262
39308
  if (!parsed || typeof parsed.version !== "string" || typeof parsed.path !== "string") return null;
39263
39309
  return {
39264
39310
  version: parsed.version,
@@ -39272,8 +39318,8 @@ function readAppManifest(home = homedir2()) {
39272
39318
  }
39273
39319
  function writeAppManifest(manifest, home = homedir2()) {
39274
39320
  const p = appManifestPath(home);
39275
- mkdirSync23(dirname25(p), { recursive: true });
39276
- writeFileSync30(p, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
39321
+ mkdirSync24(dirname26(p), { recursive: true });
39322
+ writeFileSync31(p, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
39277
39323
  }
39278
39324
  function run(cmd, args) {
39279
39325
  execFileSync3(cmd, args, { stdio: ["ignore", "ignore", "pipe"] });
@@ -39282,17 +39328,17 @@ function runCapture(cmd, args) {
39282
39328
  return execFileSync3(cmd, args, { encoding: "utf-8" }).toString().trim();
39283
39329
  }
39284
39330
  function validateAppBundle(appDir) {
39285
- if (!appDir.endsWith(".app") || !existsSync50(appDir)) {
39331
+ if (!appDir.endsWith(".app") || !existsSync51(appDir)) {
39286
39332
  throw new Error(`Not a .app bundle: ${appDir}`);
39287
39333
  }
39288
- const macos = join48(appDir, "Contents", "MacOS");
39289
- const plist = join48(appDir, "Contents", "Info.plist");
39290
- if (!existsSync50(macos) || !existsSync50(plist)) {
39334
+ const macos = join49(appDir, "Contents", "MacOS");
39335
+ const plist = join49(appDir, "Contents", "Info.plist");
39336
+ if (!existsSync51(macos) || !existsSync51(plist)) {
39291
39337
  throw new Error(`Malformed .app (missing Contents/MacOS or Info.plist): ${appDir}`);
39292
39338
  }
39293
39339
  }
39294
39340
  function readBundleVersion(appDir) {
39295
- const plist = join48(appDir, "Contents", "Info.plist");
39341
+ const plist = join49(appDir, "Contents", "Info.plist");
39296
39342
  try {
39297
39343
  return runCapture("plutil", ["-extract", "CFBundleShortVersionString", "raw", "-o", "-", plist]) || null;
39298
39344
  } catch {
@@ -39301,11 +39347,11 @@ function readBundleVersion(appDir) {
39301
39347
  }
39302
39348
  function findAppInDir(dir) {
39303
39349
  const entries = readdirSync12(dir).filter((e) => e.endsWith(".app"));
39304
- return entries.length > 0 ? join48(dir, entries[0]) : null;
39350
+ return entries.length > 0 ? join49(dir, entries[0]) : null;
39305
39351
  }
39306
39352
  function materializeAppBundle(source, workDir) {
39307
39353
  const src = resolve9(source);
39308
- if (!existsSync50(src)) throw new Error(`Source not found: ${src}`);
39354
+ if (!existsSync51(src)) throw new Error(`Source not found: ${src}`);
39309
39355
  if (src.endsWith(".app")) {
39310
39356
  return src;
39311
39357
  }
@@ -39342,14 +39388,14 @@ function installAppBundle(source, opts = {}) {
39342
39388
  }
39343
39389
  const home = opts.home ?? homedir2();
39344
39390
  const installDir = opts.installDir ?? defaultInstallDir(home);
39345
- mkdirSync23(installDir, { recursive: true });
39346
- const workDir = mkdtempSync(join48(tmpdir(), "dc-app-"));
39391
+ mkdirSync24(installDir, { recursive: true });
39392
+ const workDir = mkdtempSync(join49(tmpdir(), "dc-app-"));
39347
39393
  try {
39348
39394
  const appDir = materializeAppBundle(source, workDir);
39349
39395
  validateAppBundle(appDir);
39350
- const target = join48(installDir, APP_BUNDLE_NAME);
39351
- const staging = join48(installDir, `.${APP_BUNDLE_NAME}.new-${process.pid}`);
39352
- const backup = join48(installDir, `.${APP_BUNDLE_NAME}.old-${process.pid}`);
39396
+ const target = join49(installDir, APP_BUNDLE_NAME);
39397
+ const staging = join49(installDir, `.${APP_BUNDLE_NAME}.new-${process.pid}`);
39398
+ const backup = join49(installDir, `.${APP_BUNDLE_NAME}.old-${process.pid}`);
39353
39399
  rmSync6(staging, { recursive: true, force: true });
39354
39400
  rmSync6(backup, { recursive: true, force: true });
39355
39401
  let wasRunning;
@@ -39361,11 +39407,11 @@ function installAppBundle(source, opts = {}) {
39361
39407
  } catch {
39362
39408
  }
39363
39409
  wasRunning = isAppRunning();
39364
- replaced = existsSync50(target);
39410
+ replaced = existsSync51(target);
39365
39411
  if (replaced) renameSync7(target, backup);
39366
39412
  renameSync7(staging, target);
39367
39413
  } catch (e) {
39368
- if (existsSync50(target) === false && existsSync50(backup)) {
39414
+ if (existsSync51(target) === false && existsSync51(backup)) {
39369
39415
  try {
39370
39416
  renameSync7(backup, target);
39371
39417
  } catch {
@@ -39411,10 +39457,10 @@ async function downloadTo(url, destFile, fetchImpl = fetch) {
39411
39457
  const res = await fetchImpl(url, { headers: { "User-Agent": "dreamcontext-cli" } });
39412
39458
  if (!res.ok) throw new Error(`Download failed (${res.status}): ${url}`);
39413
39459
  const buf = Buffer.from(await res.arrayBuffer());
39414
- writeFileSync30(destFile, buf);
39460
+ writeFileSync31(destFile, buf);
39415
39461
  }
39416
39462
  function sha256File(file) {
39417
- return createHash2("sha256").update(readFileSync38(file)).digest("hex");
39463
+ return createHash2("sha256").update(readFileSync39(file)).digest("hex");
39418
39464
  }
39419
39465
  async function downloadLatestArtifact(repo = APP_RELEASE_REPO, fetchImpl = fetch) {
39420
39466
  const plat = detectPlatform();
@@ -39430,13 +39476,13 @@ async function downloadLatestArtifact(repo = APP_RELEASE_REPO, fetchImpl = fetch
39430
39476
  `Release ${release2.tag_name} is missing ${assetName}.sha256 \u2014 refusing to install an unverified binary.`
39431
39477
  );
39432
39478
  }
39433
- const workDir = mkdtempSync(join48(tmpdir(), "dc-app-dl-"));
39479
+ const workDir = mkdtempSync(join49(tmpdir(), "dc-app-dl-"));
39434
39480
  try {
39435
- const archivePath = join48(workDir, assetName);
39481
+ const archivePath = join49(workDir, assetName);
39436
39482
  await downloadTo(asset.browser_download_url, archivePath, fetchImpl);
39437
- const sumFile = join48(workDir, `${assetName}.sha256`);
39483
+ const sumFile = join49(workDir, `${assetName}.sha256`);
39438
39484
  await downloadTo(sumAsset.browser_download_url, sumFile, fetchImpl);
39439
- const expected = readFileSync38(sumFile, "utf-8").trim().split(/\s+/)[0].toLowerCase();
39485
+ const expected = readFileSync39(sumFile, "utf-8").trim().split(/\s+/)[0].toLowerCase();
39440
39486
  const actual = sha256File(archivePath).toLowerCase();
39441
39487
  if (!expected || expected !== actual) {
39442
39488
  throw new Error(`Checksum mismatch for ${assetName}: expected ${expected || "(empty)"}, got ${actual}`);
@@ -39498,7 +39544,7 @@ async function doInstall(from, dir) {
39498
39544
  }
39499
39545
  source = dl.archivePath;
39500
39546
  sourceLabel = "github";
39501
- tempToClean = dirname25(dl.archivePath);
39547
+ tempToClean = dirname26(dl.archivePath);
39502
39548
  }
39503
39549
  try {
39504
39550
  const res = installAppBundle(source, { installDir: dir, sourceLabel });
@@ -39550,7 +39596,7 @@ async function doUpdate(from, dir) {
39550
39596
  console.log(source_default.green(`\u2713 Updated dreamcontext-beta ${installed.version} \u2192 ${res.version ?? dl.version}`));
39551
39597
  if (res.wasRunning) console.log(source_default.yellow("Restart the app to apply the update."));
39552
39598
  } finally {
39553
- rmSync6(dirname25(dl.archivePath), { recursive: true, force: true });
39599
+ rmSync6(dirname26(dl.archivePath), { recursive: true, force: true });
39554
39600
  }
39555
39601
  }
39556
39602
  function doStatus() {
@@ -39559,7 +39605,7 @@ function doStatus() {
39559
39605
  console.log("Desktop app: not installed (run `dreamcontext app install`).");
39560
39606
  return;
39561
39607
  }
39562
- const onDisk = existsSync50(installed.path);
39608
+ const onDisk = existsSync51(installed.path);
39563
39609
  console.log(`Desktop app: ${installed.version}`);
39564
39610
  console.log(` path: ${installed.path}${onDisk ? "" : source_default.red(" (missing!)")}`);
39565
39611
  console.log(` source: ${installed.source}`);
@@ -39588,15 +39634,82 @@ var init_app = __esm({
39588
39634
  }
39589
39635
  });
39590
39636
 
39637
+ // src/cli/commands/asset-drift.ts
39638
+ import { mkdtempSync as mkdtempSync2, rmSync as rmSync7, existsSync as existsSync52, readFileSync as readFileSync40, readdirSync as readdirSync13 } from "fs";
39639
+ import { tmpdir as tmpdir2 } from "os";
39640
+ import { join as join50, dirname as dirname27 } from "path";
39641
+ function walkFiles(dir, base, out) {
39642
+ for (const entry of readdirSync13(dir, { withFileTypes: true })) {
39643
+ const abs = join50(dir, entry.name);
39644
+ if (entry.isDirectory()) walkFiles(abs, base, out);
39645
+ else if (entry.isFile()) out.push(abs.slice(base.length + 1));
39646
+ }
39647
+ }
39648
+ async function computeUsedAssetsChanged(projectRoot, config) {
39649
+ const tmp = mkdtempSync2(join50(tmpdir2(), "dc-assetdrift-"));
39650
+ try {
39651
+ for (const platform2 of config.platforms) {
39652
+ await installCoreForPlatform(platform2, tmp);
39653
+ }
39654
+ if (config.packs.length > 0) {
39655
+ directPackInstall(config.packs, tmp, config.platforms, emptyManifest());
39656
+ }
39657
+ const produced = [];
39658
+ walkFiles(tmp, tmp, produced);
39659
+ for (const rel of produced) {
39660
+ if (rel.endsWith("settings.json")) continue;
39661
+ if (rel.startsWith("_dream_context/")) continue;
39662
+ const onDisk = join50(projectRoot, rel);
39663
+ if (!existsSync52(onDisk)) return true;
39664
+ if (!readFileSync40(join50(tmp, rel)).equals(readFileSync40(onDisk))) return true;
39665
+ }
39666
+ return false;
39667
+ } finally {
39668
+ try {
39669
+ rmSync7(tmp, { recursive: true, force: true });
39670
+ } catch {
39671
+ }
39672
+ }
39673
+ }
39674
+ async function runAssetDriftRefresh(contextRoot) {
39675
+ const projectRoot = dirname27(contextRoot);
39676
+ const config = readSetupConfig(projectRoot);
39677
+ if (!config) return;
39678
+ const cliVersion = dreamcontextVersion();
39679
+ const state = resolveDriftState({
39680
+ cliVersion,
39681
+ setupVersion: config.setupVersion,
39682
+ driftCheckEnv: process.env.DREAMCONTEXT_DRIFT_CHECK
39683
+ });
39684
+ if (state !== "stale" && state !== "bootstrap") return;
39685
+ const usedAssetsChanged = await computeUsedAssetsChanged(projectRoot, config);
39686
+ writeAssetDriftCache(contextRoot, {
39687
+ cliVersion,
39688
+ setupVersion: config.setupVersion,
39689
+ usedAssetsChanged,
39690
+ checkedAt: Date.now()
39691
+ });
39692
+ }
39693
+ var init_asset_drift = __esm({
39694
+ "src/cli/commands/asset-drift.ts"() {
39695
+ "use strict";
39696
+ init_setup_config();
39697
+ init_manifest();
39698
+ init_setup_drift();
39699
+ init_asset_drift_cache();
39700
+ init_install_skill();
39701
+ }
39702
+ });
39703
+
39591
39704
  // src/cli/commands/hook.ts
39592
- import { readFileSync as readFileSync39, existsSync as existsSync51, statSync as statSync7 } from "fs";
39705
+ import { readFileSync as readFileSync41, existsSync as existsSync53, statSync as statSync7 } from "fs";
39593
39706
  import { execFileSync as execFileSync4, spawn as spawn3 } from "child_process";
39594
39707
  import { get as httpGet } from "http";
39595
- import { dirname as dirname26, resolve as resolve10, join as join49, extname as extname2, basename as basename15, relative as relative4 } from "path";
39708
+ import { dirname as dirname28, resolve as resolve10, join as join51, extname as extname2, basename as basename15, relative as relative4 } from "path";
39596
39709
  function readStdin() {
39597
39710
  if (process.stdin.isTTY) return null;
39598
39711
  try {
39599
- const raw = readFileSync39(0, "utf-8");
39712
+ const raw = readFileSync41(0, "utf-8");
39600
39713
  if (!raw.trim()) return null;
39601
39714
  const parsed = JSON.parse(raw);
39602
39715
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
@@ -39606,11 +39719,11 @@ function readStdin() {
39606
39719
  }
39607
39720
  }
39608
39721
  function analyzeTranscript(transcriptPath) {
39609
- if (!existsSync51(transcriptPath)) return ZERO_ANALYSIS;
39722
+ if (!existsSync53(transcriptPath)) return ZERO_ANALYSIS;
39610
39723
  try {
39611
39724
  const stat = statSync7(transcriptPath);
39612
39725
  if (stat.size === 0 || stat.size > MAX_TRANSCRIPT_BYTES2) return ZERO_ANALYSIS;
39613
- const content = readFileSync39(transcriptPath, "utf-8");
39726
+ const content = readFileSync41(transcriptPath, "utf-8");
39614
39727
  const changeMatches = content.match(/"name"\s*:\s*"(?:Write|Edit)"/g);
39615
39728
  const toolMatches = content.match(/"name"\s*:\s*"[A-Za-z_]+"/g);
39616
39729
  const slugs = /* @__PURE__ */ new Set();
@@ -39706,39 +39819,39 @@ function isJsTsFile(filePath) {
39706
39819
  return JS_TS_EXTENSIONS.has(extname2(filePath).toLowerCase());
39707
39820
  }
39708
39821
  function findProjectConfig(filePath) {
39709
- let dir = dirname26(resolve10(filePath));
39822
+ let dir = dirname28(resolve10(filePath));
39710
39823
  let formatter = null;
39711
39824
  let tsconfig = null;
39712
39825
  for (let i = 0; i <= MAX_WALK_LEVELS; i++) {
39713
39826
  if (!formatter) {
39714
39827
  for (const name of BIOME_CONFIGS) {
39715
- if (existsSync51(join49(dir, name))) {
39716
- formatter = { type: "biome", configPath: join49(dir, name), projectRoot: dir };
39828
+ if (existsSync53(join51(dir, name))) {
39829
+ formatter = { type: "biome", configPath: join51(dir, name), projectRoot: dir };
39717
39830
  break;
39718
39831
  }
39719
39832
  }
39720
39833
  if (!formatter) {
39721
39834
  for (const name of PRETTIER_CONFIGS) {
39722
- if (existsSync51(join49(dir, name))) {
39723
- formatter = { type: "prettier", configPath: join49(dir, name), projectRoot: dir };
39835
+ if (existsSync53(join51(dir, name))) {
39836
+ formatter = { type: "prettier", configPath: join51(dir, name), projectRoot: dir };
39724
39837
  break;
39725
39838
  }
39726
39839
  }
39727
39840
  }
39728
39841
  }
39729
- if (!tsconfig && existsSync51(join49(dir, "tsconfig.json"))) {
39730
- tsconfig = join49(dir, "tsconfig.json");
39842
+ if (!tsconfig && existsSync53(join51(dir, "tsconfig.json"))) {
39843
+ tsconfig = join51(dir, "tsconfig.json");
39731
39844
  }
39732
39845
  if (formatter && tsconfig) break;
39733
- const parent = dirname26(dir);
39846
+ const parent = dirname28(dir);
39734
39847
  if (parent === dir) break;
39735
39848
  dir = parent;
39736
39849
  }
39737
39850
  return { formatter, tsconfig };
39738
39851
  }
39739
39852
  function resolveLocalBin(binName, projectRoot) {
39740
- const localBin = join49(projectRoot, "node_modules", ".bin", binName);
39741
- return existsSync51(localBin) ? localBin : null;
39853
+ const localBin = join51(projectRoot, "node_modules", ".bin", binName);
39854
+ return existsSync53(localBin) ? localBin : null;
39742
39855
  }
39743
39856
  function runFormatter(detection, filePath) {
39744
39857
  try {
@@ -39780,7 +39893,7 @@ function runFormatter(detection, filePath) {
39780
39893
  }
39781
39894
  }
39782
39895
  function runTscCheckWithConfig(filePath, tsconfigPath) {
39783
- const projectRoot = dirname26(tsconfigPath);
39896
+ const projectRoot = dirname28(tsconfigPath);
39784
39897
  let tscOutput;
39785
39898
  try {
39786
39899
  const localBin = resolveLocalBin("tsc", projectRoot);
@@ -39945,6 +40058,16 @@ function spawnDashboard(port) {
39945
40058
  });
39946
40059
  child.unref();
39947
40060
  }
40061
+ function spawnAssetDriftRefresh() {
40062
+ const cliEntry = process.argv[1];
40063
+ if (!cliEntry) return;
40064
+ const child = spawn3(process.execPath, [cliEntry, "hook", "refresh-asset-drift"], {
40065
+ detached: true,
40066
+ stdio: "ignore",
40067
+ cwd: process.cwd()
40068
+ });
40069
+ child.unref();
40070
+ }
39948
40071
  function registerHookCommand(program2) {
39949
40072
  const hook = program2.command("hook").description("Hook handlers for Claude Code (stop, session-start, subagent-start, pre-tool-use, user-prompt-submit, post-tool-use, pre-compact)");
39950
40073
  hook.command("stop").description("Record session metadata (called by Claude Code Stop hook)").action(() => {
@@ -40140,7 +40263,7 @@ function registerHookCommand(program2) {
40140
40263
  }
40141
40264
  if (process.env.DREAMCONTEXT_VERSION_CHECK !== "0") {
40142
40265
  try {
40143
- const projectRoot = dirname26(root);
40266
+ const projectRoot = dirname28(root);
40144
40267
  let vcache = readVersionCache(projectRoot);
40145
40268
  if (!isCacheFresh(vcache)) {
40146
40269
  const loaded = loadCatalog();
@@ -40151,6 +40274,7 @@ function registerHookCommand(program2) {
40151
40274
  refreshVersionCache(projectRoot, { catalogPackNames: packNames });
40152
40275
  vcache = readVersionCache(projectRoot);
40153
40276
  maybeTriggerAppUpdate();
40277
+ spawnAssetDriftRefresh();
40154
40278
  }
40155
40279
  const notice = maybeAutoUpgrade(projectRoot, dreamcontextVersion(), vcache);
40156
40280
  if (notice) console.log(notice);
@@ -40215,7 +40339,7 @@ function registerHookCommand(program2) {
40215
40339
  try {
40216
40340
  const prompt = String(input2.prompt ?? "");
40217
40341
  if (prompt.trim().length >= 8) {
40218
- const skillsRoot = join49(process.cwd(), ".claude", "skills");
40342
+ const skillsRoot = join51(process.cwd(), ".claude", "skills");
40219
40343
  const docs = loadSkillDocs(skillsRoot);
40220
40344
  if (docs.length > 0 && bm25Search(prompt, docs, 5).some((h) => h.score >= SKILL_SCORE_THRESHOLD)) {
40221
40345
  gatedSkills = true;
@@ -40287,16 +40411,26 @@ function registerHookCommand(program2) {
40287
40411
  try {
40288
40412
  const sessionId = input2 && typeof input2.session_id === "string" ? input2.session_id : "";
40289
40413
  const transcriptPath = input2 && typeof input2.transcript_path === "string" ? input2.transcript_path : "";
40290
- if (sessionId && transcriptPath && existsSync51(transcriptPath)) {
40414
+ if (sessionId && transcriptPath && existsSync53(transcriptPath)) {
40291
40415
  const distilled = distillTranscript(transcriptPath);
40292
40416
  writeDigest(root, sessionId, buildDigest(distilled), { partial: true });
40293
40417
  }
40294
40418
  } catch {
40295
40419
  }
40296
40420
  });
40421
+ hook.command("refresh-asset-drift").description("Recompute whether `dreamcontext update` would change any asset this project uses (detached cache refresh)").action(async () => {
40422
+ readStdin();
40423
+ try {
40424
+ const root = resolveContextRoot();
40425
+ if (root) await runAssetDriftRefresh(root);
40426
+ } catch {
40427
+ }
40428
+ process.exit(0);
40429
+ });
40297
40430
  hook.command("ensure-dashboard").description("Open the web dashboard if it is not already running (called by Claude Code SessionStart hook)").action(async () => {
40298
40431
  readStdin();
40299
40432
  if (process.env.DREAMCONTEXT_AUTO_DASHBOARD === "0") process.exit(0);
40433
+ if (readAppManifest() !== null) process.exit(0);
40300
40434
  const root = resolveContextRoot();
40301
40435
  if (!root) process.exit(0);
40302
40436
  const port = resolveDashboardPort();
@@ -40333,6 +40467,7 @@ var init_hook = __esm({
40333
40467
  init_version_check();
40334
40468
  init_manifest();
40335
40469
  init_app();
40470
+ init_asset_drift();
40336
40471
  init_install_skill();
40337
40472
  MAX_TRANSCRIPT_BYTES2 = 50 * 1024 * 1024;
40338
40473
  SKILL_SCORE_THRESHOLD = 1;
@@ -40363,11 +40498,11 @@ var init_hook = __esm({
40363
40498
  });
40364
40499
 
40365
40500
  // src/cli/commands/doctor.ts
40366
- import { existsSync as existsSync52, readFileSync as readFileSync40, readdirSync as readdirSync13, statSync as statSync8 } from "fs";
40367
- import { join as join50 } from "path";
40501
+ import { existsSync as existsSync54, readFileSync as readFileSync42, readdirSync as readdirSync14, statSync as statSync8 } from "fs";
40502
+ import { join as join52 } from "path";
40368
40503
  function checkFile(root, relPath, label, required) {
40369
- const fullPath = join50(root, relPath);
40370
- if (!existsSync52(fullPath)) {
40504
+ const fullPath = join52(root, relPath);
40505
+ if (!existsSync54(fullPath)) {
40371
40506
  return {
40372
40507
  name: label,
40373
40508
  status: required ? "error" : "warn",
@@ -40383,7 +40518,7 @@ function checkFile(root, relPath, label, required) {
40383
40518
  };
40384
40519
  }
40385
40520
  if (relPath.endsWith(".md")) {
40386
- const content = readFileSync40(fullPath, "utf-8");
40521
+ const content = readFileSync42(fullPath, "utf-8");
40387
40522
  if (content.includes("(Add your") || content.includes("{{") || content.includes("(To be defined)")) {
40388
40523
  return {
40389
40524
  name: label,
@@ -40395,12 +40530,12 @@ function checkFile(root, relPath, label, required) {
40395
40530
  return { name: label, status: "ok", message: relPath };
40396
40531
  }
40397
40532
  function checkJson(root, relPath, label) {
40398
- const fullPath = join50(root, relPath);
40399
- if (!existsSync52(fullPath)) {
40533
+ const fullPath = join52(root, relPath);
40534
+ if (!existsSync54(fullPath)) {
40400
40535
  return { name: label, status: "error", message: `Missing: ${relPath}` };
40401
40536
  }
40402
40537
  try {
40403
- const content = readFileSync40(fullPath, "utf-8");
40538
+ const content = readFileSync42(fullPath, "utf-8");
40404
40539
  JSON.parse(content);
40405
40540
  return { name: label, status: "ok", message: relPath };
40406
40541
  } catch {
@@ -40408,8 +40543,8 @@ function checkJson(root, relPath, label) {
40408
40543
  }
40409
40544
  }
40410
40545
  function checkDirectory(root, relPath, label) {
40411
- const fullPath = join50(root, relPath);
40412
- if (!existsSync52(fullPath)) {
40546
+ const fullPath = join52(root, relPath);
40547
+ if (!existsSync54(fullPath)) {
40413
40548
  return { name: label, status: "error", message: `Missing directory: ${relPath}` };
40414
40549
  }
40415
40550
  return { name: label, status: "ok", message: relPath };
@@ -40417,13 +40552,13 @@ function checkDirectory(root, relPath, label) {
40417
40552
  function checkDataStructures(root) {
40418
40553
  const results = [];
40419
40554
  const dirRel = "knowledge/data-structures";
40420
- const dirAbs = join50(root, dirRel);
40555
+ const dirAbs = join52(root, dirRel);
40421
40556
  const oldRel = "core/data-structures";
40422
- const oldAbs = join50(root, oldRel);
40423
- const oldExists = existsSync52(oldAbs);
40557
+ const oldAbs = join52(root, oldRel);
40558
+ const oldExists = existsSync54(oldAbs);
40424
40559
  const legacyRel = "core/5.data_structures.sql";
40425
- const legacyExists = existsSync52(join50(root, legacyRel));
40426
- if (!existsSync52(dirAbs)) {
40560
+ const legacyExists = existsSync54(join52(root, legacyRel));
40561
+ if (!existsSync54(dirAbs)) {
40427
40562
  if (oldExists) {
40428
40563
  results.push({
40429
40564
  name: "Data structures",
@@ -40447,7 +40582,7 @@ function checkDataStructures(root) {
40447
40582
  }
40448
40583
  let mdCount = 0;
40449
40584
  try {
40450
- mdCount = readdirSync13(dirAbs).filter((f) => f.endsWith(".md")).length;
40585
+ mdCount = readdirSync14(dirAbs).filter((f) => f.endsWith(".md")).length;
40451
40586
  } catch {
40452
40587
  results.push({
40453
40588
  name: "Data structures",
@@ -40519,19 +40654,19 @@ function registerDoctorCommand(program2) {
40519
40654
  checkFile(root, "core/4.tech_stack.md", "Tech stack", false),
40520
40655
  ...checkDataStructures(root),
40521
40656
  // Taxonomy vocabulary (non-fatal: absent means DEFAULT_VOCABULARY used)
40522
- ...!existsSync52(join50(root, "core", "taxonomy.json")) ? [{
40657
+ ...!existsSync54(join52(root, "core", "taxonomy.json")) ? [{
40523
40658
  name: "Taxonomy vocabulary",
40524
40659
  status: "warn",
40525
40660
  message: "core/taxonomy.json not found \u2014 run `dreamcontext taxonomy init` to scaffold it"
40526
40661
  }] : [checkJson(root, "core/taxonomy.json", "Taxonomy vocabulary")],
40527
40662
  // Sleep state (optional — created on first Stop hook)
40528
- ...existsSync52(join50(root, "state", ".sleep.json")) ? [checkJson(root, "state/.sleep.json", "Sleep state")] : [],
40529
- ...existsSync52(join50(root, "state", ".platforms.json")) ? [checkJson(root, "state/.platforms.json", "Platform defaults")] : []
40663
+ ...existsSync54(join52(root, "state", ".sleep.json")) ? [checkJson(root, "state/.sleep.json", "Sleep state")] : [],
40664
+ ...existsSync54(join52(root, "state", ".platforms.json")) ? [checkJson(root, "state/.platforms.json", "Platform defaults")] : []
40530
40665
  ];
40531
- const sleepPath = join50(root, "state", ".sleep.json");
40532
- if (existsSync52(sleepPath)) {
40666
+ const sleepPath = join52(root, "state", ".sleep.json");
40667
+ if (existsSync54(sleepPath)) {
40533
40668
  try {
40534
- const parsed = JSON.parse(readFileSync40(sleepPath, "utf-8"));
40669
+ const parsed = JSON.parse(readFileSync42(sleepPath, "utf-8"));
40535
40670
  if (typeof parsed.debt !== "number" || parsed.debt < 0) {
40536
40671
  results.push({ name: "Sleep debt", status: "warn", message: "Invalid debt value in .sleep.json" });
40537
40672
  }
@@ -40694,23 +40829,23 @@ var init_middleware = __esm({
40694
40829
  });
40695
40830
 
40696
40831
  // src/server/static.ts
40697
- import { existsSync as existsSync53, readFileSync as readFileSync41, statSync as statSync9 } from "fs";
40698
- import { join as join51, extname as extname3 } from "path";
40832
+ import { existsSync as existsSync55, readFileSync as readFileSync43, statSync as statSync9 } from "fs";
40833
+ import { join as join53, extname as extname3 } from "path";
40699
40834
  function serveStatic(req, res, staticDir) {
40700
40835
  const url = new URL(req.url || "/", `http://${req.headers.host}`);
40701
- let filePath = join51(staticDir, url.pathname);
40836
+ let filePath = join53(staticDir, url.pathname);
40702
40837
  if (!filePath.startsWith(staticDir)) {
40703
40838
  res.writeHead(403, { "Content-Type": "text/plain" });
40704
40839
  res.end("Forbidden");
40705
40840
  return;
40706
40841
  }
40707
- if (existsSync53(filePath) && statSync9(filePath).isDirectory()) {
40708
- filePath = join51(filePath, "index.html");
40842
+ if (existsSync55(filePath) && statSync9(filePath).isDirectory()) {
40843
+ filePath = join53(filePath, "index.html");
40709
40844
  }
40710
- if (existsSync53(filePath) && statSync9(filePath).isFile()) {
40845
+ if (existsSync55(filePath) && statSync9(filePath).isFile()) {
40711
40846
  const ext = extname3(filePath);
40712
40847
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
40713
- const content = readFileSync41(filePath);
40848
+ const content = readFileSync43(filePath);
40714
40849
  res.writeHead(200, {
40715
40850
  "Content-Type": contentType,
40716
40851
  "Content-Length": content.length,
@@ -40719,9 +40854,9 @@ function serveStatic(req, res, staticDir) {
40719
40854
  res.end(content);
40720
40855
  return;
40721
40856
  }
40722
- const indexPath2 = join51(staticDir, "index.html");
40723
- if (existsSync53(indexPath2)) {
40724
- const content = readFileSync41(indexPath2);
40857
+ const indexPath2 = join53(staticDir, "index.html");
40858
+ if (existsSync55(indexPath2)) {
40859
+ const content = readFileSync43(indexPath2);
40725
40860
  res.writeHead(200, {
40726
40861
  "Content-Type": "text/html; charset=utf-8",
40727
40862
  "Content-Length": content.length,
@@ -41242,20 +41377,20 @@ var init_sleep2 = __esm({
41242
41377
  });
41243
41378
 
41244
41379
  // src/server/routes/core.ts
41245
- import { existsSync as existsSync54, readdirSync as readdirSync14 } from "fs";
41246
- import { join as join52 } from "path";
41380
+ import { existsSync as existsSync56, readdirSync as readdirSync15 } from "fs";
41381
+ import { join as join54 } from "path";
41247
41382
  function getCoreDir(contextRoot) {
41248
- return join52(contextRoot, "core");
41383
+ return join54(contextRoot, "core");
41249
41384
  }
41250
41385
  async function handleCoreList(_req, res, _params, contextRoot) {
41251
41386
  const coreDir = getCoreDir(contextRoot);
41252
- if (!existsSync54(coreDir)) {
41387
+ if (!existsSync56(coreDir)) {
41253
41388
  sendJson(res, 200, { files: [] });
41254
41389
  return;
41255
41390
  }
41256
- const entries = readdirSync14(coreDir, { withFileTypes: true });
41391
+ const entries = readdirSync15(coreDir, { withFileTypes: true });
41257
41392
  const files = entries.filter((e) => e.isFile() && (e.name.endsWith(".md") || e.name.endsWith(".sql") || e.name.endsWith(".json"))).map((e) => {
41258
- const filePath = join52(coreDir, e.name);
41393
+ const filePath = join54(coreDir, e.name);
41259
41394
  let frontmatter = {};
41260
41395
  if (e.name.endsWith(".md")) {
41261
41396
  try {
@@ -41279,13 +41414,13 @@ async function handleCoreGet(_req, res, params, contextRoot) {
41279
41414
  sendError(res, 400, "invalid_path", "Invalid filename.");
41280
41415
  return;
41281
41416
  }
41282
- if (!existsSync54(filePath)) {
41417
+ if (!existsSync56(filePath)) {
41283
41418
  sendError(res, 404, "not_found", `Core file not found: ${filename}`);
41284
41419
  return;
41285
41420
  }
41286
41421
  if (filename.endsWith(".json")) {
41287
- const { readFileSync: readFileSync67 } = await import("fs");
41288
- const raw2 = readFileSync67(filePath, "utf-8");
41422
+ const { readFileSync: readFileSync69 } = await import("fs");
41423
+ const raw2 = readFileSync69(filePath, "utf-8");
41289
41424
  try {
41290
41425
  const data = JSON.parse(raw2);
41291
41426
  sendJson(res, 200, { filename, type: "json", data });
@@ -41319,8 +41454,8 @@ async function handleCoreGet(_req, res, params, contextRoot) {
41319
41454
  });
41320
41455
  return;
41321
41456
  }
41322
- const { readFileSync: readFileSync66 } = await import("fs");
41323
- const raw = readFileSync66(filePath, "utf-8");
41457
+ const { readFileSync: readFileSync68 } = await import("fs");
41458
+ const raw = readFileSync68(filePath, "utf-8");
41324
41459
  sendJson(res, 200, { filename, type: "text", content: raw });
41325
41460
  }
41326
41461
  async function handleCoreUpdate(req, res, params, contextRoot) {
@@ -41330,7 +41465,7 @@ async function handleCoreUpdate(req, res, params, contextRoot) {
41330
41465
  sendError(res, 400, "invalid_path", "Invalid filename.");
41331
41466
  return;
41332
41467
  }
41333
- if (!existsSync54(filePath)) {
41468
+ if (!existsSync56(filePath)) {
41334
41469
  sendError(res, 404, "not_found", `Core file not found: ${filename}`);
41335
41470
  return;
41336
41471
  }
@@ -41370,8 +41505,8 @@ async function handleCoreUpdate(req, res, params, contextRoot) {
41370
41505
  return;
41371
41506
  }
41372
41507
  changedParts.push("content");
41373
- const { writeFileSync: writeFileSync45 } = await import("fs");
41374
- writeFileSync45(filePath, body.content, "utf-8");
41508
+ const { writeFileSync: writeFileSync46 } = await import("fs");
41509
+ writeFileSync46(filePath, body.content, "utf-8");
41375
41510
  }
41376
41511
  const what = changedParts.length > 0 ? changedParts.join(" and ") : "file";
41377
41512
  recordDashboardChange(contextRoot, {
@@ -41394,10 +41529,10 @@ var init_core2 = __esm({
41394
41529
  });
41395
41530
 
41396
41531
  // src/server/routes/knowledge.ts
41397
- import { existsSync as existsSync55 } from "fs";
41398
- import { join as join53 } from "path";
41532
+ import { existsSync as existsSync57 } from "fs";
41533
+ import { join as join55 } from "path";
41399
41534
  function getKnowledgeDir2(contextRoot) {
41400
- return join53(contextRoot, "knowledge");
41535
+ return join55(contextRoot, "knowledge");
41401
41536
  }
41402
41537
  async function handleKnowledgeList(_req, res, _params, contextRoot) {
41403
41538
  const entries = buildKnowledgeIndex(contextRoot);
@@ -41410,7 +41545,7 @@ async function handleKnowledgeGet(_req, res, params, contextRoot) {
41410
41545
  sendError(res, 400, "invalid_path", `Invalid knowledge slug: ${slug}`);
41411
41546
  return;
41412
41547
  }
41413
- if (!existsSync55(filePath)) {
41548
+ if (!existsSync57(filePath)) {
41414
41549
  sendError(res, 404, "not_found", `Knowledge file not found: ${slug}`);
41415
41550
  return;
41416
41551
  }
@@ -41434,7 +41569,7 @@ async function handleKnowledgeUpdate(req, res, params, contextRoot) {
41434
41569
  sendError(res, 400, "invalid_path", `Invalid knowledge slug: ${slug}`);
41435
41570
  return;
41436
41571
  }
41437
- if (!existsSync55(filePath)) {
41572
+ if (!existsSync57(filePath)) {
41438
41573
  sendError(res, 404, "not_found", `Knowledge file not found: ${slug}`);
41439
41574
  return;
41440
41575
  }
@@ -41491,14 +41626,14 @@ var init_knowledge2 = __esm({
41491
41626
  });
41492
41627
 
41493
41628
  // src/server/routes/features.ts
41494
- import { existsSync as existsSync56 } from "fs";
41495
- import { join as join54, basename as basename16 } from "path";
41629
+ import { existsSync as existsSync58 } from "fs";
41630
+ import { join as join56, basename as basename16 } from "path";
41496
41631
  function getFeaturesDir2(contextRoot) {
41497
- return join54(contextRoot, "core", "features");
41632
+ return join56(contextRoot, "core", "features");
41498
41633
  }
41499
41634
  async function handleFeaturesList(_req, res, _params, contextRoot) {
41500
41635
  const featuresDir = getFeaturesDir2(contextRoot);
41501
- if (!existsSync56(featuresDir)) {
41636
+ if (!existsSync58(featuresDir)) {
41502
41637
  sendJson(res, 200, { features: [] });
41503
41638
  return;
41504
41639
  }
@@ -41529,7 +41664,7 @@ async function handleFeaturesGet(_req, res, params, contextRoot) {
41529
41664
  sendError(res, 400, "invalid_path", `Invalid feature slug: ${slug}`);
41530
41665
  return;
41531
41666
  }
41532
- if (!existsSync56(filePath)) {
41667
+ if (!existsSync58(filePath)) {
41533
41668
  sendError(res, 404, "not_found", `Feature not found: ${slug}`);
41534
41669
  return;
41535
41670
  }
@@ -41571,11 +41706,11 @@ var init_features2 = __esm({
41571
41706
  });
41572
41707
 
41573
41708
  // src/server/routes/changelog.ts
41574
- import { existsSync as existsSync57 } from "fs";
41575
- import { join as join55 } from "path";
41709
+ import { existsSync as existsSync59 } from "fs";
41710
+ import { join as join57 } from "path";
41576
41711
  async function handleChangelogGet(_req, res, _params, contextRoot) {
41577
- const filePath = join55(contextRoot, "core", "CHANGELOG.json");
41578
- if (!existsSync57(filePath)) {
41712
+ const filePath = join57(contextRoot, "core", "CHANGELOG.json");
41713
+ if (!existsSync59(filePath)) {
41579
41714
  sendJson(res, 200, { entries: [] });
41580
41715
  return;
41581
41716
  }
@@ -41587,8 +41722,8 @@ async function handleChangelogGet(_req, res, _params, contextRoot) {
41587
41722
  }
41588
41723
  }
41589
41724
  async function handleReleasesGet(_req, res, _params, contextRoot) {
41590
- const filePath = join55(contextRoot, "core", "RELEASES.json");
41591
- if (!existsSync57(filePath)) {
41725
+ const filePath = join57(contextRoot, "core", "RELEASES.json");
41726
+ if (!existsSync59(filePath)) {
41592
41727
  sendJson(res, 200, { entries: [] });
41593
41728
  return;
41594
41729
  }
@@ -41642,7 +41777,7 @@ async function handleReleasesCreate(req, res, _params, contextRoot) {
41642
41777
  tasks: Array.isArray(body.tasks) ? body.tasks : [],
41643
41778
  changelog: Array.isArray(body.changelog) ? body.changelog : []
41644
41779
  };
41645
- const filePath = join55(contextRoot, "core", "RELEASES.json");
41780
+ const filePath = join57(contextRoot, "core", "RELEASES.json");
41646
41781
  insertToJsonArray(filePath, release2);
41647
41782
  if (release2.features.length > 0) {
41648
41783
  backPopulateFeatures(contextRoot, release2.features, release2.version);
@@ -41661,8 +41796,8 @@ async function handleReleasesUpdate(req, res, params, contextRoot) {
41661
41796
  sendError(res, 400, "invalid_body", "Request body must be JSON.");
41662
41797
  return;
41663
41798
  }
41664
- const filePath = join55(contextRoot, "core", "RELEASES.json");
41665
- if (!existsSync57(filePath)) {
41799
+ const filePath = join57(contextRoot, "core", "RELEASES.json");
41800
+ if (!existsSync59(filePath)) {
41666
41801
  sendError(res, 404, "not_found", `Release not found: ${params.version}`);
41667
41802
  return;
41668
41803
  }
@@ -41716,8 +41851,8 @@ var init_changelog = __esm({
41716
41851
  });
41717
41852
 
41718
41853
  // src/lib/graph.ts
41719
- import { existsSync as existsSync58, readFileSync as readFileSync42 } from "fs";
41720
- import { join as join56, basename as basename17 } from "path";
41854
+ import { existsSync as existsSync60, readFileSync as readFileSync44 } from "fs";
41855
+ import { join as join58, basename as basename17 } from "path";
41721
41856
  function buildGraph(contextRoot) {
41722
41857
  const nodes = [];
41723
41858
  const links = [];
@@ -41731,14 +41866,14 @@ function buildGraph(contextRoot) {
41731
41866
  byId.set(node.id, node);
41732
41867
  if (slug) bySlug.set(slug, node);
41733
41868
  };
41734
- const coreDir = join56(contextRoot, "core");
41869
+ const coreDir = join58(contextRoot, "core");
41735
41870
  const foundational = [
41736
41871
  { prefix: "0", group: "soul" },
41737
41872
  { prefix: "1", group: "user" },
41738
41873
  { prefix: "2", group: "memory" }
41739
41874
  ];
41740
41875
  for (const { prefix, group } of foundational) {
41741
- if (!existsSync58(coreDir)) continue;
41876
+ if (!existsSync60(coreDir)) continue;
41742
41877
  const matches = import_fast_glob15.default.sync(`${prefix}.*.md`, { cwd: coreDir, absolute: true });
41743
41878
  for (const file of matches) {
41744
41879
  try {
@@ -41758,7 +41893,7 @@ function buildGraph(contextRoot) {
41758
41893
  }
41759
41894
  }
41760
41895
  }
41761
- if (existsSync58(coreDir)) {
41896
+ if (existsSync60(coreDir)) {
41762
41897
  const others = import_fast_glob15.default.sync("[3-9]*.md", { cwd: coreDir, absolute: true });
41763
41898
  for (const file of others) {
41764
41899
  const filename = basename17(file);
@@ -41778,8 +41913,8 @@ function buildGraph(contextRoot) {
41778
41913
  }
41779
41914
  }
41780
41915
  }
41781
- const featuresDir = join56(coreDir, "features");
41782
- if (existsSync58(featuresDir)) {
41916
+ const featuresDir = join58(coreDir, "features");
41917
+ if (existsSync60(featuresDir)) {
41783
41918
  const files = import_fast_glob15.default.sync("*.md", { cwd: featuresDir, absolute: true });
41784
41919
  for (const file of files) {
41785
41920
  const fileSlug = basename17(file, ".md");
@@ -41809,8 +41944,8 @@ function buildGraph(contextRoot) {
41809
41944
  }
41810
41945
  }
41811
41946
  }
41812
- const stateDir = join56(contextRoot, "state");
41813
- if (existsSync58(stateDir)) {
41947
+ const stateDir = join58(contextRoot, "state");
41948
+ if (existsSync60(stateDir)) {
41814
41949
  const files = import_fast_glob15.default.sync("*.md", { cwd: stateDir, absolute: true });
41815
41950
  for (const file of files) {
41816
41951
  const fileSlug = basename17(file, ".md");
@@ -41861,8 +41996,8 @@ function buildGraph(contextRoot) {
41861
41996
  entry.slug
41862
41997
  );
41863
41998
  }
41864
- const inboxDir2 = join56(contextRoot, "inbox");
41865
- if (existsSync58(inboxDir2)) {
41999
+ const inboxDir2 = join58(contextRoot, "inbox");
42000
+ if (existsSync60(inboxDir2)) {
41866
42001
  const files = import_fast_glob15.default.sync("*.md", { cwd: inboxDir2, absolute: true });
41867
42002
  for (const file of files) {
41868
42003
  const slug = basename17(file, ".md");
@@ -41883,11 +42018,11 @@ function buildGraph(contextRoot) {
41883
42018
  });
41884
42019
  }
41885
42020
  }
41886
- const releasesPath = join56(coreDir, "RELEASES.json");
42021
+ const releasesPath = join58(coreDir, "RELEASES.json");
41887
42022
  let releases = [];
41888
- if (existsSync58(releasesPath)) {
42023
+ if (existsSync60(releasesPath)) {
41889
42024
  try {
41890
- const parsed = JSON.parse(readFileSync42(releasesPath, "utf-8"));
42025
+ const parsed = JSON.parse(readFileSync44(releasesPath, "utf-8"));
41891
42026
  if (Array.isArray(parsed)) releases = parsed;
41892
42027
  } catch {
41893
42028
  }
@@ -41983,7 +42118,7 @@ var init_graph = __esm({
41983
42118
  });
41984
42119
 
41985
42120
  // src/server/routes/graph.ts
41986
- import { existsSync as existsSync59, readFileSync as readFileSync43 } from "fs";
42121
+ import { existsSync as existsSync61, readFileSync as readFileSync45 } from "fs";
41987
42122
  import { normalize, resolve as resolve11, sep as sep6 } from "path";
41988
42123
  async function handleGraphGet(_req, res, _params, contextRoot) {
41989
42124
  try {
@@ -42007,7 +42142,7 @@ async function handleGraphContentGet(req, res, _params, contextRoot) {
42007
42142
  sendError(res, 400, "invalid_path", "Path escapes context root.");
42008
42143
  return;
42009
42144
  }
42010
- if (!existsSync59(absTarget)) {
42145
+ if (!existsSync61(absTarget)) {
42011
42146
  sendError(res, 404, "not_found", `Path not found: ${rawPath}`);
42012
42147
  return;
42013
42148
  }
@@ -42028,7 +42163,7 @@ async function handleGraphContentGet(req, res, _params, contextRoot) {
42028
42163
  }
42029
42164
  if (absTarget.endsWith(".json")) {
42030
42165
  try {
42031
- const raw = readFileSync43(absTarget, "utf-8");
42166
+ const raw = readFileSync45(absTarget, "utf-8");
42032
42167
  try {
42033
42168
  sendJson(res, 200, { path: rawPath, type: "json", data: JSON.parse(raw) });
42034
42169
  } catch {
@@ -42041,7 +42176,7 @@ async function handleGraphContentGet(req, res, _params, contextRoot) {
42041
42176
  return;
42042
42177
  }
42043
42178
  try {
42044
- const content = readFileSync43(absTarget, "utf-8");
42179
+ const content = readFileSync45(absTarget, "utf-8");
42045
42180
  sendJson(res, 200, { path: rawPath, type: "text", content });
42046
42181
  } catch (err) {
42047
42182
  const message = err instanceof Error ? err.message : "Failed to read file";
@@ -42058,12 +42193,12 @@ var init_graph2 = __esm({
42058
42193
  });
42059
42194
 
42060
42195
  // src/lib/council.ts
42061
- import { existsSync as existsSync60, mkdirSync as mkdirSync24, readFileSync as readFileSync44 } from "fs";
42062
- import { join as join57, resolve as resolve12, sep as sep7 } from "path";
42196
+ import { existsSync as existsSync62, mkdirSync as mkdirSync25, readFileSync as readFileSync46 } from "fs";
42197
+ import { join as join59, resolve as resolve12, sep as sep7 } from "path";
42063
42198
  import { fileURLToPath as fileURLToPath6 } from "url";
42064
42199
  function getCouncilDir() {
42065
42200
  const root = ensureContextRoot();
42066
- return join57(root, "council");
42201
+ return join59(root, "council");
42067
42202
  }
42068
42203
  function assertSafeSegment(kind, id) {
42069
42204
  if (!id || typeof id !== "string") {
@@ -42086,29 +42221,29 @@ function assertWithinCouncil(target) {
42086
42221
  }
42087
42222
  function getDebateDir(debateId) {
42088
42223
  assertSafeSegment("debate_id", debateId);
42089
- const target = join57(getCouncilDir(), debateId);
42224
+ const target = join59(getCouncilDir(), debateId);
42090
42225
  return assertWithinCouncil(target);
42091
42226
  }
42092
42227
  function getPersonaDir(debateId, personaSlug) {
42093
42228
  assertSafeSegment("persona_slug", personaSlug);
42094
- const target = join57(getDebateDir(debateId), personaSlug);
42229
+ const target = join59(getDebateDir(debateId), personaSlug);
42095
42230
  return assertWithinCouncil(target);
42096
42231
  }
42097
42232
  function getCouncilIndexPath() {
42098
- return join57(getCouncilDir(), "index.json");
42233
+ return join59(getCouncilDir(), "index.json");
42099
42234
  }
42100
42235
  function ensureCouncilDir() {
42101
42236
  const dir = getCouncilDir();
42102
- mkdirSync24(dir, { recursive: true });
42237
+ mkdirSync25(dir, { recursive: true });
42103
42238
  const indexPath2 = getCouncilIndexPath();
42104
- if (!existsSync60(indexPath2)) {
42239
+ if (!existsSync62(indexPath2)) {
42105
42240
  writeJsonArray(indexPath2, []);
42106
42241
  }
42107
42242
  return dir;
42108
42243
  }
42109
42244
  function ensureDebateExists(debateId) {
42110
42245
  const dir = getDebateDir(debateId);
42111
- if (!existsSync60(dir)) {
42246
+ if (!existsSync62(dir)) {
42112
42247
  throw new Error(`Debate not found: ${debateId}`);
42113
42248
  }
42114
42249
  return dir;
@@ -42116,19 +42251,19 @@ function ensureDebateExists(debateId) {
42116
42251
  function ensurePersonaExists(debateId, personaSlug) {
42117
42252
  ensureDebateExists(debateId);
42118
42253
  const dir = getPersonaDir(debateId, personaSlug);
42119
- if (!existsSync60(dir)) {
42254
+ if (!existsSync62(dir)) {
42120
42255
  throw new Error(`Persona not found in ${debateId}: ${personaSlug}`);
42121
42256
  }
42122
42257
  return dir;
42123
42258
  }
42124
42259
  function readDebateFrontmatter(debateId) {
42125
42260
  ensureDebateExists(debateId);
42126
- const { data } = readFrontmatter(join57(getDebateDir(debateId), "debate.md"));
42261
+ const { data } = readFrontmatter(join59(getDebateDir(debateId), "debate.md"));
42127
42262
  return data;
42128
42263
  }
42129
42264
  function loadCouncilIndex() {
42130
42265
  const indexPath2 = getCouncilIndexPath();
42131
- if (!existsSync60(indexPath2)) return [];
42266
+ if (!existsSync62(indexPath2)) return [];
42132
42267
  return readJsonArray(indexPath2);
42133
42268
  }
42134
42269
  function saveCouncilIndex(entries) {
@@ -42146,17 +42281,17 @@ function upsertCouncilIndex(entry) {
42146
42281
  }
42147
42282
  function loadTemplate(filename) {
42148
42283
  const candidates = [
42149
- join57(__dirname6, "templates", filename),
42284
+ join59(__dirname6, "templates", filename),
42150
42285
  // bundled: dist/templates/
42151
- join57(__dirname6, "..", "templates", filename),
42286
+ join59(__dirname6, "..", "templates", filename),
42152
42287
  // alt layout
42153
- join57(__dirname6, "..", "src", "templates", filename),
42288
+ join59(__dirname6, "..", "src", "templates", filename),
42154
42289
  // dev fallback
42155
- join57(__dirname6, "..", "..", "src", "templates", filename)
42290
+ join59(__dirname6, "..", "..", "src", "templates", filename)
42156
42291
  ];
42157
42292
  for (const path2 of candidates) {
42158
- if (existsSync60(path2)) {
42159
- return readFileSync44(path2, "utf-8");
42293
+ if (existsSync62(path2)) {
42294
+ return readFileSync46(path2, "utf-8");
42160
42295
  }
42161
42296
  }
42162
42297
  throw new Error(`Template not found: ${filename}`);
@@ -42230,8 +42365,8 @@ function parseReportRounds(reportContent) {
42230
42365
  return entries;
42231
42366
  }
42232
42367
  function getPersonaRoundSummary(debateId, personaSlug, round) {
42233
- const reportPath = join57(getPersonaDir(debateId, personaSlug), "report.md");
42234
- if (!existsSync60(reportPath)) return null;
42368
+ const reportPath = join59(getPersonaDir(debateId, personaSlug), "report.md");
42369
+ if (!existsSync62(reportPath)) return null;
42235
42370
  const { content } = readFrontmatter(reportPath);
42236
42371
  const entries = parseReportRounds(content);
42237
42372
  const entry = entries.find((e) => e.round === round);
@@ -42265,10 +42400,10 @@ var init_council = __esm({
42265
42400
  });
42266
42401
 
42267
42402
  // src/server/routes/council.ts
42268
- import { existsSync as existsSync61 } from "fs";
42269
- import { join as join58, resolve as resolve13, sep as sep8 } from "path";
42403
+ import { existsSync as existsSync63 } from "fs";
42404
+ import { join as join60, resolve as resolve13, sep as sep8 } from "path";
42270
42405
  function getCouncilDir2(contextRoot) {
42271
- return join58(contextRoot, "council");
42406
+ return join60(contextRoot, "council");
42272
42407
  }
42273
42408
  function assertSafeSegment2(id) {
42274
42409
  if (!id || typeof id !== "string") return false;
@@ -42321,14 +42456,14 @@ function toParsedRound(entry) {
42321
42456
  };
42322
42457
  }
42323
42458
  function loadPersonaDetail(debateDir, slug) {
42324
- const personaDir = join58(debateDir, slug);
42325
- if (!existsSync61(personaDir)) return null;
42326
- const personaFile = join58(personaDir, "context-and-persona.md");
42327
- const reportFile = join58(personaDir, "report.md");
42459
+ const personaDir = join60(debateDir, slug);
42460
+ if (!existsSync63(personaDir)) return null;
42461
+ const personaFile = join60(personaDir, "context-and-persona.md");
42462
+ const reportFile = join60(personaDir, "report.md");
42328
42463
  let fm = { name: slug, model: "unknown", aspects: [], round_entries: 0 };
42329
42464
  let persona = "";
42330
42465
  let crossContext = {};
42331
- if (existsSync61(personaFile)) {
42466
+ if (existsSync63(personaFile)) {
42332
42467
  const parsed = readFrontmatter(personaFile);
42333
42468
  fm = {
42334
42469
  name: parsed.data.name ?? slug,
@@ -42341,13 +42476,13 @@ function loadPersonaDetail(debateDir, slug) {
42341
42476
  crossContext = split.crossContext;
42342
42477
  }
42343
42478
  let rounds = [];
42344
- if (existsSync61(reportFile)) {
42479
+ if (existsSync63(reportFile)) {
42345
42480
  const { content } = readFrontmatter(reportFile);
42346
42481
  rounds = parseReportRounds(content).map(toParsedRound);
42347
42482
  }
42348
- const researchIndex = join58(personaDir, "researches", "index.json");
42483
+ const researchIndex = join60(personaDir, "researches", "index.json");
42349
42484
  let researches = [];
42350
- if (existsSync61(researchIndex)) {
42485
+ if (existsSync63(researchIndex)) {
42351
42486
  try {
42352
42487
  researches = readJsonArray(researchIndex);
42353
42488
  } catch {
@@ -42357,17 +42492,17 @@ function loadPersonaDetail(debateDir, slug) {
42357
42492
  return { slug, frontmatter: fm, persona, crossContext, rounds, researches };
42358
42493
  }
42359
42494
  async function handleCouncilList(_req, res, _params, contextRoot) {
42360
- const indexPath2 = join58(getCouncilDir2(contextRoot), "index.json");
42361
- if (!existsSync61(indexPath2)) {
42495
+ const indexPath2 = join60(getCouncilDir2(contextRoot), "index.json");
42496
+ if (!existsSync63(indexPath2)) {
42362
42497
  sendJson(res, 200, { debates: [] });
42363
42498
  return;
42364
42499
  }
42365
42500
  try {
42366
42501
  const debates = readJsonArray(indexPath2);
42367
42502
  const enriched = debates.map((d) => {
42368
- const debateFile = join58(getCouncilDir2(contextRoot), d.id, "debate.md");
42503
+ const debateFile = join60(getCouncilDir2(contextRoot), d.id, "debate.md");
42369
42504
  let personaSlugs = [];
42370
- if (existsSync61(debateFile)) {
42505
+ if (existsSync63(debateFile)) {
42371
42506
  try {
42372
42507
  const fm = readFrontmatter(debateFile).data;
42373
42508
  if (Array.isArray(fm.personas)) personaSlugs = fm.personas;
@@ -42390,14 +42525,14 @@ async function handleCouncilGet(_req, res, params, contextRoot) {
42390
42525
  return;
42391
42526
  }
42392
42527
  const councilDir = getCouncilDir2(contextRoot);
42393
- const debateDirUnchecked = join58(councilDir, debateId);
42528
+ const debateDirUnchecked = join60(councilDir, debateId);
42394
42529
  const debateDir = assertWithin(councilDir, debateDirUnchecked);
42395
- if (!debateDir || !existsSync61(debateDir)) {
42530
+ if (!debateDir || !existsSync63(debateDir)) {
42396
42531
  sendError(res, 404, "not_found", `Debate not found: ${debateId}`);
42397
42532
  return;
42398
42533
  }
42399
- const debateFile = join58(debateDir, "debate.md");
42400
- if (!existsSync61(debateFile)) {
42534
+ const debateFile = join60(debateDir, "debate.md");
42535
+ if (!existsSync63(debateFile)) {
42401
42536
  sendError(res, 404, "not_found", `Debate metadata missing: ${debateId}`);
42402
42537
  return;
42403
42538
  }
@@ -42414,11 +42549,11 @@ async function handleCouncilGet(_req, res, params, contextRoot) {
42414
42549
  created_at: String(fmRaw.created_at ?? ""),
42415
42550
  updated_at: String(fmRaw.updated_at ?? "")
42416
42551
  };
42417
- const roundLogFile = join58(debateDir, "round-log.md");
42418
- const roundLog = existsSync61(roundLogFile) ? readFrontmatter(roundLogFile).content : null;
42419
- const finalReportFile = join58(debateDir, "final-report.md");
42552
+ const roundLogFile = join60(debateDir, "round-log.md");
42553
+ const roundLog = existsSync63(roundLogFile) ? readFrontmatter(roundLogFile).content : null;
42554
+ const finalReportFile = join60(debateDir, "final-report.md");
42420
42555
  let finalReport = null;
42421
- if (existsSync61(finalReportFile)) {
42556
+ if (existsSync63(finalReportFile)) {
42422
42557
  const parsed = readFrontmatter(finalReportFile);
42423
42558
  finalReport = { frontmatter: parsed.data, content: parsed.content };
42424
42559
  }
@@ -42446,9 +42581,9 @@ async function handleCouncilResearchGet(_req, res, params, contextRoot) {
42446
42581
  const councilDir = getCouncilDir2(contextRoot);
42447
42582
  const researchFile = assertWithin(
42448
42583
  councilDir,
42449
- join58(councilDir, debateId, personaSlug, "researches", `${researchSlug}.md`)
42584
+ join60(councilDir, debateId, personaSlug, "researches", `${researchSlug}.md`)
42450
42585
  );
42451
- if (!researchFile || !existsSync61(researchFile)) {
42586
+ if (!researchFile || !existsSync63(researchFile)) {
42452
42587
  sendError(res, 404, "not_found", `Research not found: ${researchSlug}`);
42453
42588
  return;
42454
42589
  }
@@ -42466,9 +42601,9 @@ var init_council2 = __esm({
42466
42601
  });
42467
42602
 
42468
42603
  // src/server/routes/config.ts
42469
- import { dirname as dirname27 } from "path";
42604
+ import { dirname as dirname29 } from "path";
42470
42605
  async function handleConfigGet(_req, res, _params, contextRoot) {
42471
- const config = readSetupConfig(dirname27(contextRoot));
42606
+ const config = readSetupConfig(dirname29(contextRoot));
42472
42607
  sendJson(res, 200, { config });
42473
42608
  }
42474
42609
  async function handleConfigUpdate(req, res, _params, contextRoot) {
@@ -42552,14 +42687,14 @@ async function handleConfigUpdate(req, res, _params, contextRoot) {
42552
42687
  }
42553
42688
  picked.changelogTarget = "comments";
42554
42689
  }
42555
- const existing = readSetupConfig(dirname27(contextRoot))?.clickup ?? {};
42690
+ const existing = readSetupConfig(dirname29(contextRoot))?.clickup ?? {};
42556
42691
  patch.clickup = { ...existing, ...picked };
42557
42692
  }
42558
42693
  if (patch.platforms === void 0 && patch.packs === void 0 && patch.disableNativeMemory === void 0 && patch.taskBackend === void 0 && patch.cloudTaskManagement === void 0 && patch.clickup === void 0 && patch.shareable === void 0) {
42559
42694
  sendError(res, 400, "no_changes", "Provide at least one of: platforms, packs, disableNativeMemory, taskBackend, cloudTaskManagement, clickup, shareable.");
42560
42695
  return;
42561
42696
  }
42562
- const projectRoot = dirname27(contextRoot);
42697
+ const projectRoot = dirname29(contextRoot);
42563
42698
  if (patch.taskBackend === "clickup") {
42564
42699
  try {
42565
42700
  ensureRemoteBackendGitignore(projectRoot);
@@ -42586,11 +42721,11 @@ var init_config = __esm({
42586
42721
  });
42587
42722
 
42588
42723
  // src/server/routes/vaults.ts
42589
- import { dirname as dirname28, resolve as resolve14 } from "path";
42590
- import { existsSync as existsSync62 } from "fs";
42724
+ import { dirname as dirname30, resolve as resolve14 } from "path";
42725
+ import { existsSync as existsSync64 } from "fs";
42591
42726
  async function handleVaultsGet(_req, res, _params, contextRoot) {
42592
- const vaults = listVaults().map((v) => ({ ...v, exists: existsSync62(resolve14(v.path)) }));
42593
- const current = contextRoot ? vaults.find((v) => resolve14(v.path) === resolve14(dirname28(contextRoot)))?.name ?? null : null;
42727
+ const vaults = listVaults().map((v) => ({ ...v, exists: existsSync64(resolve14(v.path)) }));
42728
+ const current = contextRoot ? vaults.find((v) => resolve14(v.path) === resolve14(dirname30(contextRoot)))?.name ?? null : null;
42594
42729
  sendJson(res, 200, { vaults, current });
42595
42730
  }
42596
42731
  var init_vaults2 = __esm({
@@ -42602,7 +42737,7 @@ var init_vaults2 = __esm({
42602
42737
  });
42603
42738
 
42604
42739
  // src/lib/vault-discovery.ts
42605
- import { dirname as dirname29 } from "path";
42740
+ import { dirname as dirname31 } from "path";
42606
42741
  function discoverVaults(root) {
42607
42742
  const matches = import_fast_glob16.default.sync("**/_dream_context", {
42608
42743
  cwd: root,
@@ -42613,7 +42748,7 @@ function discoverVaults(root) {
42613
42748
  suppressErrors: true
42614
42749
  });
42615
42750
  const projects = /* @__PURE__ */ new Set();
42616
- for (const ctx of matches) projects.add(dirname29(ctx));
42751
+ for (const ctx of matches) projects.add(dirname31(ctx));
42617
42752
  return Array.from(projects).sort();
42618
42753
  }
42619
42754
  async function discoverVaultsAsync(root) {
@@ -42626,7 +42761,7 @@ async function discoverVaultsAsync(root) {
42626
42761
  suppressErrors: true
42627
42762
  });
42628
42763
  const projects = /* @__PURE__ */ new Set();
42629
- for (const ctx of matches) projects.add(dirname29(ctx));
42764
+ for (const ctx of matches) projects.add(dirname31(ctx));
42630
42765
  return Array.from(projects).sort();
42631
42766
  }
42632
42767
  var import_fast_glob16;
@@ -42684,8 +42819,8 @@ var init_ensure_cli = __esm({
42684
42819
  });
42685
42820
 
42686
42821
  // src/server/routes/launcher.ts
42687
- import { basename as basename18, isAbsolute, join as join59, resolve as resolve15, sep as sep9 } from "path";
42688
- import { existsSync as existsSync63, mkdirSync as mkdirSync25, readdirSync as readdirSync15, statSync as statSync10, createReadStream, readFileSync as readFileSync45, writeFileSync as writeFileSync32 } from "fs";
42822
+ import { basename as basename18, isAbsolute, join as join61, resolve as resolve15, sep as sep9 } from "path";
42823
+ import { existsSync as existsSync65, mkdirSync as mkdirSync26, readdirSync as readdirSync16, statSync as statSync10, createReadStream, readFileSync as readFileSync47, writeFileSync as writeFileSync33 } from "fs";
42689
42824
  import { homedir as homedir3 } from "os";
42690
42825
  import { execFile as execFile2, spawn as spawn4 } from "child_process";
42691
42826
  import { promisify as promisify2 } from "util";
@@ -42709,7 +42844,7 @@ async function handleLauncherDiscover(req, res, _params, _contextRoot) {
42709
42844
  return;
42710
42845
  }
42711
42846
  const resolvedRoot = resolve15(root);
42712
- if (!existsSync63(resolvedRoot)) {
42847
+ if (!existsSync65(resolvedRoot)) {
42713
42848
  sendError(res, 400, "invalid_root", `Path does not exist: ${resolvedRoot}`);
42714
42849
  return;
42715
42850
  }
@@ -42752,7 +42887,7 @@ async function handleLauncherRegister(req, res, _params, _contextRoot) {
42752
42887
  }
42753
42888
  function isNonEmptyDir(dir) {
42754
42889
  try {
42755
- return statSync10(dir).isDirectory() && readdirSync15(dir).length > 0;
42890
+ return statSync10(dir).isDirectory() && readdirSync16(dir).length > 0;
42756
42891
  } catch {
42757
42892
  return false;
42758
42893
  }
@@ -42777,30 +42912,30 @@ async function scaffoldProject(a, runner = defaultCliRunner, home) {
42777
42912
  throw new ScaffoldError("parentDir must be an absolute path.");
42778
42913
  }
42779
42914
  const resolvedParent = resolve15(parentDir);
42780
- if (!existsSync63(resolvedParent) || !statSync10(resolvedParent).isDirectory()) {
42915
+ if (!existsSync65(resolvedParent) || !statSync10(resolvedParent).isDirectory()) {
42781
42916
  throw new ScaffoldError(`Parent directory does not exist: ${resolvedParent}`);
42782
42917
  }
42783
42918
  target = resolve15(resolvedParent, name);
42784
- if (target !== join59(resolvedParent, name) || !target.startsWith(resolvedParent + sep9)) {
42919
+ if (target !== join61(resolvedParent, name) || !target.startsWith(resolvedParent + sep9)) {
42785
42920
  throw new ScaffoldError("Resolved project path escapes the parent directory.");
42786
42921
  }
42787
- if (isNonEmptyDir(target) && !existsSync63(join59(target, "_dream_context"))) {
42922
+ if (isNonEmptyDir(target) && !existsSync65(join61(target, "_dream_context"))) {
42788
42923
  throw new ScaffoldError(`A non-empty folder already exists at ${target}.`);
42789
42924
  }
42790
- mkdirSync25(target, { recursive: true });
42925
+ mkdirSync26(target, { recursive: true });
42791
42926
  } else if (a.mode === "existing") {
42792
42927
  const projectPath = (a.projectPath ?? "").trim();
42793
42928
  if (!projectPath || !isAbsolute(projectPath)) {
42794
42929
  throw new ScaffoldError("projectPath must be an absolute path.");
42795
42930
  }
42796
42931
  target = resolve15(projectPath);
42797
- if (!existsSync63(target) || !statSync10(target).isDirectory()) {
42932
+ if (!existsSync65(target) || !statSync10(target).isDirectory()) {
42798
42933
  throw new ScaffoldError(`Folder does not exist: ${target}`);
42799
42934
  }
42800
42935
  } else {
42801
42936
  throw new ScaffoldError("mode must be 'new' or 'existing'.");
42802
42937
  }
42803
- const alreadyProject = existsSync63(join59(target, "_dream_context"));
42938
+ const alreadyProject = existsSync65(join61(target, "_dream_context"));
42804
42939
  if (!alreadyProject) {
42805
42940
  const initArgs = ["init", "--yes", "--platforms", platformArg, "--name", name];
42806
42941
  if (a.description?.trim()) initArgs.push("--description", a.description.trim());
@@ -42855,13 +42990,13 @@ async function handleLauncherDetect(req, res, _params, _contextRoot) {
42855
42990
  return;
42856
42991
  }
42857
42992
  const resolved = resolve15(path2);
42858
- if (!existsSync63(resolved)) {
42993
+ if (!existsSync65(resolved)) {
42859
42994
  sendError(res, 400, "invalid_path", `Path does not exist: ${resolved}`);
42860
42995
  return;
42861
42996
  }
42862
42997
  sendJson(res, 200, {
42863
42998
  stack: detectTechStack(resolved) ?? "",
42864
- hasContext: existsSync63(join59(resolved, "_dream_context")),
42999
+ hasContext: existsSync65(join61(resolved, "_dream_context")),
42865
43000
  name: basename18(resolved)
42866
43001
  });
42867
43002
  }
@@ -42881,15 +43016,15 @@ async function handleLauncherCatalog(_req, res, _params, _contextRoot) {
42881
43016
  sendJson(res, 200, { platforms, packs });
42882
43017
  }
42883
43018
  function sleepyConfigPath() {
42884
- return join59(homedir3(), ".dreamcontext", "sleepy.json");
43019
+ return join61(homedir3(), ".dreamcontext", "sleepy.json");
42885
43020
  }
42886
43021
  async function handleSleepyConfigGet(_req, res, _params, _contextRoot) {
42887
43022
  let enabled = false;
42888
43023
  let hotkey = "Alt+Cmd+S";
42889
43024
  try {
42890
43025
  const p = sleepyConfigPath();
42891
- if (existsSync63(p)) {
42892
- const raw = JSON.parse(readFileSync45(p, "utf-8"));
43026
+ if (existsSync65(p)) {
43027
+ const raw = JSON.parse(readFileSync47(p, "utf-8"));
42893
43028
  enabled = raw.enabled === true;
42894
43029
  if (typeof raw.hotkey === "string" && raw.hotkey.trim()) hotkey = raw.hotkey;
42895
43030
  }
@@ -42907,8 +43042,8 @@ async function handleSleepyConfigSet(req, res, _params, _contextRoot) {
42907
43042
  const hotkey = typeof body.hotkey === "string" && body.hotkey.trim() ? body.hotkey.trim() : "Alt+Cmd+S";
42908
43043
  try {
42909
43044
  const p = sleepyConfigPath();
42910
- mkdirSync25(join59(homedir3(), ".dreamcontext"), { recursive: true });
42911
- writeFileSync32(p, JSON.stringify({ enabled, hotkey }, null, 2) + "\n", "utf-8");
43045
+ mkdirSync26(join61(homedir3(), ".dreamcontext"), { recursive: true });
43046
+ writeFileSync33(p, JSON.stringify({ enabled, hotkey }, null, 2) + "\n", "utf-8");
42912
43047
  sendJson(res, 200, { enabled, hotkey });
42913
43048
  } catch (err) {
42914
43049
  console.error("[launcher] sleepy-config write failed:", err);
@@ -42928,8 +43063,8 @@ async function handleSleepyVideo(req, res, _params, _contextRoot) {
42928
43063
  res.end();
42929
43064
  return;
42930
43065
  }
42931
- const file = join59(dir, `${mode}.mp4`);
42932
- if (!existsSync63(file)) {
43066
+ const file = join61(dir, `${mode}.mp4`);
43067
+ if (!existsSync65(file)) {
42933
43068
  res.writeHead(404);
42934
43069
  res.end();
42935
43070
  return;
@@ -42960,8 +43095,8 @@ async function handleSleepyAnim(req, res, _params, _contextRoot) {
42960
43095
  return;
42961
43096
  }
42962
43097
  const dir = process.env.DREAMCONTEXT_SLEEPY_DIR;
42963
- const file = dir ? join59(dir, `${mode}.webp`) : "";
42964
- if (!file || !existsSync63(file)) {
43098
+ const file = dir ? join61(dir, `${mode}.webp`) : "";
43099
+ if (!file || !existsSync65(file)) {
42965
43100
  res.writeHead(404);
42966
43101
  res.end();
42967
43102
  return;
@@ -43013,14 +43148,14 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
43013
43148
  return;
43014
43149
  }
43015
43150
  const cwd = resolve15(vault.path);
43016
- if (!existsSync63(cwd)) {
43151
+ if (!existsSync65(cwd)) {
43017
43152
  sendError(res, 400, "missing_vault", `Vault path no longer exists: ${cwd}`);
43018
43153
  return;
43019
43154
  }
43020
43155
  if (mode === "learn") {
43021
43156
  try {
43022
- const changelogPath = join59(cwd, "_dream_context", "core", "CHANGELOG.json");
43023
- if (!existsSync63(changelogPath)) {
43157
+ const changelogPath = join61(cwd, "_dream_context", "core", "CHANGELOG.json");
43158
+ if (!existsSync65(changelogPath)) {
43024
43159
  sendError(res, 400, "not_initialized", `"${vaultName}" has no _dream_context \u2014 run init first.`);
43025
43160
  return;
43026
43161
  }
@@ -43102,10 +43237,10 @@ async function handleLauncherCaptureStatus(req, res, _params, _contextRoot) {
43102
43237
  }
43103
43238
  async function handleLauncherDefaults(_req, res, _params, _contextRoot) {
43104
43239
  const home = homedir3();
43105
- sendJson(res, 200, { home, defaultParent: join59(home, "projects") });
43240
+ sendJson(res, 200, { home, defaultParent: join61(home, "projects") });
43106
43241
  }
43107
43242
  function computeVaultStatus(v, latest) {
43108
- const exists = existsSync63(resolve15(v.path));
43243
+ const exists = existsSync65(resolve15(v.path));
43109
43244
  let setupVersion = "0.0.0";
43110
43245
  let shareable = false;
43111
43246
  if (exists) {
@@ -43157,7 +43292,7 @@ async function handleLauncherUpdate(req, res, _params, _contextRoot) {
43157
43292
  return;
43158
43293
  }
43159
43294
  const target = resolve15(vault.path);
43160
- if (!existsSync63(target)) {
43295
+ if (!existsSync65(target)) {
43161
43296
  sendError(res, 400, "missing_vault", `Vault path no longer exists: ${target}`);
43162
43297
  return;
43163
43298
  }
@@ -43178,21 +43313,23 @@ async function handleLauncherFederationGraph(_req, res, _params, _contextRoot) {
43178
43313
  const shareableByName = new Map(nodes.map((n) => [n.name, n.shareable]));
43179
43314
  const known = new Set(vaults.map((v) => v.name));
43180
43315
  const edges = [];
43316
+ const connections = [];
43181
43317
  const seen = /* @__PURE__ */ new Set();
43182
43318
  for (const v of vaults) {
43183
- if (!existsSync63(resolve15(v.path))) continue;
43184
- const conns = listConnections(join59(resolve15(v.path), "_dream_context"));
43319
+ if (!existsSync65(resolve15(v.path))) continue;
43320
+ const conns = listConnections(join61(resolve15(v.path), "_dream_context"));
43185
43321
  for (const c of conns) {
43186
- if (c.direction !== "out" && c.direction !== "both") continue;
43187
43322
  if (!known.has(c.vault)) continue;
43188
43323
  if (c.status === "stale") continue;
43189
- const key = `${v.name}\0${c.vault}`;
43324
+ connections.push({ from: v.name, to: c.vault, direction: c.direction });
43325
+ if (c.direction !== "out" && c.direction !== "both") continue;
43326
+ const key = `${v.name} ${c.vault}`;
43190
43327
  if (seen.has(key)) continue;
43191
43328
  seen.add(key);
43192
43329
  edges.push({ source: v.name, target: c.vault, active: shareableByName.get(c.vault) === true });
43193
43330
  }
43194
43331
  }
43195
- sendJson(res, 200, { nodes, edges, latestVersion: latest });
43332
+ sendJson(res, 200, { nodes, edges, connections, latestVersion: latest });
43196
43333
  }
43197
43334
  async function handleLauncherConnectionCreate(req, res, _params, _contextRoot) {
43198
43335
  const body = await parseJsonBody(req);
@@ -43211,9 +43348,10 @@ async function handleLauncherConnectionCreate(req, res, _params, _contextRoot) {
43211
43348
  sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
43212
43349
  return;
43213
43350
  }
43214
- const fromRoot = join59(resolve15(fromVault.path), "_dream_context");
43351
+ const fromRoot = join61(resolve15(fromVault.path), "_dream_context");
43215
43352
  try {
43216
- addConnection(fromRoot, from, to, "out", null);
43353
+ const cur = dirToward(fromRoot, to);
43354
+ addConnection(fromRoot, from, to, addOut(cur?.dir ?? null), cur?.topics ?? null);
43217
43355
  sendJson(res, 200, { ok: true });
43218
43356
  } catch (err) {
43219
43357
  if (err instanceof VaultError) {
@@ -43241,9 +43379,83 @@ async function handleLauncherConnectionRemove(req, res, _params, _contextRoot) {
43241
43379
  sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
43242
43380
  return;
43243
43381
  }
43244
- const fromRoot = join59(resolve15(fromVault.path), "_dream_context");
43245
- const removed = removeConnection(fromRoot, to);
43246
- sendJson(res, 200, { ok: true, removed });
43382
+ const fromRoot = join61(resolve15(fromVault.path), "_dream_context");
43383
+ const a = dirToward(fromRoot, to);
43384
+ if (a) applyDir(fromRoot, from, to, dropOut(a.dir), a.topics);
43385
+ const toRoot = vaultRoot(to);
43386
+ if (toRoot) {
43387
+ const b = dirToward(toRoot, from);
43388
+ if (b) applyDir(toRoot, to, from, dropIn(b.dir), b.topics);
43389
+ }
43390
+ sendJson(res, 200, { ok: true, removed: true });
43391
+ }
43392
+ function dirToward(root, peer) {
43393
+ const c = listConnections(root).find((x) => x.vault === peer);
43394
+ return c ? { dir: c.direction, topics: c.topics } : null;
43395
+ }
43396
+ function vaultRoot(name) {
43397
+ const v = listVaults().find((x) => x.name === name);
43398
+ return v ? join61(resolve15(v.path), "_dream_context") : null;
43399
+ }
43400
+ function applyDir(fromRoot, fromName, peer, next, topics) {
43401
+ if (next === null) removeConnection(fromRoot, peer);
43402
+ else addConnection(fromRoot, fromName, peer, next, topics);
43403
+ }
43404
+ async function handleLauncherSyncCreate(req, res, _params, _contextRoot) {
43405
+ const body = await parseJsonBody(req);
43406
+ if (!body) {
43407
+ sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
43408
+ return;
43409
+ }
43410
+ const from = typeof body.from === "string" ? body.from.trim() : "";
43411
+ const to = typeof body.to === "string" ? body.to.trim() : "";
43412
+ if (!from || !to) {
43413
+ sendError(res, 400, "invalid_body", "from and to must be non-empty strings.");
43414
+ return;
43415
+ }
43416
+ const fromRoot = vaultRoot(from);
43417
+ const toRoot = vaultRoot(to);
43418
+ if (!fromRoot) {
43419
+ sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
43420
+ return;
43421
+ }
43422
+ if (!toRoot) {
43423
+ sendError(res, 400, "unknown_vault", `No registered vault named "${to}".`);
43424
+ return;
43425
+ }
43426
+ try {
43427
+ const a = dirToward(fromRoot, to);
43428
+ addConnection(fromRoot, from, to, addOut(a?.dir ?? null), a?.topics ?? null);
43429
+ const b = dirToward(toRoot, from);
43430
+ addConnection(toRoot, to, from, addIn(b?.dir ?? null), b?.topics ?? null);
43431
+ sendJson(res, 200, { ok: true });
43432
+ } catch (err) {
43433
+ if (err instanceof VaultError) {
43434
+ sendError(res, 400, "invalid_connection", err.message);
43435
+ return;
43436
+ }
43437
+ console.error("[launcher] sync create failed:", err);
43438
+ sendError(res, 500, "sync_failed", "Failed to enable sync.");
43439
+ }
43440
+ }
43441
+ async function handleLauncherSyncRemove(req, res, _params, _contextRoot) {
43442
+ const body = await parseJsonBody(req);
43443
+ if (!body) {
43444
+ sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
43445
+ return;
43446
+ }
43447
+ const from = typeof body.from === "string" ? body.from.trim() : "";
43448
+ const to = typeof body.to === "string" ? body.to.trim() : "";
43449
+ if (!from || !to) {
43450
+ sendError(res, 400, "invalid_body", "from and to must be non-empty strings.");
43451
+ return;
43452
+ }
43453
+ const toRoot = vaultRoot(to);
43454
+ if (toRoot) {
43455
+ const b = dirToward(toRoot, from);
43456
+ if (b) applyDir(toRoot, to, from, dropIn(b.dir), b.topics);
43457
+ }
43458
+ sendJson(res, 200, { ok: true });
43247
43459
  }
43248
43460
  async function handleLauncherShareable(req, res, _params, _contextRoot) {
43249
43461
  const body = await parseJsonBody(req);
@@ -43263,7 +43475,7 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
43263
43475
  return;
43264
43476
  }
43265
43477
  const root = resolve15(vault.path);
43266
- if (!existsSync63(root)) {
43478
+ if (!existsSync65(root)) {
43267
43479
  sendError(res, 400, "missing_vault", `Vault path no longer exists: ${root}`);
43268
43480
  return;
43269
43481
  }
@@ -43275,7 +43487,7 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
43275
43487
  sendError(res, 500, "shareable_failed", "Failed to update sharing.");
43276
43488
  }
43277
43489
  }
43278
- var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, SLEEPY_MODES;
43490
+ var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, SLEEPY_MODES, addOut, addIn, dropOut, dropIn;
43279
43491
  var init_launcher = __esm({
43280
43492
  "src/server/routes/launcher.ts"() {
43281
43493
  "use strict";
@@ -43319,23 +43531,27 @@ var init_launcher = __esm({
43319
43531
  };
43320
43532
  SAFE_NAME_RE = /^[^/\\]+$/;
43321
43533
  SLEEPY_MODES = /* @__PURE__ */ new Set(["idle", "sleepy", "sleeps"]);
43534
+ addOut = (d) => d === "in" || d === "both" ? "both" : "out";
43535
+ addIn = (d) => d === "out" || d === "both" ? "both" : "in";
43536
+ dropOut = (d) => d === "both" ? "in" : d === "in" ? "in" : null;
43537
+ dropIn = (d) => d === "both" ? "out" : d === "out" ? "out" : null;
43322
43538
  }
43323
43539
  });
43324
43540
 
43325
43541
  // src/server/routes/ui-settings.ts
43326
- import { dirname as dirname30, join as join60 } from "path";
43327
- import { existsSync as existsSync64, mkdirSync as mkdirSync26, readFileSync as readFileSync46, writeFileSync as writeFileSync33 } from "fs";
43542
+ import { dirname as dirname32, join as join62 } from "path";
43543
+ import { existsSync as existsSync66, mkdirSync as mkdirSync27, readFileSync as readFileSync48, writeFileSync as writeFileSync34 } from "fs";
43328
43544
  function settingsPath(contextRoot) {
43329
- return join60(contextRoot, BRAIN_SETTINGS_REL_PATH);
43545
+ return join62(contextRoot, BRAIN_SETTINGS_REL_PATH);
43330
43546
  }
43331
43547
  async function handleBrainSettingsGet(_req, res, _params, contextRoot) {
43332
43548
  const path2 = settingsPath(contextRoot);
43333
- if (!existsSync64(path2)) {
43549
+ if (!existsSync66(path2)) {
43334
43550
  sendJson(res, 200, { settings: {} });
43335
43551
  return;
43336
43552
  }
43337
43553
  try {
43338
- const raw = JSON.parse(readFileSync46(path2, "utf-8"));
43554
+ const raw = JSON.parse(readFileSync48(path2, "utf-8"));
43339
43555
  const settings = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
43340
43556
  sendJson(res, 200, { settings });
43341
43557
  } catch {
@@ -43360,8 +43576,8 @@ async function handleBrainSettingsPut(req, res, _params, contextRoot) {
43360
43576
  }
43361
43577
  try {
43362
43578
  const path2 = settingsPath(contextRoot);
43363
- mkdirSync26(dirname30(path2), { recursive: true });
43364
- writeFileSync33(path2, serialized + "\n", "utf-8");
43579
+ mkdirSync27(dirname32(path2), { recursive: true });
43580
+ writeFileSync34(path2, serialized + "\n", "utf-8");
43365
43581
  sendJson(res, 200, { ok: true });
43366
43582
  } catch (err) {
43367
43583
  console.error("[ui-settings] brain-settings write failed:", err);
@@ -43391,7 +43607,7 @@ var init_federation_config = __esm({
43391
43607
  });
43392
43608
 
43393
43609
  // src/lib/federation-recall.ts
43394
- import { basename as basename19, dirname as dirname31 } from "path";
43610
+ import { basename as basename19, dirname as dirname33 } from "path";
43395
43611
  function namespacedKey(vault, type, slug) {
43396
43612
  return `${vault}::${type}/${slug}`;
43397
43613
  }
@@ -43416,7 +43632,7 @@ function crossVaultRecall(query, opts) {
43416
43632
  }
43417
43633
  const isCurrent = target.current === true;
43418
43634
  if (!isCurrent) {
43419
- const projectRoot = dirname31(contextRoot);
43635
+ const projectRoot = dirname33(contextRoot);
43420
43636
  if (!isShareable(projectRoot)) continue;
43421
43637
  }
43422
43638
  const corpus = buildCorpus(contextRoot, opts.types ? { types: opts.types } : {}).filter((doc) => !isFederated(doc));
@@ -43489,9 +43705,9 @@ var init_federation_recall = __esm({
43489
43705
  });
43490
43706
 
43491
43707
  // src/server/routes/connections.ts
43492
- import { dirname as dirname32 } from "path";
43708
+ import { dirname as dirname34 } from "path";
43493
43709
  function currentVaultName(contextRoot) {
43494
- return currentVaultTarget(dirname32(contextRoot)).name;
43710
+ return currentVaultTarget(dirname34(contextRoot)).name;
43495
43711
  }
43496
43712
  async function handleConnectionsList(_req, res, _params, contextRoot) {
43497
43713
  sendJson(res, 200, { connections: listConnections(contextRoot) });
@@ -43566,8 +43782,8 @@ var init_connections2 = __esm({
43566
43782
  });
43567
43783
 
43568
43784
  // src/lib/federation-digest.ts
43569
- import { existsSync as existsSync65 } from "fs";
43570
- import { join as join61 } from "path";
43785
+ import { existsSync as existsSync67 } from "fs";
43786
+ import { join as join63 } from "path";
43571
43787
  function buildInterestProfile(peerRoot, topics) {
43572
43788
  if (topics && topics.length > 0) {
43573
43789
  const terms2 = Array.from(new Set(tokenize(topics.join(" "))));
@@ -43586,8 +43802,8 @@ function buildInterestProfile(peerRoot, topics) {
43586
43802
  return { terms, query: terms.join(" ") };
43587
43803
  }
43588
43804
  function activeTaskTerms(peerRoot) {
43589
- const stateDir = join61(peerRoot, "state");
43590
- if (!existsSync65(stateDir)) return [];
43805
+ const stateDir = join63(peerRoot, "state");
43806
+ if (!existsSync67(stateDir)) return [];
43591
43807
  let files;
43592
43808
  try {
43593
43809
  files = import_fast_glob17.default.sync("*.md", { cwd: stateDir, absolute: true });
@@ -43688,7 +43904,7 @@ var init_federation_digest = __esm({
43688
43904
  });
43689
43905
 
43690
43906
  // src/server/routes/federation.ts
43691
- import { dirname as dirname33 } from "path";
43907
+ import { dirname as dirname35 } from "path";
43692
43908
  async function handleFederationInboxGet(_req, res, _params, contextRoot) {
43693
43909
  const { entries, quarantined } = drainInbox(contextRoot);
43694
43910
  const pending = entries.map((e) => e.entry);
@@ -43700,7 +43916,7 @@ async function handleFederationInboxGet(_req, res, _params, contextRoot) {
43700
43916
  });
43701
43917
  }
43702
43918
  async function handleFederationSyncPost(_req, res, _params, contextRoot) {
43703
- const senderName = currentVaultTarget(dirname33(contextRoot)).name;
43919
+ const senderName = currentVaultTarget(dirname35(contextRoot)).name;
43704
43920
  const outbound = listConnections(contextRoot).filter(
43705
43921
  (c) => (c.direction === "out" || c.direction === "both") && c.status !== "stale"
43706
43922
  );
@@ -43748,14 +43964,14 @@ var init_federation = __esm({
43748
43964
  });
43749
43965
 
43750
43966
  // src/server/routes/packs.ts
43751
- import { dirname as dirname34 } from "path";
43967
+ import { dirname as dirname36 } from "path";
43752
43968
  async function handlePacksGet(_req, res, _params, contextRoot) {
43753
43969
  const loaded = loadCatalog();
43754
43970
  if (!loaded) {
43755
43971
  sendJson(res, 200, { packs: [], standalone: [] });
43756
43972
  return;
43757
43973
  }
43758
- const projectRoot = dirname34(contextRoot);
43974
+ const projectRoot = dirname36(contextRoot);
43759
43975
  const packs = loaded.catalog.packs.map((p) => ({ ...p, installed: isSkillInstalled(projectRoot, p.name) }));
43760
43976
  const standalone = loaded.catalog.standalone.map((s) => ({ ...s, installed: isSkillInstalled(projectRoot, s.name) }));
43761
43977
  sendJson(res, 200, { packs, standalone });
@@ -43769,7 +43985,7 @@ var init_packs = __esm({
43769
43985
  });
43770
43986
 
43771
43987
  // src/server/routes/packs-install.ts
43772
- import { dirname as dirname35 } from "path";
43988
+ import { dirname as dirname37 } from "path";
43773
43989
  function validatePackName(name, contextRoot) {
43774
43990
  if (name.includes("/") || name.includes("\0") || safeChildPath2("/x", name) === null) {
43775
43991
  return { ok: false, status: 400, code: "invalid_name", message: "Invalid pack name." };
@@ -43782,7 +43998,7 @@ function validatePackName(name, contextRoot) {
43782
43998
  if (!known) {
43783
43999
  return { ok: false, status: 404, code: "unknown_pack", message: `Pack "${name}" not found.` };
43784
44000
  }
43785
- const projectRoot = dirname35(contextRoot);
44001
+ const projectRoot = dirname37(contextRoot);
43786
44002
  const config = readSetupConfig(projectRoot);
43787
44003
  const platforms = normalizePlatforms(config?.platforms ?? []);
43788
44004
  const resolved = platforms.length > 0 ? platforms : [...DEFAULT_PLATFORMS];
@@ -43855,10 +44071,10 @@ var init_packs_install = __esm({
43855
44071
  });
43856
44072
 
43857
44073
  // src/server/routes/version-check.ts
43858
- import { dirname as dirname36 } from "path";
44074
+ import { dirname as dirname38 } from "path";
43859
44075
  async function handleVersionCheckGet(_req, res, _params, contextRoot) {
43860
44076
  try {
43861
- const projectRoot = dirname36(contextRoot);
44077
+ const projectRoot = dirname38(contextRoot);
43862
44078
  const cache = readVersionCache(projectRoot);
43863
44079
  const fresh = isCacheFresh(cache);
43864
44080
  const installedCli = dreamcontextVersion();
@@ -43913,7 +44129,7 @@ var init_taxonomy2 = __esm({
43913
44129
 
43914
44130
  // src/server/index.ts
43915
44131
  import { createServer } from "http";
43916
- import { join as join62, resolve as resolve16 } from "path";
44132
+ import { join as join64, resolve as resolve16 } from "path";
43917
44133
  import { fileURLToPath as fileURLToPath7 } from "url";
43918
44134
  import { exec } from "child_process";
43919
44135
  function buildRouter() {
@@ -43965,6 +44181,8 @@ function buildRouter() {
43965
44181
  router.get("/api/launcher/federation-graph", handleLauncherFederationGraph);
43966
44182
  router.post("/api/launcher/connection", handleLauncherConnectionCreate);
43967
44183
  router.post("/api/launcher/connection/remove", handleLauncherConnectionRemove);
44184
+ router.post("/api/launcher/sync", handleLauncherSyncCreate);
44185
+ router.post("/api/launcher/sync/remove", handleLauncherSyncRemove);
43968
44186
  router.post("/api/launcher/shareable", handleLauncherShareable);
43969
44187
  router.get("/api/sleepy/video", handleSleepyVideo);
43970
44188
  router.get("/api/sleepy/anim", handleSleepyAnim);
@@ -44000,7 +44218,7 @@ function resolveRequestVault(req) {
44000
44218
  if (/[/\\:.\x00]/.test(h)) return "INVALID";
44001
44219
  const v = listVaults().find((x) => x.name === h);
44002
44220
  if (!v) return "INVALID";
44003
- return join62(v.path, "_dream_context");
44221
+ return join64(v.path, "_dream_context");
44004
44222
  }
44005
44223
  function getDashboardDir() {
44006
44224
  const __dirname8 = fileURLToPath7(new URL(".", import.meta.url));
@@ -44292,8 +44510,8 @@ var init_trigger = __esm({
44292
44510
  });
44293
44511
 
44294
44512
  // src/lib/reflection.ts
44295
- import { existsSync as existsSync66, mkdirSync as mkdirSync27, writeFileSync as writeFileSync34 } from "fs";
44296
- import { join as join63, dirname as dirname37 } from "path";
44513
+ import { existsSync as existsSync68, mkdirSync as mkdirSync28, writeFileSync as writeFileSync35 } from "fs";
44514
+ import { join as join65, dirname as dirname39 } from "path";
44297
44515
  function buildExclusionSet(corpus, excludedExtra) {
44298
44516
  const excluded = new Set(excludedExtra);
44299
44517
  for (const doc of corpus) {
@@ -44469,13 +44687,13 @@ function formatReflection(result) {
44469
44687
  return capToBytes(lines, MAX_REFLECTION_BYTES);
44470
44688
  }
44471
44689
  function reflectionPath(root) {
44472
- return join63(root, "state", ".reflection.md");
44690
+ return join65(root, "state", ".reflection.md");
44473
44691
  }
44474
44692
  function writeReflection(root, md) {
44475
44693
  const outPath = reflectionPath(root);
44476
- const dir = dirname37(outPath);
44477
- if (!existsSync66(dir)) {
44478
- mkdirSync27(dir, { recursive: true });
44694
+ const dir = dirname39(outPath);
44695
+ if (!existsSync68(dir)) {
44696
+ mkdirSync28(dir, { recursive: true });
44479
44697
  }
44480
44698
  const tsMatch = md.match(/Generated: ([^\n]+)/);
44481
44699
  const generatedAt = tsMatch ? tsMatch[1].trim() : (/* @__PURE__ */ new Date()).toISOString();
@@ -44486,7 +44704,7 @@ function writeReflection(root, md) {
44486
44704
  "---",
44487
44705
  ""
44488
44706
  ].join("\n");
44489
- writeFileSync34(outPath, frontmatter + md, "utf-8");
44707
+ writeFileSync35(outPath, frontmatter + md, "utf-8");
44490
44708
  return outPath;
44491
44709
  }
44492
44710
  var MAX_REFLECTION_BYTES, DEFAULT_MIN_SESSIONS, DEFAULT_MAX_CANDIDATES, REFLECTION_NOISE;
@@ -44650,14 +44868,14 @@ var init_reflection = __esm({
44650
44868
  });
44651
44869
 
44652
44870
  // src/cli/commands/reflect.ts
44653
- import { existsSync as existsSync67, readFileSync as readFileSync49 } from "fs";
44654
- import { join as join64 } from "path";
44871
+ import { existsSync as existsSync69, readFileSync as readFileSync51 } from "fs";
44872
+ import { join as join66 } from "path";
44655
44873
  function buildBookmarkSessions(root) {
44656
- const sleepPath = join64(root, "state", ".sleep.json");
44874
+ const sleepPath = join66(root, "state", ".sleep.json");
44657
44875
  const result = /* @__PURE__ */ new Map();
44658
- if (!existsSync67(sleepPath)) return result;
44876
+ if (!existsSync69(sleepPath)) return result;
44659
44877
  try {
44660
- const parsed = JSON.parse(readFileSync49(sleepPath, "utf-8"));
44878
+ const parsed = JSON.parse(readFileSync51(sleepPath, "utf-8"));
44661
44879
  const bookmarks = parsed.bookmarks ?? [];
44662
44880
  for (const b of bookmarks) {
44663
44881
  if (b.id && b.session_id) {
@@ -44671,13 +44889,13 @@ function buildBookmarkSessions(root) {
44671
44889
  function buildExcludedExtra(root) {
44672
44890
  const excluded = /* @__PURE__ */ new Set();
44673
44891
  const coreFiles = [
44674
- join64(root, "core", "0.soul.md"),
44675
- join64(root, "core", "1.user.md")
44892
+ join66(root, "core", "0.soul.md"),
44893
+ join66(root, "core", "1.user.md")
44676
44894
  ];
44677
44895
  for (const filePath of coreFiles) {
44678
- if (!existsSync67(filePath)) continue;
44896
+ if (!existsSync69(filePath)) continue;
44679
44897
  try {
44680
- const content = readFileSync49(filePath, "utf-8");
44898
+ const content = readFileSync51(filePath, "utf-8");
44681
44899
  for (const tok of tokenize(content)) {
44682
44900
  excluded.add(tok);
44683
44901
  }
@@ -44728,8 +44946,8 @@ var init_reflect = __esm({
44728
44946
  });
44729
44947
 
44730
44948
  // src/cli/commands/council.ts
44731
- import { existsSync as existsSync68, mkdirSync as mkdirSync28, readFileSync as readFileSync50, writeFileSync as writeFileSync35 } from "fs";
44732
- import { join as join65 } from "path";
44949
+ import { existsSync as existsSync70, mkdirSync as mkdirSync29, readFileSync as readFileSync52, writeFileSync as writeFileSync36 } from "fs";
44950
+ import { join as join67 } from "path";
44733
44951
  function roundRunningStatus(n) {
44734
44952
  return `round_${n}_running`;
44735
44953
  }
@@ -44771,12 +44989,12 @@ function registerCreate(council) {
44771
44989
  }
44772
44990
  const id = generateId("council");
44773
44991
  const dir = getDebateDir(id);
44774
- mkdirSync28(dir, { recursive: true });
44992
+ mkdirSync29(dir, { recursive: true });
44775
44993
  const template = loadTemplate("council-debate.md");
44776
44994
  const content = template.replaceAll("{{ID}}", id).replaceAll("{{TOPIC}}", topic.replace(/"/g, '\\"')).replaceAll("{{ROUNDS}}", String(rounds)).replaceAll("{{INTERRUPT}}", opts.interrupt ? "true" : "false").replaceAll("{{DATE}}", today());
44777
- writeFileSync35(join65(dir, "debate.md"), content, "utf-8");
44778
- writeFileSync35(
44779
- join65(dir, "round-log.md"),
44995
+ writeFileSync36(join67(dir, "debate.md"), content, "utf-8");
44996
+ writeFileSync36(
44997
+ join67(dir, "round-log.md"),
44780
44998
  `# Round log \u2014 ${id}
44781
44999
 
44782
45000
  (Main agent appends timeline entries here.)
@@ -44818,8 +45036,8 @@ function registerAgent(council) {
44818
45036
  process.exit(1);
44819
45037
  }
44820
45038
  const personaDir = getPersonaDir(debateId, slug);
44821
- const personaFile = join65(personaDir, "context-and-persona.md");
44822
- if (existsSync68(personaFile) && !opts.force) {
45039
+ const personaFile = join67(personaDir, "context-and-persona.md");
45040
+ if (existsSync70(personaFile) && !opts.force) {
44823
45041
  error(`Persona already exists: ${slug}`, "Use --force to overwrite.");
44824
45042
  process.exit(1);
44825
45043
  }
@@ -44829,14 +45047,14 @@ function registerAgent(council) {
44829
45047
  process.exit(1);
44830
45048
  }
44831
45049
  const aspects = opts.aspects ? opts.aspects.split(",").map((a) => a.trim()).filter(Boolean) : [];
44832
- mkdirSync28(personaDir, { recursive: true });
45050
+ mkdirSync29(personaDir, { recursive: true });
44833
45051
  const template = loadTemplate("council-persona.md");
44834
45052
  const personaContent = template.replaceAll("{{SLUG}}", slug).replaceAll("{{MODEL}}", opts.model).replaceAll("{{ASPECTS}}", JSON.stringify(aspects)).replaceAll("{{PERSONA_BODY}}", body.trim());
44835
- writeFileSync35(personaFile, personaContent, "utf-8");
45053
+ writeFileSync36(personaFile, personaContent, "utf-8");
44836
45054
  const reportTemplate = loadTemplate("council-report.md");
44837
45055
  const reportContent = reportTemplate.replaceAll("{{SLUG}}", slug);
44838
- writeFileSync35(join65(personaDir, "report.md"), reportContent, "utf-8");
44839
- const debateFile = join65(getDebateDir(debateId), "debate.md");
45056
+ writeFileSync36(join67(personaDir, "report.md"), reportContent, "utf-8");
45057
+ const debateFile = join67(getDebateDir(debateId), "debate.md");
44840
45058
  const { data } = readFrontmatter(debateFile);
44841
45059
  const personas = Array.isArray(data.personas) ? data.personas.slice() : [];
44842
45060
  if (!personas.includes(slug)) personas.push(slug);
@@ -44865,7 +45083,7 @@ function registerRound(council) {
44865
45083
  error(`Round ${n} exceeds planned rounds (${data.rounds_planned}).`);
44866
45084
  process.exit(1);
44867
45085
  }
44868
- const debateFile = join65(getDebateDir(debateId), "debate.md");
45086
+ const debateFile = join67(getDebateDir(debateId), "debate.md");
44869
45087
  const personas = data.personas ?? [];
44870
45088
  if (personas.length === 0) {
44871
45089
  error("No personas registered. Run `council agent create` first.");
@@ -44874,9 +45092,9 @@ function registerRound(council) {
44874
45092
  const crossContextHeader = `## Round ${n} \u2014 Cross-context loaded`;
44875
45093
  if (n >= 2) {
44876
45094
  for (const persona of personas) {
44877
- const personaFile = join65(getPersonaDir(debateId, persona), "context-and-persona.md");
44878
- if (!existsSync68(personaFile)) continue;
44879
- const existing = readFileSync50(personaFile, "utf-8");
45095
+ const personaFile = join67(getPersonaDir(debateId, persona), "context-and-persona.md");
45096
+ if (!existsSync70(personaFile)) continue;
45097
+ const existing = readFileSync52(personaFile, "utf-8");
44880
45098
  if (existing.includes(crossContextHeader)) {
44881
45099
  continue;
44882
45100
  }
@@ -44898,7 +45116,7 @@ _(no round ${n - 1} report submitted)_`);
44898
45116
 
44899
45117
  ${peerLines.join("\n\n")}`;
44900
45118
  const updated = existing.trimEnd() + "\n\n" + newSection + "\n";
44901
- writeFileSync35(personaFile, updated, "utf-8");
45119
+ writeFileSync36(personaFile, updated, "utf-8");
44902
45120
  }
44903
45121
  }
44904
45122
  updateFrontmatterFields(debateFile, {
@@ -44906,13 +45124,13 @@ ${peerLines.join("\n\n")}`;
44906
45124
  current_round: n,
44907
45125
  updated_at: today()
44908
45126
  });
44909
- const logFile = join65(getDebateDir(debateId), "round-log.md");
44910
- const logExisting = existsSync68(logFile) ? readFileSync50(logFile, "utf-8") : "";
45127
+ const logFile = join67(getDebateDir(debateId), "round-log.md");
45128
+ const logExisting = existsSync70(logFile) ? readFileSync52(logFile, "utf-8") : "";
44911
45129
  const logEntry = `
44912
45130
  ## Round ${n} started \u2014 ${today()}
44913
45131
  - Personas: ${formatPersonaList(personas)}
44914
45132
  `;
44915
- writeFileSync35(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
45133
+ writeFileSync36(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
44916
45134
  upsertCouncilIndex({
44917
45135
  id: debateId,
44918
45136
  topic: data.topic,
@@ -44946,18 +45164,18 @@ ${peerLines.join("\n\n")}`;
44946
45164
  error(`Round ${n} incomplete. Missing reports from: ${missing.join(", ")}`);
44947
45165
  process.exit(1);
44948
45166
  }
44949
- const debateFile = join65(getDebateDir(debateId), "debate.md");
45167
+ const debateFile = join67(getDebateDir(debateId), "debate.md");
44950
45168
  updateFrontmatterFields(debateFile, {
44951
45169
  status: roundCompleteStatus(n),
44952
45170
  updated_at: today()
44953
45171
  });
44954
- const logFile = join65(getDebateDir(debateId), "round-log.md");
44955
- const logExisting = existsSync68(logFile) ? readFileSync50(logFile, "utf-8") : "";
45172
+ const logFile = join67(getDebateDir(debateId), "round-log.md");
45173
+ const logExisting = existsSync70(logFile) ? readFileSync52(logFile, "utf-8") : "";
44956
45174
  const logEntry = `
44957
45175
  ## Round ${n} complete \u2014 ${today()}
44958
45176
  - All ${personas.length} personas submitted reports.
44959
45177
  `;
44960
- writeFileSync35(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
45178
+ writeFileSync36(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
44961
45179
  upsertCouncilIndex({
44962
45180
  id: debateId,
44963
45181
  topic: data.topic,
@@ -44980,8 +45198,8 @@ function registerRoundContext(council) {
44980
45198
  try {
44981
45199
  const data = readDebateFrontmatter(debateId);
44982
45200
  ensurePersonaExists(debateId, personaSlug);
44983
- const personaFile = join65(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
44984
- const personaContent = readFileSync50(personaFile, "utf-8");
45201
+ const personaFile = join67(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
45202
+ const personaContent = readFileSync52(personaFile, "utf-8");
44985
45203
  console.log(`# Council debate: ${data.topic}`);
44986
45204
  console.log(`Debate ID: ${debateId}`);
44987
45205
  console.log(`Current round: ${data.current_round}/${data.rounds_planned}`);
@@ -44990,8 +45208,8 @@ function registerRoundContext(council) {
44990
45208
  console.log("---");
44991
45209
  console.log("");
44992
45210
  console.log(personaContent);
44993
- const debateFile = join65(getDebateDir(debateId), "debate.md");
44994
- const debateRaw = readFileSync50(debateFile, "utf-8");
45211
+ const debateFile = join67(getDebateDir(debateId), "debate.md");
45212
+ const debateRaw = readFileSync52(debateFile, "utf-8");
44995
45213
  const questionMatch = debateRaw.match(/##\s+Question\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
44996
45214
  const constraintsMatch = debateRaw.match(/##\s+Constraints & Known Facts\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
44997
45215
  if (questionMatch) {
@@ -45034,7 +45252,7 @@ function registerReport(council) {
45034
45252
  process.exit(1);
45035
45253
  }
45036
45254
  for (const w of validation.warnings) warn(w);
45037
- const reportFile = join65(getPersonaDir(debateId, personaSlug), "report.md");
45255
+ const reportFile = join67(getPersonaDir(debateId, personaSlug), "report.md");
45038
45256
  const { data: reportData, content } = readFrontmatter(reportFile);
45039
45257
  const existingRounds = parseReportRounds(content);
45040
45258
  if (existingRounds.find((r) => r.round === round)) {
@@ -45056,7 +45274,7 @@ ${otherSerialized}
45056
45274
  persona: personaSlug,
45057
45275
  rounds_completed: Math.max(reportData.rounds_completed ?? 0, round)
45058
45276
  }, "\n" + merged);
45059
- const personaFile = join65(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
45277
+ const personaFile = join67(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
45060
45278
  const { data: pData } = readFrontmatter(personaFile);
45061
45279
  updateFrontmatterFields(personaFile, {
45062
45280
  round_entries: Math.max(pData.round_entries ?? 0, round)
@@ -45099,13 +45317,13 @@ function registerResearch(council) {
45099
45317
  error("Research topic is required.");
45100
45318
  process.exit(1);
45101
45319
  }
45102
- const researchesDir = join65(getPersonaDir(debateId, personaSlug), "researches");
45103
- mkdirSync28(researchesDir, { recursive: true });
45104
- const indexPath2 = join65(researchesDir, "index.json");
45105
- if (!existsSync68(indexPath2)) writeJsonArray(indexPath2, []);
45320
+ const researchesDir = join67(getPersonaDir(debateId, personaSlug), "researches");
45321
+ mkdirSync29(researchesDir, { recursive: true });
45322
+ const indexPath2 = join67(researchesDir, "index.json");
45323
+ if (!existsSync70(indexPath2)) writeJsonArray(indexPath2, []);
45106
45324
  const slug = slugify(topic);
45107
- const file = join65(researchesDir, `${slug}.md`);
45108
- if (existsSync68(file)) {
45325
+ const file = join67(researchesDir, `${slug}.md`);
45326
+ if (existsSync70(file)) {
45109
45327
  error(`Research note already exists: ${slug}.md`);
45110
45328
  process.exit(1);
45111
45329
  }
@@ -45120,7 +45338,7 @@ _Added ${today()} by ${personaSlug}_
45120
45338
 
45121
45339
  ${body.trim()}
45122
45340
  `;
45123
- writeFileSync35(file, noteContent, "utf-8");
45341
+ writeFileSync36(file, noteContent, "utf-8");
45124
45342
  insertToJsonArray(indexPath2, {
45125
45343
  slug,
45126
45344
  topic,
@@ -45135,9 +45353,9 @@ ${body.trim()}
45135
45353
  research.command("list").argument("<debate_id>").argument("<persona_slug>").description("List this persona's prior research notes.").action((debateId, personaSlug) => {
45136
45354
  try {
45137
45355
  ensurePersonaExists(debateId, personaSlug);
45138
- const researchesDir = join65(getPersonaDir(debateId, personaSlug), "researches");
45139
- const indexPath2 = join65(researchesDir, "index.json");
45140
- if (!existsSync68(indexPath2)) {
45356
+ const researchesDir = join67(getPersonaDir(debateId, personaSlug), "researches");
45357
+ const indexPath2 = join67(researchesDir, "index.json");
45358
+ if (!existsSync70(indexPath2)) {
45141
45359
  console.log(source_default.dim("(no researches)"));
45142
45360
  return;
45143
45361
  }
@@ -45159,7 +45377,7 @@ function registerSynthesize(council) {
45159
45377
  council.command("synthesize").argument("<debate_id>").description("Mark status=synthesizing; print manifest of files synthesizer should read.").action((debateId) => {
45160
45378
  try {
45161
45379
  const data = readDebateFrontmatter(debateId);
45162
- const debateFile = join65(getDebateDir(debateId), "debate.md");
45380
+ const debateFile = join67(getDebateDir(debateId), "debate.md");
45163
45381
  updateFrontmatterFields(debateFile, {
45164
45382
  status: "synthesizing",
45165
45383
  updated_at: today()
@@ -45181,8 +45399,8 @@ function registerSynthesize(council) {
45181
45399
  const personaDir = getPersonaDir(debateId, persona);
45182
45400
  manifest.push(`_dream_context/council/${debateId}/${persona}/context-and-persona.md`);
45183
45401
  manifest.push(`_dream_context/council/${debateId}/${persona}/report.md`);
45184
- const researchesIndex = join65(personaDir, "researches", "index.json");
45185
- if (existsSync68(researchesIndex)) {
45402
+ const researchesIndex = join67(personaDir, "researches", "index.json");
45403
+ if (existsSync70(researchesIndex)) {
45186
45404
  manifest.push(`_dream_context/council/${debateId}/${persona}/researches/`);
45187
45405
  }
45188
45406
  }
@@ -45200,12 +45418,12 @@ function registerComplete(council) {
45200
45418
  council.command("complete").argument("<debate_id>").description("Mark status=complete after final-report.md is written.").action((debateId) => {
45201
45419
  try {
45202
45420
  const data = readDebateFrontmatter(debateId);
45203
- const finalReport = join65(getDebateDir(debateId), "final-report.md");
45204
- if (!existsSync68(finalReport)) {
45421
+ const finalReport = join67(getDebateDir(debateId), "final-report.md");
45422
+ if (!existsSync70(finalReport)) {
45205
45423
  error("final-report.md not found.", "Synthesizer must write it before calling `council complete`.");
45206
45424
  process.exit(1);
45207
45425
  }
45208
- const debateFile = join65(getDebateDir(debateId), "debate.md");
45426
+ const debateFile = join67(getDebateDir(debateId), "debate.md");
45209
45427
  updateFrontmatterFields(debateFile, {
45210
45428
  status: "complete",
45211
45429
  updated_at: today()
@@ -45237,8 +45455,8 @@ function registerPromote(council) {
45237
45455
  error(`Cannot promote: debate status is "${data.status}", expected "complete".`);
45238
45456
  process.exit(1);
45239
45457
  }
45240
- const finalReport = join65(getDebateDir(debateId), "final-report.md");
45241
- if (!existsSync68(finalReport)) {
45458
+ const finalReport = join67(getDebateDir(debateId), "final-report.md");
45459
+ if (!existsSync70(finalReport)) {
45242
45460
  error("final-report.md not found.");
45243
45461
  process.exit(1);
45244
45462
  }
@@ -45251,12 +45469,12 @@ function registerPromote(council) {
45251
45469
 
45252
45470
  ${sec.body.trim()}` : null;
45253
45471
  }).filter(Boolean).join("\n\n");
45254
- const knowledgeDir = join65(root, "knowledge");
45255
- mkdirSync28(knowledgeDir, { recursive: true });
45472
+ const knowledgeDir = join67(root, "knowledge");
45473
+ mkdirSync29(knowledgeDir, { recursive: true });
45256
45474
  const slug = slugify(data.topic).slice(0, 80) || debateId;
45257
45475
  const filename = `decision-${slug}.md`;
45258
- const target = join65(knowledgeDir, filename);
45259
- if (existsSync68(target) && !opts.force) {
45476
+ const target = join67(knowledgeDir, filename);
45477
+ if (existsSync70(target) && !opts.force) {
45260
45478
  error(`Knowledge file exists: ${filename}`, "Use --force to overwrite.");
45261
45479
  process.exit(1);
45262
45480
  }
@@ -45280,7 +45498,7 @@ ${kept}
45280
45498
  _Promoted from council debate \`${debateId}\` on ${today()}. See \`_dream_context/council/${debateId}/final-report.md\` for the full record._
45281
45499
  `;
45282
45500
  writeFrontmatter(target, knowledgeFrontmatter, body);
45283
- updateFrontmatterFields(join65(getDebateDir(debateId), "debate.md"), {
45501
+ updateFrontmatterFields(join67(getDebateDir(debateId), "debate.md"), {
45284
45502
  promoted_to_knowledge: `knowledge/${filename}`,
45285
45503
  updated_at: today()
45286
45504
  });
@@ -45342,10 +45560,10 @@ function registerShow(council) {
45342
45560
  console.log(` promoted: ${data.promoted_to_knowledge ?? source_default.dim("(no)")}`);
45343
45561
  console.log(` created: ${data.created_at}`);
45344
45562
  console.log(` updated: ${data.updated_at}`);
45345
- const logFile = join65(getDebateDir(debateId), "round-log.md");
45346
- if (existsSync68(logFile)) {
45563
+ const logFile = join67(getDebateDir(debateId), "round-log.md");
45564
+ if (existsSync70(logFile)) {
45347
45565
  console.log("\n" + source_default.dim("\u2500\u2500\u2500 Round log \u2500\u2500\u2500"));
45348
- console.log(readFileSync50(logFile, "utf-8"));
45566
+ console.log(readFileSync52(logFile, "utf-8"));
45349
45567
  }
45350
45568
  } catch (err) {
45351
45569
  error(err.message);
@@ -45537,12 +45755,12 @@ var init_env_loader = __esm({
45537
45755
  });
45538
45756
 
45539
45757
  // src/lib/marketing/config.ts
45540
- import { existsSync as existsSync69, readFileSync as readFileSync51, writeFileSync as writeFileSync36, mkdirSync as mkdirSync29 } from "fs";
45541
- import { dirname as dirname38 } from "path";
45758
+ import { existsSync as existsSync71, readFileSync as readFileSync53, writeFileSync as writeFileSync37, mkdirSync as mkdirSync30 } from "fs";
45759
+ import { dirname as dirname40 } from "path";
45542
45760
  function readEnvFile() {
45543
45761
  const path2 = MARKETING_PATHS.envFile();
45544
- if (!existsSync69(path2)) return {};
45545
- const raw = readFileSync51(path2, "utf8");
45762
+ if (!existsSync71(path2)) return {};
45763
+ const raw = readFileSync53(path2, "utf8");
45546
45764
  const parsed = parseEnv(raw);
45547
45765
  if (parsed.errors.length > 0) {
45548
45766
  for (const e of parsed.errors) {
@@ -45586,9 +45804,9 @@ function requireEnv(keys = REQUIRED_KEYS) {
45586
45804
  }
45587
45805
  function loadConfig() {
45588
45806
  const path2 = MARKETING_PATHS.configFile();
45589
- if (!existsSync69(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
45807
+ if (!existsSync71(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
45590
45808
  try {
45591
- const raw = readFileSync51(path2, "utf8");
45809
+ const raw = readFileSync53(path2, "utf8");
45592
45810
  const parsed = JSON.parse(raw);
45593
45811
  return {
45594
45812
  default_profile: parsed.default_profile ?? null,
@@ -45603,21 +45821,21 @@ function loadConfig() {
45603
45821
  }
45604
45822
  function writeConfig(cfg) {
45605
45823
  const path2 = MARKETING_PATHS.configFile();
45606
- mkdirSync29(dirname38(path2), { recursive: true });
45607
- writeFileSync36(path2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
45824
+ mkdirSync30(dirname40(path2), { recursive: true });
45825
+ writeFileSync37(path2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
45608
45826
  }
45609
45827
  function ensureConfigFile() {
45610
45828
  const path2 = MARKETING_PATHS.configFile();
45611
- if (existsSync69(path2)) return loadConfig();
45829
+ if (existsSync71(path2)) return loadConfig();
45612
45830
  const cfg = { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
45613
45831
  writeConfig(cfg);
45614
45832
  return cfg;
45615
45833
  }
45616
45834
  function ensureEnvFile() {
45617
45835
  const path2 = MARKETING_PATHS.envFile();
45618
- if (existsSync69(path2)) return;
45619
- mkdirSync29(marketingRoot(), { recursive: true });
45620
- writeFileSync36(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
45836
+ if (existsSync71(path2)) return;
45837
+ mkdirSync30(marketingRoot(), { recursive: true });
45838
+ writeFileSync37(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
45621
45839
  }
45622
45840
  var DEFAULT_API_VERSION, EMPTY_CONFIG, REQUIRED_KEYS, OPTIONAL_KEYS, ENV_TEMPLATE;
45623
45841
  var init_config2 = __esm({
@@ -45658,9 +45876,9 @@ REINFLUENCE_BIN= # optional override; default uses .venv
45658
45876
 
45659
45877
  // src/lib/marketing/bootstrap.ts
45660
45878
  import { spawn as spawn5, spawnSync as spawnSync2 } from "child_process";
45661
- import { existsSync as existsSync70, mkdirSync as mkdirSync30, cpSync as cpSync3 } from "fs";
45879
+ import { existsSync as existsSync72, mkdirSync as mkdirSync31, cpSync as cpSync3 } from "fs";
45662
45880
  import { fileURLToPath as fileURLToPath8 } from "url";
45663
- import { dirname as dirname39, resolve as resolve17, join as join66 } from "path";
45881
+ import { dirname as dirname41, resolve as resolve17, join as join68 } from "path";
45664
45882
  function findBundledReinfluence() {
45665
45883
  const candidates = [
45666
45884
  // Installed npm package: dist/<chunk>.js -> ../tools/reinfluence
@@ -45670,7 +45888,7 @@ function findBundledReinfluence() {
45670
45888
  resolve17(__dirname7, "..", "..", "..", "tools", "reinfluence")
45671
45889
  ];
45672
45890
  for (const c of candidates) {
45673
- if (existsSync70(join66(c, "__main__.py"))) return c;
45891
+ if (existsSync72(join68(c, "__main__.py"))) return c;
45674
45892
  }
45675
45893
  throw new Error(
45676
45894
  "Bundled reinfluence not found. Reinstall dreamcontext or set REINFLUENCE_BIN."
@@ -45701,18 +45919,18 @@ async function bootstrapMarketing(opts = {}) {
45701
45919
  if (verbose) process.stderr.write(`[mk init] ${msg}
45702
45920
  `);
45703
45921
  };
45704
- mkdirSync30(marketingRoot(), { recursive: true });
45922
+ mkdirSync31(marketingRoot(), { recursive: true });
45705
45923
  const bundled = findBundledReinfluence();
45706
45924
  const target = MARKETING_PATHS.reinfluenceDir();
45707
45925
  log(`copying tools \u2192 ${target}`);
45708
- mkdirSync30(MARKETING_PATHS.toolsDir(), { recursive: true });
45926
+ mkdirSync31(MARKETING_PATHS.toolsDir(), { recursive: true });
45709
45927
  cpSync3(bundled, target, { recursive: true });
45710
45928
  const py = findPython3();
45711
45929
  if (!py) {
45712
45930
  throw new Error("python3 not found on PATH. Install Python 3.10+ and retry.");
45713
45931
  }
45714
45932
  const venv = MARKETING_PATHS.venvDir();
45715
- if (!existsSync70(MARKETING_PATHS.venvPython())) {
45933
+ if (!existsSync72(MARKETING_PATHS.venvPython())) {
45716
45934
  log(`creating venv \u2192 ${venv}`);
45717
45935
  const r2 = runBlocking(py, ["-m", "venv", venv]);
45718
45936
  if (r2.code !== 0) {
@@ -45725,7 +45943,7 @@ async function bootstrapMarketing(opts = {}) {
45725
45943
  log("upgrading pip");
45726
45944
  let r = runBlocking(venvPy, ["-m", "pip", "install", "--upgrade", "pip", "--quiet"]);
45727
45945
  if (r.code !== 0) log(`pip upgrade warning: ${r.stderr.trim().slice(0, 200)}`);
45728
- const reqs = join66(target, "requirements.txt");
45946
+ const reqs = join68(target, "requirements.txt");
45729
45947
  log("installing python deps (whisper / yt-dlp / instaloader) \u2014 first run can take several minutes");
45730
45948
  r = runBlocking(venvPy, ["-m", "pip", "install", "-r", reqs, "--quiet"]);
45731
45949
  if (r.code !== 0) {
@@ -45735,7 +45953,7 @@ ${r.stderr.trim() || r.stdout.trim()}`);
45735
45953
  let whisperPrimed = false;
45736
45954
  if (whisperModel) {
45737
45955
  log(`pre-pulling whisper model "${whisperModel}" into ${MARKETING_PATHS.whisperCacheDir()}`);
45738
- mkdirSync30(MARKETING_PATHS.whisperCacheDir(), { recursive: true });
45956
+ mkdirSync31(MARKETING_PATHS.whisperCacheDir(), { recursive: true });
45739
45957
  whisperPrimed = await primeWhisper(whisperModel);
45740
45958
  if (!whisperPrimed) log("whisper pre-pull failed (will retry on first ingest)");
45741
45959
  }
@@ -45775,15 +45993,15 @@ function subprocessEnv() {
45775
45993
  return {
45776
45994
  ...process.env,
45777
45995
  XDG_CACHE_HOME: cache,
45778
- HF_HOME: join66(cache, "hf"),
45779
- TRANSFORMERS_CACHE: join66(cache, "hf", "transformers"),
45996
+ HF_HOME: join68(cache, "hf"),
45997
+ TRANSFORMERS_CACHE: join68(cache, "hf", "transformers"),
45780
45998
  WHISPER_CACHE_DIR: MARKETING_PATHS.whisperCacheDir(),
45781
45999
  PYTHONUNBUFFERED: "1",
45782
46000
  PYTHONPATH: MARKETING_PATHS.toolsDir()
45783
46001
  };
45784
46002
  }
45785
46003
  function isBootstrapped() {
45786
- return existsSync70(MARKETING_PATHS.venvPython()) && existsSync70(join66(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
46004
+ return existsSync72(MARKETING_PATHS.venvPython()) && existsSync72(join68(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
45787
46005
  }
45788
46006
  var __filename, __dirname7;
45789
46007
  var init_bootstrap = __esm({
@@ -45791,12 +46009,12 @@ var init_bootstrap = __esm({
45791
46009
  "use strict";
45792
46010
  init_paths2();
45793
46011
  __filename = fileURLToPath8(import.meta.url);
45794
- __dirname7 = dirname39(__filename);
46012
+ __dirname7 = dirname41(__filename);
45795
46013
  }
45796
46014
  });
45797
46015
 
45798
46016
  // src/cli/commands/marketing/init.ts
45799
- import { mkdirSync as mkdirSync31 } from "fs";
46017
+ import { mkdirSync as mkdirSync32 } from "fs";
45800
46018
  function registerMarketingInit(parent) {
45801
46019
  parent.command("init").description("Bootstrap _dream_context/marketing/ (folders, .env, venv, reinfluence tools, whisper cache)").option("--skip-bootstrap", "Only create folders + .env template; skip venv + pip install", false).option("--whisper-model <model>", "Whisper model to pre-pull (default: medium)", "medium").option("--no-whisper", "Skip Whisper model pre-pull").action(async (opts) => {
45802
46020
  try {
@@ -45807,7 +46025,7 @@ function registerMarketingInit(parent) {
45807
46025
  }
45808
46026
  console.log(header("Marketing init"));
45809
46027
  const root = marketingRoot();
45810
- mkdirSync31(root, { recursive: true });
46028
+ mkdirSync32(root, { recursive: true });
45811
46029
  for (const dir of [
45812
46030
  MARKETING_PATHS.cohortsDir(),
45813
46031
  MARKETING_PATHS.campaignsDir(),
@@ -45820,7 +46038,7 @@ function registerMarketingInit(parent) {
45820
46038
  MARKETING_PATHS.byIdemDir(),
45821
46039
  MARKETING_PATHS.cacheDir()
45822
46040
  ]) {
45823
- mkdirSync31(dir, { recursive: true });
46041
+ mkdirSync32(dir, { recursive: true });
45824
46042
  }
45825
46043
  info(`folders ready under ${source_default.dim(root)}`);
45826
46044
  ensureEnvFile();
@@ -45860,8 +46078,8 @@ var init_init2 = __esm({
45860
46078
  });
45861
46079
 
45862
46080
  // src/lib/marketing/vision.ts
45863
- import { existsSync as existsSync71, readFileSync as readFileSync52, writeFileSync as writeFileSync37 } from "fs";
45864
- import { dirname as dirname40, join as join67 } from "path";
46081
+ import { existsSync as existsSync73, readFileSync as readFileSync54, writeFileSync as writeFileSync38 } from "fs";
46082
+ import { dirname as dirname42, join as join69 } from "path";
45865
46083
  function pickVisionProvider(env2 = process.env) {
45866
46084
  const oai = env2.OPENAI_VISION_API_KEY;
45867
46085
  if (oai && oai.trim().length > 0) return { provider: "openai", apiKey: oai.trim() };
@@ -45900,11 +46118,11 @@ function parseLabelsFromText(text, allowlist = LABEL_ALLOWLIST) {
45900
46118
  return out;
45901
46119
  }
45902
46120
  async function readImageAsBase64(framePath) {
45903
- const buf = readFileSync52(framePath);
46121
+ const buf = readFileSync54(framePath);
45904
46122
  return buf.toString("base64");
45905
46123
  }
45906
46124
  async function labelHookFrame(framePath, opts) {
45907
- if (!existsSync71(framePath)) return [];
46125
+ if (!existsSync73(framePath)) return [];
45908
46126
  const fetcher = opts.fetcher ?? defaultFetcher;
45909
46127
  const prompt = opts.promptOverride ?? PROMPT;
45910
46128
  const b64 = await readImageAsBase64(framePath);
@@ -45954,7 +46172,7 @@ async function labelHookFrame(framePath, opts) {
45954
46172
  return parseLabelsFromText(text);
45955
46173
  }
45956
46174
  async function runVisionPassOnPost(postJsonPath, opts = {}) {
45957
- const raw = readFileSync52(postJsonPath, "utf-8");
46175
+ const raw = readFileSync54(postJsonPath, "utf-8");
45958
46176
  const post = JSON.parse(raw);
45959
46177
  const shortcode = post.shortcode ?? "?";
45960
46178
  const provider = opts.provider && opts.apiKey ? { provider: opts.provider, apiKey: opts.apiKey } : pickVisionProvider();
@@ -45993,15 +46211,15 @@ async function runVisionPassOnPost(postJsonPath, opts = {}) {
45993
46211
  post.pattern_tags = [...aggregated].sort();
45994
46212
  post.vision_summary = post.pattern_tags.length > 0 ? `Vision-tagged ${framesLabeled}/${hookFrames.length} hook frames; patterns: ${post.pattern_tags.join(", ")}.` : `Vision pass found no allowlisted patterns across ${hookFrames.length} hook frames.`;
45995
46213
  const tmp = postJsonPath + ".tmp";
45996
- writeFileSync37(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
46214
+ writeFileSync38(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
45997
46215
  const fs = await import("fs");
45998
46216
  fs.renameSync(tmp, postJsonPath);
45999
- const mdPath = join67(dirname40(postJsonPath), `${shortcode}.md`);
46000
- if (existsSync71(mdPath)) {
46217
+ const mdPath = join69(dirname42(postJsonPath), `${shortcode}.md`);
46218
+ if (existsSync73(mdPath)) {
46001
46219
  try {
46002
- const md = readFileSync52(mdPath, "utf-8");
46220
+ const md = readFileSync54(mdPath, "utf-8");
46003
46221
  const refreshed = updatePatternTagsInBridge(md, post.pattern_tags);
46004
- writeFileSync37(mdPath, refreshed, "utf-8");
46222
+ writeFileSync38(mdPath, refreshed, "utf-8");
46005
46223
  } catch {
46006
46224
  }
46007
46225
  }
@@ -46076,8 +46294,8 @@ Example output: ["talking-head","prop-driven"]`;
46076
46294
  // src/lib/marketing/competitors.ts
46077
46295
  import { spawn as spawn6 } from "child_process";
46078
46296
  import { spawnSync as spawnSync3 } from "child_process";
46079
- import { existsSync as existsSync72, mkdirSync as mkdirSync32, statfsSync } from "fs";
46080
- import { dirname as dirname41, join as join68, basename as basename20, extname as extname4 } from "path";
46297
+ import { existsSync as existsSync74, mkdirSync as mkdirSync33, statfsSync } from "fs";
46298
+ import { dirname as dirname43, join as join70, basename as basename20, extname as extname4 } from "path";
46081
46299
  function which(cmd) {
46082
46300
  const r = spawnSync3(process.platform === "win32" ? "where" : "which", [cmd], { encoding: "utf8" });
46083
46301
  if (r.status === 0) return (r.stdout || "").trim().split("\n")[0] || null;
@@ -46154,8 +46372,8 @@ ${h.installHints.join("\n")}`);
46154
46372
  skip_transcripts: !!opts.skipTranscripts,
46155
46373
  skip_frames: !!opts.skipFrames
46156
46374
  });
46157
- const outDir = join68(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run2.id);
46158
- mkdirSync32(outDir, { recursive: true });
46375
+ const outDir = join70(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run2.id);
46376
+ mkdirSync33(outDir, { recursive: true });
46159
46377
  const args = [
46160
46378
  "-m",
46161
46379
  "reinfluence",
@@ -46255,15 +46473,15 @@ stderr: ${stderrBuf.slice(0, 1e3)}`));
46255
46473
  return { runId: run2.id, postsIngested, warnings, errors };
46256
46474
  }
46257
46475
  function persistPost(evt) {
46258
- const handleDir = join68(MARKETING_PATHS.competitorsDir(), evt.handle);
46259
- const postsDir = join68(handleDir, "posts");
46260
- const mediaDir = join68(handleDir, "_media", evt.shortcode);
46261
- mkdirSync32(postsDir, { recursive: true });
46262
- mkdirSync32(mediaDir, { recursive: true });
46263
- const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join68(mediaDir, basename20(evt.video_path))) : null;
46476
+ const handleDir = join70(MARKETING_PATHS.competitorsDir(), evt.handle);
46477
+ const postsDir = join70(handleDir, "posts");
46478
+ const mediaDir = join70(handleDir, "_media", evt.shortcode);
46479
+ mkdirSync33(postsDir, { recursive: true });
46480
+ mkdirSync33(mediaDir, { recursive: true });
46481
+ const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join70(mediaDir, basename20(evt.video_path))) : null;
46264
46482
  const finalFramePaths = [];
46265
46483
  for (const fr of evt.frames) {
46266
- const finalP = moveAsset(fr.path, join68(mediaDir, "frames", basename20(fr.path)));
46484
+ const finalP = moveAsset(fr.path, join70(mediaDir, "frames", basename20(fr.path)));
46267
46485
  finalFramePaths.push(finalP);
46268
46486
  }
46269
46487
  const id = `${evt.handle}__${evt.shortcode}`;
@@ -46283,14 +46501,14 @@ function persistPost(evt) {
46283
46501
  ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
46284
46502
  asset_paths: { video: finalVideoPath, frames: finalFramePaths }
46285
46503
  };
46286
- const jsonPath = join68(postsDir, `${evt.shortcode}.json`);
46287
- const bridgePath = join68(postsDir, `${evt.shortcode}.md`);
46504
+ const jsonPath = join70(postsDir, `${evt.shortcode}.json`);
46505
+ const bridgePath = join70(postsDir, `${evt.shortcode}.md`);
46288
46506
  writeJsonWithBridge(jsonPath, bridgePath, json, renderPostBridge(json));
46289
- const metaPath = join68(handleDir, "meta.json");
46290
- if (!existsSync72(metaPath)) {
46507
+ const metaPath = join70(handleDir, "meta.json");
46508
+ if (!existsSync74(metaPath)) {
46291
46509
  writeJsonWithBridge(
46292
46510
  metaPath,
46293
- join68(handleDir, "meta.md"),
46511
+ join70(handleDir, "meta.md"),
46294
46512
  { handle: evt.handle, first_seen_at: (/* @__PURE__ */ new Date()).toISOString() },
46295
46513
  `---
46296
46514
  id: competitor_${evt.handle}
@@ -46307,8 +46525,8 @@ First seen: ${(/* @__PURE__ */ new Date()).toISOString()}
46307
46525
  return jsonPath;
46308
46526
  }
46309
46527
  function moveAsset(src, dest) {
46310
- if (!existsSync72(src)) return dest;
46311
- mkdirSync32(dirname41(dest), { recursive: true });
46528
+ if (!existsSync74(src)) return dest;
46529
+ mkdirSync33(dirname43(dest), { recursive: true });
46312
46530
  const fs = __require("fs");
46313
46531
  try {
46314
46532
  fs.renameSync(src, dest);
@@ -46369,8 +46587,8 @@ var init_competitors = __esm({
46369
46587
  });
46370
46588
 
46371
46589
  // src/cli/commands/marketing/competitor.ts
46372
- import { existsSync as existsSync73, readdirSync as readdirSync16, statSync as statSync11 } from "fs";
46373
- import { join as join69 } from "path";
46590
+ import { existsSync as existsSync75, readdirSync as readdirSync17, statSync as statSync11 } from "fs";
46591
+ import { join as join71 } from "path";
46374
46592
  function registerMarketingCompetitor(parent) {
46375
46593
  const cmd = parent.command("competitor").description("Ingest competitor IG / YouTube content (Reinfluence pipeline).");
46376
46594
  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) => {
@@ -46420,13 +46638,13 @@ function registerMarketingCompetitor(parent) {
46420
46638
  });
46421
46639
  cmd.command("list").description("List ingested competitor handles.").action(() => {
46422
46640
  const dir = MARKETING_PATHS.competitorsDir();
46423
- if (!existsSync73(dir)) {
46641
+ if (!existsSync75(dir)) {
46424
46642
  info("No competitors ingested yet.");
46425
46643
  return;
46426
46644
  }
46427
- const handles = readdirSync16(dir).filter((name) => {
46645
+ const handles = readdirSync17(dir).filter((name) => {
46428
46646
  if (name.startsWith("_") || name.startsWith(".")) return false;
46429
- const full = join69(dir, name);
46647
+ const full = join71(dir, name);
46430
46648
  try {
46431
46649
  return statSync11(full).isDirectory();
46432
46650
  } catch {
@@ -46439,8 +46657,8 @@ function registerMarketingCompetitor(parent) {
46439
46657
  }
46440
46658
  console.log(header("Competitors"));
46441
46659
  for (const handle of handles) {
46442
- const postsDir = join69(dir, handle, "posts");
46443
- const postCount = existsSync73(postsDir) ? readdirSync16(postsDir).filter((f) => f.endsWith(".json")).length : 0;
46660
+ const postsDir = join71(dir, handle, "posts");
46661
+ const postCount = existsSync75(postsDir) ? readdirSync17(postsDir).filter((f) => f.endsWith(".json")).length : 0;
46444
46662
  console.log(` ${source_default.cyan("@" + handle)} ${source_default.dim(`${postCount} post(s)`)}`);
46445
46663
  }
46446
46664
  });
@@ -46453,11 +46671,11 @@ function registerMarketingCompetitor(parent) {
46453
46671
  }
46454
46672
  info(`Provider: ${provider.provider}`);
46455
46673
  const competitorsDir = MARKETING_PATHS.competitorsDir();
46456
- const handles = opts.handle ? [opts.handle] : existsSync73(competitorsDir) ? readdirSync16(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(join69(competitorsDir, h)).isDirectory()) : [];
46674
+ const handles = opts.handle ? [opts.handle] : existsSync75(competitorsDir) ? readdirSync17(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(join71(competitorsDir, h)).isDirectory()) : [];
46457
46675
  const matches = [];
46458
46676
  for (const h of handles) {
46459
- const candidate = join69(competitorsDir, h, "posts", `${shortcode}.json`);
46460
- if (existsSync73(candidate)) matches.push(candidate);
46677
+ const candidate = join71(competitorsDir, h, "posts", `${shortcode}.json`);
46678
+ if (existsSync75(candidate)) matches.push(candidate);
46461
46679
  }
46462
46680
  if (matches.length === 0) {
46463
46681
  error(`No post JSON found for shortcode "${shortcode}".`);
@@ -46492,18 +46710,18 @@ function registerMarketingCompetitor(parent) {
46492
46710
  process.exit(1);
46493
46711
  }
46494
46712
  const competitorsDir = MARKETING_PATHS.competitorsDir();
46495
- if (!existsSync73(competitorsDir)) {
46713
+ if (!existsSync75(competitorsDir)) {
46496
46714
  warn("No competitors directory yet \u2014 nothing to relabel.");
46497
46715
  return;
46498
46716
  }
46499
- const handles = readdirSync16(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(join69(competitorsDir, h)).isDirectory());
46717
+ const handles = readdirSync17(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(join71(competitorsDir, h)).isDirectory());
46500
46718
  let labeled = 0;
46501
46719
  let skipped = 0;
46502
46720
  for (const h of handles) {
46503
- const postsDir = join69(competitorsDir, h, "posts");
46504
- if (!existsSync73(postsDir)) continue;
46505
- for (const f of readdirSync16(postsDir).filter((n) => n.endsWith(".json"))) {
46506
- const path2 = join69(postsDir, f);
46721
+ const postsDir = join71(competitorsDir, h, "posts");
46722
+ if (!existsSync75(postsDir)) continue;
46723
+ for (const f of readdirSync17(postsDir).filter((n) => n.endsWith(".json"))) {
46724
+ const path2 = join71(postsDir, f);
46507
46725
  if (opts.dryRun) {
46508
46726
  info(`would relabel: ${path2}`);
46509
46727
  continue;
@@ -46550,8 +46768,8 @@ var init_competitor = __esm({
46550
46768
  });
46551
46769
 
46552
46770
  // src/lib/marketing/meta-fetch.ts
46553
- import { existsSync as existsSync74, mkdirSync as mkdirSync33, readFileSync as readFileSync53, writeFileSync as writeFileSync38, statSync as statSync12, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
46554
- import { dirname as dirname42, basename as basename21 } from "path";
46771
+ import { existsSync as existsSync76, mkdirSync as mkdirSync34, readFileSync as readFileSync55, writeFileSync as writeFileSync39, statSync as statSync12, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
46772
+ import { dirname as dirname44, basename as basename21 } from "path";
46555
46773
  import { randomUUID as randomUUID3 } from "crypto";
46556
46774
  function getQueue(accountId) {
46557
46775
  let q = writeQueues.get(accountId);
@@ -46601,17 +46819,17 @@ function idemCachePath(key) {
46601
46819
  }
46602
46820
  function readIdem(key) {
46603
46821
  const p = idemCachePath(key);
46604
- if (!existsSync74(p)) return null;
46822
+ if (!existsSync76(p)) return null;
46605
46823
  try {
46606
- return JSON.parse(readFileSync53(p, "utf8"));
46824
+ return JSON.parse(readFileSync55(p, "utf8"));
46607
46825
  } catch {
46608
46826
  return null;
46609
46827
  }
46610
46828
  }
46611
46829
  function writeIdem(rec) {
46612
46830
  const p = idemCachePath(rec.key);
46613
- mkdirSync33(dirname42(p), { recursive: true });
46614
- writeFileSync38(p, JSON.stringify(rec, null, 2) + "\n", "utf8");
46831
+ mkdirSync34(dirname44(p), { recursive: true });
46832
+ writeFileSync39(p, JSON.stringify(rec, null, 2) + "\n", "utf8");
46615
46833
  }
46616
46834
  function backoffMs(attempt, hintSec) {
46617
46835
  if (hintSec != null && Number.isFinite(hintSec) && hintSec > 0) {
@@ -46879,7 +47097,7 @@ async function singleShotVideoUpload(ctx, filepath, fields) {
46879
47097
  if (fields.name) form.set("name", fields.name);
46880
47098
  if (fields.title) form.set("title", fields.title);
46881
47099
  if (fields.description) form.set("description", fields.description);
46882
- const buffer = readFileSync53(filepath);
47100
+ const buffer = readFileSync55(filepath);
46883
47101
  const blob = new Blob([new Uint8Array(buffer)], { type: "video/mp4" });
46884
47102
  form.set("source", blob, basename21(filepath));
46885
47103
  const resp = await fetch(url, {
@@ -46928,7 +47146,7 @@ async function uploadImageFile(ctx, filepath) {
46928
47146
  return withWriteSlot(ctx.adAccountId, async () => {
46929
47147
  const url = buildUrl(ctx, { method: "POST", path: `${ctx.adAccountId}/adimages` });
46930
47148
  const form = new FormData();
46931
- const buffer = readFileSync53(filepath);
47149
+ const buffer = readFileSync55(filepath);
46932
47150
  const blob = new Blob([new Uint8Array(buffer)], { type: "image/png" });
46933
47151
  form.set("filename", blob, basename21(filepath));
46934
47152
  const resp = await fetch(url, {
@@ -47347,7 +47565,7 @@ var init_account = __esm({
47347
47565
  });
47348
47566
 
47349
47567
  // src/lib/marketing/hypothesis.ts
47350
- import { existsSync as existsSync75, readFileSync as readFileSync54 } from "fs";
47568
+ import { existsSync as existsSync77, readFileSync as readFileSync56 } from "fs";
47351
47569
  function validateHypothesis(raw, options2 = {}) {
47352
47570
  const errors = [];
47353
47571
  const fieldErrors = {};
@@ -47414,12 +47632,12 @@ function validateHypothesis(raw, options2 = {}) {
47414
47632
  };
47415
47633
  }
47416
47634
  function loadHypothesisFile(path2, options2 = {}) {
47417
- if (!existsSync75(path2)) {
47635
+ if (!existsSync77(path2)) {
47418
47636
  return { ok: false, errors: [`Hypothesis file not found: ${path2}`] };
47419
47637
  }
47420
47638
  let parsed;
47421
47639
  try {
47422
- parsed = JSON.parse(readFileSync54(path2, "utf8"));
47640
+ parsed = JSON.parse(readFileSync56(path2, "utf8"));
47423
47641
  } catch (e) {
47424
47642
  return { ok: false, errors: [`Failed to parse JSON at ${path2}: ${e.message}`] };
47425
47643
  }
@@ -47607,8 +47825,8 @@ var init_cohort2 = __esm({
47607
47825
  });
47608
47826
 
47609
47827
  // src/lib/marketing/insights-cache.ts
47610
- import { existsSync as existsSync76, readFileSync as readFileSync55, mkdirSync as mkdirSync34, writeFileSync as writeFileSync39, readdirSync as readdirSync17, statSync as statSync13 } from "fs";
47611
- import { join as join70 } from "path";
47828
+ import { existsSync as existsSync78, readFileSync as readFileSync57, mkdirSync as mkdirSync35, writeFileSync as writeFileSync40, readdirSync as readdirSync18, statSync as statSync13 } from "fs";
47829
+ import { join as join72 } from "path";
47612
47830
  import { randomBytes as randomBytes3 } from "crypto";
47613
47831
  function snapshotFilename(entityId, pulledAt) {
47614
47832
  const yyyy = pulledAt.getUTCFullYear();
@@ -47619,30 +47837,30 @@ function snapshotFilename(entityId, pulledAt) {
47619
47837
  return `${safe}__${yyyy}-${mm}-${dd}-${hh}.json`;
47620
47838
  }
47621
47839
  function indexPath() {
47622
- return join70(MARKETING_PATHS.insightsDir(), "_index.json");
47840
+ return join72(MARKETING_PATHS.insightsDir(), "_index.json");
47623
47841
  }
47624
47842
  function readIndex() {
47625
47843
  const p = indexPath();
47626
- if (!existsSync76(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
47844
+ if (!existsSync78(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
47627
47845
  try {
47628
- return JSON.parse(readFileSync55(p, "utf8"));
47846
+ return JSON.parse(readFileSync57(p, "utf8"));
47629
47847
  } catch {
47630
47848
  return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
47631
47849
  }
47632
47850
  }
47633
47851
  function writeIndex(idx) {
47634
47852
  const p = indexPath();
47635
- mkdirSync34(MARKETING_PATHS.insightsDir(), { recursive: true });
47853
+ mkdirSync35(MARKETING_PATHS.insightsDir(), { recursive: true });
47636
47854
  const tmp = `${p}.tmp.${process.pid}.${randomBytes3(4).toString("hex")}`;
47637
- writeFileSync39(tmp, JSON.stringify(idx, null, 2) + "\n", "utf8");
47855
+ writeFileSync40(tmp, JSON.stringify(idx, null, 2) + "\n", "utf8");
47638
47856
  __require("fs").renameSync(tmp, p);
47639
47857
  }
47640
47858
  function saveInsightsSnapshot(snap) {
47641
- mkdirSync34(MARKETING_PATHS.insightsDir(), { recursive: true });
47859
+ mkdirSync35(MARKETING_PATHS.insightsDir(), { recursive: true });
47642
47860
  const filename = snapshotFilename(snap.entity_id, new Date(snap.pulled_at));
47643
- const fullPath = join70(MARKETING_PATHS.insightsDir(), filename);
47861
+ const fullPath = join72(MARKETING_PATHS.insightsDir(), filename);
47644
47862
  const tmp = `${fullPath}.tmp.${process.pid}.${randomBytes3(4).toString("hex")}`;
47645
- writeFileSync39(tmp, JSON.stringify(snap, null, 2) + "\n", "utf8");
47863
+ writeFileSync40(tmp, JSON.stringify(snap, null, 2) + "\n", "utf8");
47646
47864
  __require("fs").renameSync(tmp, fullPath);
47647
47865
  const idx = readIndex();
47648
47866
  idx.latest[snap.entity_id] = filename;
@@ -47654,10 +47872,10 @@ function getCachedInsights(entityId) {
47654
47872
  const idx = readIndex();
47655
47873
  const filename = idx.latest[entityId];
47656
47874
  if (!filename) return null;
47657
- const fullPath = join70(MARKETING_PATHS.insightsDir(), filename);
47658
- if (!existsSync76(fullPath)) return null;
47875
+ const fullPath = join72(MARKETING_PATHS.insightsDir(), filename);
47876
+ if (!existsSync78(fullPath)) return null;
47659
47877
  try {
47660
- const snap = JSON.parse(readFileSync55(fullPath, "utf8"));
47878
+ const snap = JSON.parse(readFileSync57(fullPath, "utf8"));
47661
47879
  const ageMs = Date.now() - new Date(snap.pulled_at).getTime();
47662
47880
  if (ageMs > INSIGHTS_TTL_MS) return null;
47663
47881
  return snap;
@@ -47669,20 +47887,20 @@ function getLatestSnapshot(entityId) {
47669
47887
  const idx = readIndex();
47670
47888
  const filename = idx.latest[entityId];
47671
47889
  if (!filename) return null;
47672
- const fullPath = join70(MARKETING_PATHS.insightsDir(), filename);
47673
- if (!existsSync76(fullPath)) return null;
47890
+ const fullPath = join72(MARKETING_PATHS.insightsDir(), filename);
47891
+ if (!existsSync78(fullPath)) return null;
47674
47892
  try {
47675
- return JSON.parse(readFileSync55(fullPath, "utf8"));
47893
+ return JSON.parse(readFileSync57(fullPath, "utf8"));
47676
47894
  } catch {
47677
47895
  return null;
47678
47896
  }
47679
47897
  }
47680
47898
  function getPriorSnapshot(entityId, beforeMs) {
47681
47899
  const dir = MARKETING_PATHS.insightsDir();
47682
- if (!existsSync76(dir)) return null;
47900
+ if (!existsSync78(dir)) return null;
47683
47901
  const safe = entityId.replace(/[^A-Za-z0-9_-]/g, "_");
47684
- const candidates = readdirSync17(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
47685
- const p = join70(dir, f);
47902
+ const candidates = readdirSync18(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
47903
+ const p = join72(dir, f);
47686
47904
  const stat = statSync13(p);
47687
47905
  return { f, p, mtimeMs: stat.mtimeMs };
47688
47906
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
@@ -47690,7 +47908,7 @@ function getPriorSnapshot(entityId, beforeMs) {
47690
47908
  for (const c of candidates) {
47691
47909
  if (c.mtimeMs <= cutoff) {
47692
47910
  try {
47693
- return JSON.parse(readFileSync55(c.p, "utf8"));
47911
+ return JSON.parse(readFileSync57(c.p, "utf8"));
47694
47912
  } catch {
47695
47913
  continue;
47696
47914
  }
@@ -48326,8 +48544,8 @@ var init_kill = __esm({
48326
48544
  });
48327
48545
 
48328
48546
  // src/cli/commands/marketing/doctor.ts
48329
- import { readFileSync as readFileSync56, readdirSync as readdirSync18, statSync as statSync14 } from "fs";
48330
- import { join as join71 } from "path";
48547
+ import { readFileSync as readFileSync58, readdirSync as readdirSync19, statSync as statSync14 } from "fs";
48548
+ import { join as join73 } from "path";
48331
48549
  function registerMarketingDoctor(parent) {
48332
48550
  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) => {
48333
48551
  console.log(header("Marketing doctor"));
@@ -48408,7 +48626,7 @@ function scanForSecrets(root) {
48408
48626
  for (const file of walkText(root)) {
48409
48627
  let txt;
48410
48628
  try {
48411
- txt = readFileSync56(file, "utf8");
48629
+ txt = readFileSync58(file, "utf8");
48412
48630
  } catch {
48413
48631
  continue;
48414
48632
  }
@@ -48429,13 +48647,13 @@ function scanForSecrets(root) {
48429
48647
  function* walkText(dir) {
48430
48648
  let entries;
48431
48649
  try {
48432
- entries = readdirSync18(dir);
48650
+ entries = readdirSync19(dir);
48433
48651
  } catch {
48434
48652
  return;
48435
48653
  }
48436
48654
  for (const e of entries) {
48437
48655
  if (e.startsWith(".") && (e === ".env" || e === ".env.local")) continue;
48438
- const full = join71(dir, e);
48656
+ const full = join73(dir, e);
48439
48657
  let stat;
48440
48658
  try {
48441
48659
  stat = statSync14(full);
@@ -48473,8 +48691,8 @@ var init_doctor2 = __esm({
48473
48691
  });
48474
48692
 
48475
48693
  // src/lib/marketing/entity-store.ts
48476
- import { existsSync as existsSync78, readFileSync as readFileSync57, readdirSync as readdirSync19 } from "fs";
48477
- import { join as join72 } from "path";
48694
+ import { existsSync as existsSync80, readFileSync as readFileSync59, readdirSync as readdirSync20 } from "fs";
48695
+ import { join as join74 } from "path";
48478
48696
  function dirFor(kind) {
48479
48697
  switch (kind) {
48480
48698
  case "campaign":
@@ -48493,24 +48711,24 @@ function newEntityId(kind) {
48493
48711
  }
48494
48712
  function entityPaths(kind, id) {
48495
48713
  const d = dirFor(kind);
48496
- return { json: join72(d, `${id}.json`), md: join72(d, `${id}.md`) };
48714
+ return { json: join74(d, `${id}.json`), md: join74(d, `${id}.md`) };
48497
48715
  }
48498
48716
  function loadEntity(kind, id) {
48499
48717
  const { json } = entityPaths(kind, id);
48500
- if (!existsSync78(json)) return null;
48718
+ if (!existsSync80(json)) return null;
48501
48719
  try {
48502
- return JSON.parse(readFileSync57(json, "utf8"));
48720
+ return JSON.parse(readFileSync59(json, "utf8"));
48503
48721
  } catch {
48504
48722
  return null;
48505
48723
  }
48506
48724
  }
48507
48725
  function listEntities(kind) {
48508
48726
  const d = dirFor(kind);
48509
- if (!existsSync78(d)) return [];
48727
+ if (!existsSync80(d)) return [];
48510
48728
  const out = [];
48511
- for (const f of readdirSync19(d).filter((x) => x.endsWith(".json"))) {
48729
+ for (const f of readdirSync20(d).filter((x) => x.endsWith(".json"))) {
48512
48730
  try {
48513
- out.push(JSON.parse(readFileSync57(join72(d, f), "utf8")));
48731
+ out.push(JSON.parse(readFileSync59(join74(d, f), "utf8")));
48514
48732
  } catch {
48515
48733
  }
48516
48734
  }
@@ -48704,7 +48922,7 @@ var init_campaign = __esm({
48704
48922
  });
48705
48923
 
48706
48924
  // src/cli/commands/marketing/adset.ts
48707
- import { existsSync as existsSync79, readFileSync as readFileSync58 } from "fs";
48925
+ import { existsSync as existsSync81, readFileSync as readFileSync60 } from "fs";
48708
48926
  function registerMarketingAdSet(parent) {
48709
48927
  const cmd = parent.command("adset").description("Manage adsets.");
48710
48928
  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) => {
@@ -48724,13 +48942,13 @@ function registerMarketingAdSet(parent) {
48724
48942
  }
48725
48943
  throw e;
48726
48944
  }
48727
- if (!existsSync79(opts.targeting)) {
48945
+ if (!existsSync81(opts.targeting)) {
48728
48946
  error(`Targeting file not found: ${opts.targeting}`);
48729
48947
  process.exit(1);
48730
48948
  }
48731
48949
  let targeting;
48732
48950
  try {
48733
- targeting = JSON.parse(readFileSync58(opts.targeting, "utf8"));
48951
+ targeting = JSON.parse(readFileSync60(opts.targeting, "utf8"));
48734
48952
  } catch (e) {
48735
48953
  error(`Failed to parse targeting JSON: ${e.message}`);
48736
48954
  process.exit(1);
@@ -48987,12 +49205,12 @@ var init_creative = __esm({
48987
49205
  });
48988
49206
 
48989
49207
  // src/cli/commands/marketing/asset.ts
48990
- import { existsSync as existsSync80, statSync as statSync15 } from "fs";
49208
+ import { existsSync as existsSync82, statSync as statSync15 } from "fs";
48991
49209
  import { extname as extname5 } from "path";
48992
49210
  function registerMarketingAsset(parent) {
48993
49211
  const cmd = parent.command("asset").description("Upload creative assets to Meta.");
48994
49212
  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) => {
48995
- if (!existsSync80(path2)) {
49213
+ if (!existsSync82(path2)) {
48996
49214
  error(`File not found: ${path2}`);
48997
49215
  process.exit(1);
48998
49216
  }
@@ -49160,8 +49378,8 @@ var init_ad = __esm({
49160
49378
  });
49161
49379
 
49162
49380
  // src/lib/marketing/launch.ts
49163
- import { existsSync as existsSync81, readFileSync as readFileSync59, writeFileSync as writeFileSync40, mkdirSync as mkdirSync35, renameSync as renameSync8, readdirSync as readdirSync20 } from "fs";
49164
- import { dirname as dirname43, join as join73, basename as basename22 } from "path";
49381
+ import { existsSync as existsSync83, readFileSync as readFileSync61, writeFileSync as writeFileSync41, mkdirSync as mkdirSync36, renameSync as renameSync8, readdirSync as readdirSync21 } from "fs";
49382
+ import { dirname as dirname45, join as join75, basename as basename22 } from "path";
49165
49383
  import { randomBytes as randomBytes4 } from "crypto";
49166
49384
  function buildLaunchSummary(cohortId) {
49167
49385
  const cohort = loadCohort(cohortId);
@@ -49205,15 +49423,15 @@ function isoTs2() {
49205
49423
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
49206
49424
  }
49207
49425
  function atomicWriteFile3(path2, data) {
49208
- mkdirSync35(dirname43(path2), { recursive: true });
49426
+ mkdirSync36(dirname45(path2), { recursive: true });
49209
49427
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes4(4).toString("hex")}`;
49210
- writeFileSync40(tmp, data, "utf8");
49428
+ writeFileSync41(tmp, data, "utf8");
49211
49429
  renameSync8(tmp, path2);
49212
49430
  }
49213
49431
  function readWal(path2) {
49214
- if (!existsSync81(path2)) return null;
49432
+ if (!existsSync83(path2)) return null;
49215
49433
  try {
49216
- return JSON.parse(readFileSync59(path2, "utf8"));
49434
+ return JSON.parse(readFileSync61(path2, "utf8"));
49217
49435
  } catch {
49218
49436
  return null;
49219
49437
  }
@@ -49223,13 +49441,13 @@ function writeWal(path2, wal) {
49223
49441
  }
49224
49442
  function findWalByRunId(runId) {
49225
49443
  const dir = MARKETING_PATHS.runsDir();
49226
- if (!existsSync81(dir)) return null;
49227
- for (const f of readdirSync20(dir)) {
49444
+ if (!existsSync83(dir)) return null;
49445
+ for (const f of readdirSync21(dir)) {
49228
49446
  if (!f.endsWith(".json")) continue;
49229
49447
  if (f.startsWith("by-idem")) continue;
49230
49448
  const stem = f.replace(/\.json$/, "");
49231
49449
  if (stem === runId || f === runId || basename22(f, ".json") === runId) {
49232
- return join73(dir, f);
49450
+ return join75(dir, f);
49233
49451
  }
49234
49452
  }
49235
49453
  return null;
@@ -49269,7 +49487,7 @@ function createLaunchWal(args) {
49269
49487
  flipped_count: 0,
49270
49488
  error: null
49271
49489
  };
49272
- const walPath = join73(MARKETING_PATHS.runsDir(), `${id}.json`);
49490
+ const walPath = join75(MARKETING_PATHS.runsDir(), `${id}.json`);
49273
49491
  writeWal(walPath, wal);
49274
49492
  return { walPath, wal };
49275
49493
  }
@@ -49500,7 +49718,7 @@ var init_launch2 = __esm({
49500
49718
  });
49501
49719
 
49502
49720
  // src/cli/commands/marketing/learnings.ts
49503
- import { existsSync as existsSync82, readFileSync as readFileSync60 } from "fs";
49721
+ import { existsSync as existsSync84, readFileSync as readFileSync62 } from "fs";
49504
49722
  function registerMarketingLearnings(parent) {
49505
49723
  const cmd = parent.command("learnings").description("Performance Monitor learnings ledger (per-day .md + index).");
49506
49724
  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) => {
@@ -49643,8 +49861,8 @@ async function resolveBody(body, bodyFile) {
49643
49861
  if (body) return body;
49644
49862
  if (bodyFile === "-") return readStdin3();
49645
49863
  if (bodyFile) {
49646
- if (!existsSync82(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
49647
- return readFileSync60(bodyFile, "utf8");
49864
+ if (!existsSync84(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
49865
+ return readFileSync62(bodyFile, "utf8");
49648
49866
  }
49649
49867
  return null;
49650
49868
  }
@@ -49674,29 +49892,29 @@ var init_learnings2 = __esm({
49674
49892
 
49675
49893
  // src/lib/marketing/rem-sleep.ts
49676
49894
  import {
49677
- existsSync as existsSync83,
49678
- mkdirSync as mkdirSync36,
49679
- readFileSync as readFileSync61,
49680
- writeFileSync as writeFileSync41,
49681
- readdirSync as readdirSync21,
49895
+ existsSync as existsSync85,
49896
+ mkdirSync as mkdirSync37,
49897
+ readFileSync as readFileSync63,
49898
+ writeFileSync as writeFileSync42,
49899
+ readdirSync as readdirSync22,
49682
49900
  statSync as statSync16,
49683
49901
  unlinkSync as unlinkSync3,
49684
49902
  renameSync as renameSync9
49685
49903
  } from "fs";
49686
- import { dirname as dirname44, join as join74 } from "path";
49904
+ import { dirname as dirname46, join as join76 } from "path";
49687
49905
  import { randomBytes as randomBytes5 } from "crypto";
49688
49906
  function atomicWriteFile4(path2, data) {
49689
- mkdirSync36(dirname44(path2), { recursive: true });
49907
+ mkdirSync37(dirname46(path2), { recursive: true });
49690
49908
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes5(4).toString("hex")}`;
49691
- writeFileSync41(tmp, data, "utf8");
49909
+ writeFileSync42(tmp, data, "utf8");
49692
49910
  renameSync9(tmp, path2);
49693
49911
  }
49694
49912
  function pruneRuns(opts = {}) {
49695
49913
  const keepLast = opts.keepLast ?? 100;
49696
49914
  const dir = MARKETING_PATHS.runsDir();
49697
- if (!existsSync83(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
49698
- const files = readdirSync21(dir).filter((f) => f.endsWith(".json")).map((f) => {
49699
- const p = join74(dir, f);
49915
+ if (!existsSync85(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
49916
+ const files = readdirSync22(dir).filter((f) => f.endsWith(".json")).map((f) => {
49917
+ const p = join76(dir, f);
49700
49918
  try {
49701
49919
  return { f, p, mtimeMs: statSync16(p).mtimeMs };
49702
49920
  } catch {
@@ -49730,13 +49948,13 @@ function compactInsights(opts = {}) {
49730
49948
  const weeklyAfterDays = opts.weeklyAfterDays ?? 14;
49731
49949
  const now = opts.now ?? /* @__PURE__ */ new Date();
49732
49950
  const dir = MARKETING_PATHS.insightsDir();
49733
- if (!existsSync83(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
49951
+ if (!existsSync85(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
49734
49952
  const files = [];
49735
- for (const f of readdirSync21(dir)) {
49953
+ for (const f of readdirSync22(dir)) {
49736
49954
  if (!f.endsWith(".json") || f.startsWith("_")) continue;
49737
49955
  const m = f.match(SNAP_RE);
49738
49956
  if (!m) continue;
49739
- const p = join74(dir, f);
49957
+ const p = join76(dir, f);
49740
49958
  try {
49741
49959
  const stat = statSync16(p);
49742
49960
  files.push({ f, p, mtimeMs: stat.mtimeMs, entityId: m[1], bucket: m[2] });
@@ -49802,18 +50020,18 @@ function mergeDailyLearnings(opts = {}) {
49802
50020
  const retainDays = opts.retainDays ?? 7;
49803
50021
  const now = opts.now ?? /* @__PURE__ */ new Date();
49804
50022
  const dir = MARKETING_PATHS.learningsDir();
49805
- if (!existsSync83(dir)) {
50023
+ if (!existsSync85(dir)) {
49806
50024
  return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
49807
50025
  }
49808
50026
  const dayMs = 24 * 60 * 60 * 1e3;
49809
50027
  const cutoff = now.getTime() - retainDays * dayMs;
49810
50028
  const candidates = [];
49811
- for (const f of readdirSync21(dir)) {
50029
+ for (const f of readdirSync22(dir)) {
49812
50030
  const m = f.match(/^(\d{4}-\d{2}-\d{2})\.md$/);
49813
50031
  if (!m) continue;
49814
50032
  const date = m[1];
49815
50033
  const dateMs = (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getTime();
49816
- if (dateMs < cutoff) candidates.push({ f, p: join74(dir, f), date });
50034
+ if (dateMs < cutoff) candidates.push({ f, p: join76(dir, f), date });
49817
50035
  }
49818
50036
  if (candidates.length === 0) {
49819
50037
  return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
@@ -49827,10 +50045,10 @@ function mergeDailyLearnings(opts = {}) {
49827
50045
  const mergedFiles = [];
49828
50046
  let lastArchivePath = null;
49829
50047
  for (const [q, list] of byQuarter) {
49830
- const archivePath = join74(dir, `_archive-${q}.md`);
50048
+ const archivePath = join76(dir, `_archive-${q}.md`);
49831
50049
  list.sort((a, b) => a.date.localeCompare(b.date));
49832
50050
  for (const c of list) {
49833
- const existingArchive = existsSync83(archivePath) ? readFileSync61(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
50051
+ const existingArchive = existsSync85(archivePath) ? readFileSync63(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
49834
50052
  `;
49835
50053
  const dateMarker = `# Marketing learnings \u2014 ${c.date}`;
49836
50054
  const alreadyMerged = existingArchive.includes(dateMarker);
@@ -49839,7 +50057,7 @@ function mergeDailyLearnings(opts = {}) {
49839
50057
  continue;
49840
50058
  }
49841
50059
  if (!alreadyMerged) {
49842
- const body = readFileSync61(c.p, "utf8").trimEnd();
50060
+ const body = readFileSync63(c.p, "utf8").trimEnd();
49843
50061
  const next2 = existingArchive.trimEnd() + "\n\n" + body + "\n";
49844
50062
  atomicWriteFile4(archivePath, next2);
49845
50063
  }
@@ -49882,14 +50100,14 @@ function quarterKey(yyyymmdd) {
49882
50100
  }
49883
50101
  function redactRunsSweep(opts = {}) {
49884
50102
  const dir = MARKETING_PATHS.runsDir();
49885
- if (!existsSync83(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
49886
- const files = readdirSync21(dir).filter((f) => f.endsWith(".json"));
50103
+ if (!existsSync85(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
50104
+ const files = readdirSync22(dir).filter((f) => f.endsWith(".json"));
49887
50105
  const rewrittenFiles = [];
49888
50106
  for (const f of files) {
49889
- const p = join74(dir, f);
50107
+ const p = join76(dir, f);
49890
50108
  let raw;
49891
50109
  try {
49892
- raw = readFileSync61(p, "utf8");
50110
+ raw = readFileSync63(p, "utf8");
49893
50111
  } catch {
49894
50112
  continue;
49895
50113
  }
@@ -49911,7 +50129,7 @@ function redactRunsSweep(opts = {}) {
49911
50129
  function runRemSleep(opts = {}) {
49912
50130
  const ranAt = (opts.now ?? /* @__PURE__ */ new Date()).toISOString();
49913
50131
  const root = marketingRootIfExists();
49914
- if (!root || !existsSync83(root)) {
50132
+ if (!root || !existsSync85(root)) {
49915
50133
  return {
49916
50134
  ranAt,
49917
50135
  marketingPresent: false,
@@ -49933,7 +50151,7 @@ function runRemSleep(opts = {}) {
49933
50151
  now: opts.now
49934
50152
  });
49935
50153
  const redaction = redactRunsSweep({ dryRun: opts.dryRun });
49936
- void mkdirSync36;
50154
+ void mkdirSync37;
49937
50155
  return { ranAt, marketingPresent: true, runs, insights, learnings, redaction };
49938
50156
  }
49939
50157
  var SNAP_RE;
@@ -50030,9 +50248,9 @@ var init_git_guard = __esm({
50030
50248
  });
50031
50249
 
50032
50250
  // src/cli/commands/marketing/hooks.ts
50033
- import { existsSync as existsSync84, readFileSync as readFileSync62, writeFileSync as writeFileSync42, chmodSync as chmodSync3, mkdirSync as mkdirSync37, statSync as statSync17 } from "fs";
50251
+ import { existsSync as existsSync86, readFileSync as readFileSync64, writeFileSync as writeFileSync43, chmodSync as chmodSync3, mkdirSync as mkdirSync38, statSync as statSync17 } from "fs";
50034
50252
  import { execFileSync as execFileSync6 } from "child_process";
50035
- import { join as join75 } from "path";
50253
+ import { join as join77 } from "path";
50036
50254
  function findGitDir(cwd = process.cwd()) {
50037
50255
  try {
50038
50256
  const out = execFileSync6("git", ["rev-parse", "--git-dir"], {
@@ -50041,7 +50259,7 @@ function findGitDir(cwd = process.cwd()) {
50041
50259
  stdio: ["ignore", "pipe", "ignore"]
50042
50260
  }).trim();
50043
50261
  if (!out) return null;
50044
- return out.startsWith("/") ? out : join75(cwd, out);
50262
+ return out.startsWith("/") ? out : join77(cwd, out);
50045
50263
  } catch {
50046
50264
  return null;
50047
50265
  }
@@ -50072,11 +50290,11 @@ function registerMarketingHooks(parent) {
50072
50290
  error("Not inside a git repository (or `git` is not on PATH).");
50073
50291
  process.exit(1);
50074
50292
  }
50075
- const hooksDir = join75(gitDir, "hooks");
50076
- mkdirSync37(hooksDir, { recursive: true });
50077
- const target = join75(hooksDir, "pre-commit");
50078
- if (existsSync84(target)) {
50079
- const existing = readFileSync62(target, "utf-8");
50293
+ const hooksDir = join77(gitDir, "hooks");
50294
+ mkdirSync38(hooksDir, { recursive: true });
50295
+ const target = join77(hooksDir, "pre-commit");
50296
+ if (existsSync86(target)) {
50297
+ const existing = readFileSync64(target, "utf-8");
50080
50298
  if (existing.includes(MANAGED_MARKER)) {
50081
50299
  info("pre-commit hook already managed by dreamcontext \u2014 refreshing.");
50082
50300
  } else if (!opts.force) {
@@ -50088,7 +50306,7 @@ function registerMarketingHooks(parent) {
50088
50306
  warn("Overwriting existing pre-commit hook (--force).");
50089
50307
  }
50090
50308
  }
50091
- writeFileSync42(target, HOOK_LAUNCHER, "utf-8");
50309
+ writeFileSync43(target, HOOK_LAUNCHER, "utf-8");
50092
50310
  try {
50093
50311
  chmodSync3(target, 493);
50094
50312
  } catch {
@@ -50127,26 +50345,26 @@ exec dreamcontext mk hooks check-staged
50127
50345
  });
50128
50346
 
50129
50347
  // src/lib/marketing/council-personas.ts
50130
- import { existsSync as existsSync85, readFileSync as readFileSync63, readdirSync as readdirSync22 } from "fs";
50348
+ import { existsSync as existsSync87, readFileSync as readFileSync65, readdirSync as readdirSync23 } from "fs";
50131
50349
  import { fileURLToPath as fileURLToPath9 } from "url";
50132
- import { join as join76, dirname as dirname45 } from "path";
50350
+ import { join as join78, dirname as dirname47 } from "path";
50133
50351
  function findPersonasDir() {
50134
50352
  const candidates = [
50135
50353
  // dev: src/lib/marketing/council-personas.ts → ../../../skill-packs/...
50136
- join76(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
50354
+ join78(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
50137
50355
  // built: dist/index.js → ./skill-packs/...
50138
- join76(__dirname_local, PERSONA_SUBPATH),
50356
+ join78(__dirname_local, PERSONA_SUBPATH),
50139
50357
  // tsup-bundled (deeper nesting if ever): ../skill-packs/...
50140
- join76(__dirname_local, "..", PERSONA_SUBPATH),
50141
- join76(__dirname_local, "..", "..", PERSONA_SUBPATH)
50358
+ join78(__dirname_local, "..", PERSONA_SUBPATH),
50359
+ join78(__dirname_local, "..", "..", PERSONA_SUBPATH)
50142
50360
  ];
50143
50361
  for (const candidate of candidates) {
50144
- if (existsSync85(candidate)) return candidate;
50362
+ if (existsSync87(candidate)) return candidate;
50145
50363
  }
50146
50364
  return null;
50147
50365
  }
50148
50366
  function parsePersonaFile(filePath) {
50149
- const raw = readFileSync63(filePath, "utf-8");
50367
+ const raw = readFileSync65(filePath, "utf-8");
50150
50368
  const parsed = (0, import_gray_matter5.default)(raw);
50151
50369
  const data = parsed.data;
50152
50370
  const slug = typeof data.slug === "string" ? data.slug.trim() : "";
@@ -50166,9 +50384,9 @@ function parsePersonaFile(filePath) {
50166
50384
  }
50167
50385
  function loadAllPersonas(personasDir) {
50168
50386
  const dir = personasDir ?? findPersonasDir();
50169
- if (!dir || !existsSync85(dir)) return [];
50170
- const files = readdirSync22(dir).filter((n) => n.endsWith(".md")).sort();
50171
- return files.map((name) => parsePersonaFile(join76(dir, name)));
50387
+ if (!dir || !existsSync87(dir)) return [];
50388
+ const files = readdirSync23(dir).filter((n) => n.endsWith(".md")).sort();
50389
+ return files.map((name) => parsePersonaFile(join78(dir, name)));
50172
50390
  }
50173
50391
  function selectPersonas(all, requested) {
50174
50392
  if (requested.length === 0) return [...all];
@@ -50187,23 +50405,23 @@ var init_council_personas = __esm({
50187
50405
  import_gray_matter5 = __toESM(require_gray_matter(), 1);
50188
50406
  __dirname_local = (() => {
50189
50407
  try {
50190
- return dirname45(fileURLToPath9(import.meta.url));
50408
+ return dirname47(fileURLToPath9(import.meta.url));
50191
50409
  } catch {
50192
50410
  return process.cwd();
50193
50411
  }
50194
50412
  })();
50195
50413
  VALID_MODELS2 = /* @__PURE__ */ new Set(["opus", "sonnet", "haiku"]);
50196
- PERSONA_SUBPATH = join76("skill-packs", "meta-marketing", "council-personas");
50414
+ PERSONA_SUBPATH = join78("skill-packs", "meta-marketing", "council-personas");
50197
50415
  }
50198
50416
  });
50199
50417
 
50200
50418
  // src/cli/commands/marketing/council.ts
50201
50419
  import { spawnSync as spawnSync4 } from "child_process";
50202
- import { existsSync as existsSync86 } from "fs";
50420
+ import { existsSync as existsSync88 } from "fs";
50203
50421
  function resolveDreamcontextEntry() {
50204
50422
  const node = process.argv[0];
50205
50423
  const script = process.argv[1];
50206
- if (script && existsSync86(script)) {
50424
+ if (script && existsSync88(script)) {
50207
50425
  return { node, script };
50208
50426
  }
50209
50427
  return { node, script: null };
@@ -50375,8 +50593,8 @@ var init_marketing = __esm({
50375
50593
  });
50376
50594
 
50377
50595
  // src/cli/commands/memory.ts
50378
- import { existsSync as existsSync87, unlinkSync as unlinkSync4 } from "fs";
50379
- import { join as join77, dirname as dirname46 } from "path";
50596
+ import { existsSync as existsSync89, unlinkSync as unlinkSync4 } from "fs";
50597
+ import { join as join79, dirname as dirname48 } from "path";
50380
50598
  function collectVault(value, previous) {
50381
50599
  return [...previous, value];
50382
50600
  }
@@ -50388,7 +50606,7 @@ function parseTypes(value) {
50388
50606
  return filtered.length > 0 ? filtered : void 0;
50389
50607
  }
50390
50608
  function recallFederated(contextRoot, query, topK, types, opts) {
50391
- const projectRoot = dirname46(contextRoot);
50609
+ const projectRoot = dirname48(contextRoot);
50392
50610
  const { target: currentTarget } = currentVaultTarget(projectRoot);
50393
50611
  const byName = /* @__PURE__ */ new Map();
50394
50612
  const add = (t) => {
@@ -50541,7 +50759,7 @@ function registerMemoryCommand(program2) {
50541
50759
  const summary = opts.summary ?? (text.length > 200 ? text.slice(0, 197) + "..." : text);
50542
50760
  const references = opts.references ? opts.references.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
50543
50761
  const authors = opts.person ? opts.person.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
50544
- const changelogPath = join77(root, "core", "CHANGELOG.json");
50762
+ const changelogPath = join79(root, "core", "CHANGELOG.json");
50545
50763
  const entry = {
50546
50764
  date: today(),
50547
50765
  type: opts.type ?? "note",
@@ -50559,8 +50777,8 @@ function registerMemoryCommand(program2) {
50559
50777
  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(
50560
50778
  async (slug, opts) => {
50561
50779
  const root = ensureContextRoot();
50562
- const filePath = join77(root, "knowledge", `${slug}.md`);
50563
- if (!existsSync87(filePath)) {
50780
+ const filePath = join79(root, "knowledge", `${slug}.md`);
50781
+ if (!existsSync89(filePath)) {
50564
50782
  error(`Knowledge file not found: ${slug}.md`);
50565
50783
  return;
50566
50784
  }
@@ -50607,8 +50825,8 @@ ${opts.append}
50607
50825
  );
50608
50826
  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) => {
50609
50827
  const root = ensureContextRoot();
50610
- const filePath = join77(root, "knowledge", `${slug}.md`);
50611
- if (!existsSync87(filePath)) {
50828
+ const filePath = join79(root, "knowledge", `${slug}.md`);
50829
+ if (!existsSync89(filePath)) {
50612
50830
  error(`Knowledge file not found: ${slug}.md`);
50613
50831
  return;
50614
50832
  }
@@ -50716,13 +50934,13 @@ var init_memory = __esm({
50716
50934
 
50717
50935
  // src/cli/commands/upgrade.ts
50718
50936
  import { execFileSync as execFileSync8 } from "child_process";
50719
- import { dirname as dirname47 } from "path";
50937
+ import { dirname as dirname49 } from "path";
50720
50938
  function defaultInstaller(args) {
50721
50939
  execFileSync8("npm", args, { stdio: "inherit" });
50722
50940
  }
50723
50941
  function projectRootForCache() {
50724
50942
  const contextDir = resolveContextRoot();
50725
- return contextDir ? dirname47(contextDir) : process.cwd();
50943
+ return contextDir ? dirname49(contextDir) : process.cwd();
50726
50944
  }
50727
50945
  function defaultLiveLatest() {
50728
50946
  let latest = null;
@@ -51045,9 +51263,9 @@ var init_vaults3 = __esm({
51045
51263
  });
51046
51264
 
51047
51265
  // src/cli/commands/connections.ts
51048
- import { dirname as dirname48 } from "path";
51266
+ import { dirname as dirname50 } from "path";
51049
51267
  function currentVaultName2(contextRoot) {
51050
- return currentVaultTarget(dirname48(contextRoot)).name;
51268
+ return currentVaultTarget(dirname50(contextRoot)).name;
51051
51269
  }
51052
51270
  function registerConnectionsCommand(program2) {
51053
51271
  program2.command("connect <vault>").description("Connect this vault to a peer for federation (out|in|both)").option("-d, --direction <direction>", "Connection direction: out | in | both", "both").option("--topics <list>", "Comma-separated topic filter (default: all topics)").action((vault, opts) => {
@@ -51129,17 +51347,17 @@ var init_connections3 = __esm({
51129
51347
  });
51130
51348
 
51131
51349
  // src/lib/federation-ingest.ts
51132
- import { existsSync as existsSync88, mkdirSync as mkdirSync38 } from "fs";
51133
- import { join as join78 } from "path";
51350
+ import { existsSync as existsSync90, mkdirSync as mkdirSync39 } from "fs";
51351
+ import { join as join80 } from "path";
51134
51352
  function ingestEntry(contextRoot, entry) {
51135
- const knowledgeDir = join78(contextRoot, "knowledge");
51136
- mkdirSync38(knowledgeDir, { recursive: true });
51353
+ const knowledgeDir = join80(contextRoot, "knowledge");
51354
+ mkdirSync39(knowledgeDir, { recursive: true });
51137
51355
  const baseSlug = slugFromTitle(entry.title);
51138
- const canonicalPath = join78(knowledgeDir, `${baseSlug}.md`);
51139
- const collided = existsSync88(canonicalPath);
51356
+ const canonicalPath = join80(knowledgeDir, `${baseSlug}.md`);
51357
+ const collided = existsSync90(canonicalPath);
51140
51358
  const slug = collided ? `${baseSlug}--from-${sanitizeVault(entry.origin.vault)}` : baseSlug;
51141
- const targetPath = join78(knowledgeDir, `${slug}.md`);
51142
- if (!existsSync88(targetPath)) {
51359
+ const targetPath = join80(knowledgeDir, `${slug}.md`);
51360
+ if (!existsSync90(targetPath)) {
51143
51361
  writeFrontmatter(
51144
51362
  targetPath,
51145
51363
  {
@@ -51215,9 +51433,9 @@ var init_federation_ingest = __esm({
51215
51433
  });
51216
51434
 
51217
51435
  // src/cli/commands/federation.ts
51218
- import { dirname as dirname49 } from "path";
51436
+ import { dirname as dirname51 } from "path";
51219
51437
  function currentVaultName3(contextRoot) {
51220
- return currentVaultTarget(dirname49(contextRoot)).name;
51438
+ return currentVaultTarget(dirname51(contextRoot)).name;
51221
51439
  }
51222
51440
  function outboundConnections(contextRoot) {
51223
51441
  return listConnections(contextRoot).filter(
@@ -51430,12 +51648,12 @@ var init_people = __esm({
51430
51648
  });
51431
51649
 
51432
51650
  // src/cli/commands/config.ts
51433
- import { dirname as dirname50 } from "path";
51434
- import { existsSync as existsSync89, readFileSync as readFileSync65, writeFileSync as writeFileSync44 } from "fs";
51435
- import { join as join79 } from "path";
51651
+ import { dirname as dirname52 } from "path";
51652
+ import { existsSync as existsSync91, readFileSync as readFileSync67, writeFileSync as writeFileSync45 } from "fs";
51653
+ import { join as join81 } from "path";
51436
51654
  function resolveProjectRoot() {
51437
51655
  const contextRoot = resolveContextRoot();
51438
- return contextRoot ? dirname50(contextRoot) : null;
51656
+ return contextRoot ? dirname52(contextRoot) : null;
51439
51657
  }
51440
51658
  function requireProjectRoot() {
51441
51659
  const projectRoot = resolveProjectRoot();
@@ -51594,7 +51812,7 @@ function registerConfigCommand(program2) {
51594
51812
  const liveToken = resolveClickUpToken(projectRoot);
51595
51813
  let connected = false;
51596
51814
  if (liveToken) {
51597
- const contextRoot = join79(projectRoot, "_dream_context");
51815
+ const contextRoot = join81(projectRoot, "_dream_context");
51598
51816
  const probe = createClickUpBackend(contextRoot, readSetupConfig(projectRoot));
51599
51817
  const test = await probe.testConnection();
51600
51818
  if (test.ok) {
@@ -51637,7 +51855,7 @@ function registerConfigCommand(program2) {
51637
51855
  cfgNow = readSetupConfig(projectRoot);
51638
51856
  }
51639
51857
  if (connected && cfgNow?.clickup?.listId) {
51640
- const contextRoot = join79(projectRoot, "_dream_context");
51858
+ const contextRoot = join81(projectRoot, "_dream_context");
51641
51859
  const backend2 = createClickUpBackend(contextRoot, cfgNow);
51642
51860
  if (await esm_default4({ message: "Create the recommended custom fields on the list (urgency, summary, RICE, \u2026)?", default: true })) {
51643
51861
  const result = await backend2.provisionRemote();
@@ -51692,13 +51910,13 @@ function registerConfigCommand(program2) {
51692
51910
  const contextRoot = resolveContextRoot();
51693
51911
  let userMdSynced = false;
51694
51912
  if (contextRoot) {
51695
- const userMdPath = join79(contextRoot, "core", "1.user.md");
51696
- if (existsSync89(userMdPath)) {
51913
+ const userMdPath = join81(contextRoot, "core", "1.user.md");
51914
+ if (existsSync91(userMdPath)) {
51697
51915
  try {
51698
- const before = readFileSync65(userMdPath, "utf-8");
51916
+ const before = readFileSync67(userMdPath, "utf-8");
51699
51917
  const after = ensurePeopleSection(before, roster);
51700
51918
  if (after !== before) {
51701
- writeFileSync44(userMdPath, after, "utf-8");
51919
+ writeFileSync45(userMdPath, after, "utf-8");
51702
51920
  userMdSynced = true;
51703
51921
  }
51704
51922
  } catch (err) {
@@ -51742,7 +51960,7 @@ function registerConfigCommand(program2) {
51742
51960
  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) => {
51743
51961
  const projectRoot = requireProjectRoot();
51744
51962
  if (!projectRoot) return;
51745
- const contextRoot = join79(projectRoot, "_dream_context");
51963
+ const contextRoot = join81(projectRoot, "_dream_context");
51746
51964
  const existing = readSetupConfig(projectRoot)?.clickup ?? {};
51747
51965
  const ledger = new SyncLedger(contextRoot);
51748
51966
  const changingList = !!existing.listId && existing.listId !== listId && ledger.readMap().length > 0;
@@ -51783,8 +52001,8 @@ function registerConfigCommand(program2) {
51783
52001
  if (!value) {
51784
52002
  if (!process.stdin.isTTY) {
51785
52003
  try {
51786
- const { readFileSync: readFileSync66 } = await import("fs");
51787
- value = readFileSync66(0, "utf-8").trim();
52004
+ const { readFileSync: readFileSync68 } = await import("fs");
52005
+ value = readFileSync68(0, "utf-8").trim();
51788
52006
  } catch {
51789
52007
  value = "";
51790
52008
  }
@@ -52143,12 +52361,12 @@ var init_feedback2 = __esm({
52143
52361
  });
52144
52362
 
52145
52363
  // src/cli/commands/migrations.ts
52146
- import { dirname as dirname51 } from "path";
52364
+ import { dirname as dirname53 } from "path";
52147
52365
  function registerMigrationsCommand(program2) {
52148
52366
  const migrations = program2.command("migrations").description("Inspect and record brain structure migrations");
52149
52367
  migrations.command("pending").description("Print pending agent task instructions for any unfinished migrations").action(() => {
52150
52368
  const root = ensureContextRoot();
52151
- const projectRoot = dirname51(root);
52369
+ const projectRoot = dirname53(root);
52152
52370
  const config = readSetupConfig(projectRoot);
52153
52371
  const fromVersion = config?.setupVersion ?? "0.0.0";
52154
52372
  const toVersion = dreamcontextVersion();