dreamcontext 0.16.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/dashboard/assets/{BrainCanvas3D-Dq2AZVLs.js → BrainCanvas3D-DyF_3yYD.js} +1 -1
  2. package/dist/dashboard/assets/{_baseUniq-Rjr0gzcI.js → _baseUniq-Do8VMBA0.js} +1 -1
  3. package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-B6xPVLtZ.js → ar-SA-G6X2FPQ2-DmbXDb2R.js} +1 -1
  4. package/dist/dashboard/assets/{arc-MywWiHZZ.js → arc-CwtUBQfU.js} +1 -1
  5. package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-DYku7HV_.js → architectureDiagram-Q4EWVU46-O9bOog_f.js} +1 -1
  6. package/dist/dashboard/assets/{az-AZ-76LH7QW2-DS6KjFyN.js → az-AZ-76LH7QW2-c9Zk10vG.js} +1 -1
  7. package/dist/dashboard/assets/{bg-BG-XCXSNQG7-5dVZIYN7.js → bg-BG-XCXSNQG7-uMTg84lX.js} +1 -1
  8. package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-CLHIA42j.js → blockDiagram-DXYQGD6D-BTENXCSO.js} +1 -1
  9. package/dist/dashboard/assets/{bn-BD-2XOGV67Q-DPdctd0M.js → bn-BD-2XOGV67Q-DUFKHcua.js} +1 -1
  10. package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-KCxsjhZ-.js → c4Diagram-AHTNJAMY-DMXPWRiQ.js} +1 -1
  11. package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-BwsiffyD.js → ca-ES-6MX7JW3Y-BuYX1q89.js} +1 -1
  12. package/dist/dashboard/assets/channel-2YfRjala.js +1 -0
  13. package/dist/dashboard/assets/{chunk-4BX2VUAB-CXYJqRL7.js → chunk-4BX2VUAB-DgefvnWS.js} +1 -1
  14. package/dist/dashboard/assets/{chunk-4TB4RGXK-64IoWLUH.js → chunk-4TB4RGXK-BnFO5G1t.js} +1 -1
  15. package/dist/dashboard/assets/{chunk-55IACEB6-oeTs6Ons.js → chunk-55IACEB6-COm2TYEM.js} +1 -1
  16. package/dist/dashboard/assets/{chunk-EDXVE4YY-DnBDiozF.js → chunk-EDXVE4YY-CtsGCwZp.js} +1 -1
  17. package/dist/dashboard/assets/{chunk-FMBD7UC4-1vZj5k6I.js → chunk-FMBD7UC4-cfSvx35j.js} +1 -1
  18. package/dist/dashboard/assets/{chunk-OYMX7WX6-ChzA2Qb2.js → chunk-OYMX7WX6-DAhDKteL.js} +1 -1
  19. package/dist/dashboard/assets/{chunk-QZHKN3VN-DFD_tEP6.js → chunk-QZHKN3VN-B5h4qML3.js} +1 -1
  20. package/dist/dashboard/assets/{chunk-YZCP3GAM-BHU_oH_c.js → chunk-YZCP3GAM-CGp_NiRg.js} +1 -1
  21. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DB_UnN1h.js +1 -0
  22. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DB_UnN1h.js +1 -0
  23. package/dist/dashboard/assets/clone-DaDvB3N6.js +1 -0
  24. package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-Bg8VEGjl.js → cose-bilkent-S5V4N54A-Dk7CMFA4.js} +1 -1
  25. package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-CwAnE7Z6.js → cs-CZ-2BRQDIVT-zfUTiS_d.js} +1 -1
  26. package/dist/dashboard/assets/{da-DK-5WZEPLOC-DsAINO0_.js → da-DK-5WZEPLOC-CU14f8NA.js} +1 -1
  27. package/dist/dashboard/assets/{dagre-KV5264BT-CdNovau5.js → dagre-KV5264BT-BiMVxC4Q.js} +1 -1
  28. package/dist/dashboard/assets/{de-DE-XR44H4JA-DQ5OpjQD.js → de-DE-XR44H4JA-CDOHAJGo.js} +1 -1
  29. package/dist/dashboard/assets/{diagram-5BDNPKRD-DIm6J283.js → diagram-5BDNPKRD-DfJEsVTA.js} +1 -1
  30. package/dist/dashboard/assets/{diagram-G4DWMVQ6-CK08ITsx.js → diagram-G4DWMVQ6-CztLHIcY.js} +1 -1
  31. package/dist/dashboard/assets/{diagram-MMDJMWI5-DhJYPP7z.js → diagram-MMDJMWI5-DqoQLlWK.js} +1 -1
  32. package/dist/dashboard/assets/{diagram-TYMM5635-C_e80UTu.js → diagram-TYMM5635-DvyvQBCc.js} +1 -1
  33. package/dist/dashboard/assets/{el-GR-BZB4AONW-DclRqvkS.js → el-GR-BZB4AONW-ChUphbcv.js} +1 -1
  34. package/dist/dashboard/assets/{erDiagram-SMLLAGMA-MyfjSgFp.js → erDiagram-SMLLAGMA-D_uSs2_2.js} +1 -1
  35. package/dist/dashboard/assets/{es-ES-U4NZUMDT-CHBzsVCs.js → es-ES-U4NZUMDT-BNalBEhb.js} +1 -1
  36. package/dist/dashboard/assets/{eu-ES-A7QVB2H4-CVStEZVJ.js → eu-ES-A7QVB2H4-BMiQyA2y.js} +1 -1
  37. package/dist/dashboard/assets/{fa-IR-HGAKTJCU-84UjGZiC.js → fa-IR-HGAKTJCU-Bd6ZnTSo.js} +1 -1
  38. package/dist/dashboard/assets/{fi-FI-Z5N7JZ37-B-_lgOAU.js → fi-FI-Z5N7JZ37-BWAfJadC.js} +1 -1
  39. package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-nR9IojlX.js → flowDiagram-DWJPFMVM-Bmsp6kyU.js} +1 -1
  40. package/dist/dashboard/assets/{fr-FR-RHASNOE6-lXmb84Qf.js → fr-FR-RHASNOE6-CspbYzOW.js} +1 -1
  41. package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-CDXS_k5x.js → ganttDiagram-T4ZO3ILL-wEdysXo_.js} +1 -1
  42. package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-DlSCg_be.js → gitGraphDiagram-UUTBAWPF-BEiGpPBj.js} +1 -1
  43. package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-DsAiVwM4.js → gl-ES-HMX3MZ6V-CV76vsWr.js} +1 -1
  44. package/dist/dashboard/assets/{graph-C23F2q3y.js → graph-CZFIeNHZ.js} +1 -1
  45. package/dist/dashboard/assets/{he-IL-6SHJWFNN-CNHUnglJ.js → he-IL-6SHJWFNN-Y1VoXJ_H.js} +1 -1
  46. package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-gkocGD33.js → hi-IN-IWLTKZ5I-Crh5S49o.js} +1 -1
  47. package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-lq_pPFj9.js → hu-HU-A5ZG7DT2-D4I3gCbp.js} +1 -1
  48. package/dist/dashboard/assets/{id-ID-SAP4L64H-DUKThVft.js → id-ID-SAP4L64H-Chvzkuvi.js} +1 -1
  49. package/dist/dashboard/assets/{index-xYYnjbSx.js → index-BIfrbaFS.js} +155 -155
  50. package/dist/dashboard/assets/{index-CVcgkdal.css → index-BdZ3tppu.css} +2 -2
  51. package/dist/dashboard/assets/{index-DFFGxCUu.js → index-C7Bo5AQH.js} +1 -1
  52. package/dist/dashboard/assets/{infoDiagram-42DDH7IO-BIZDd3qg.js → infoDiagram-42DDH7IO-BzfuDHl4.js} +1 -1
  53. package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-Bj5MHhfc.js → ishikawaDiagram-UXIWVN3A-BVoNJ9VS.js} +1 -1
  54. package/dist/dashboard/assets/{it-IT-JPQ66NNP-DIDeuYqe.js → it-IT-JPQ66NNP-BH_gN5es.js} +1 -1
  55. package/dist/dashboard/assets/{ja-JP-DBVTYXUO-BqPEBA22.js → ja-JP-DBVTYXUO-DU_WmLVa.js} +1 -1
  56. package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-B41HNLhc.js → journeyDiagram-VCZTEJTY-DbwICa_a.js} +1 -1
  57. package/dist/dashboard/assets/{kaa-6HZHGXH3-CCgtE0-l.js → kaa-6HZHGXH3-KYU9qowM.js} +1 -1
  58. package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-A4y6sskJ.js → kab-KAB-ZGHBKWFO-bjhyiUq5.js} +1 -1
  59. package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-DR-Zc9Wa.js → kanban-definition-6JOO6SKY-D9XucLs4.js} +1 -1
  60. package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-CaXfkWxC.js → kk-KZ-P5N5QNE5-CYTx_dAZ.js} +1 -1
  61. package/dist/dashboard/assets/{km-KH-HSX4SM5Z-DGfryG3j.js → km-KH-HSX4SM5Z-DqsuY4Lf.js} +1 -1
  62. package/dist/dashboard/assets/{ko-KR-MTYHY66A-CuNG6PfQ.js → ko-KR-MTYHY66A-BZe7NywF.js} +1 -1
  63. package/dist/dashboard/assets/{ku-TR-6OUDTVRD-DZNsnhP9.js → ku-TR-6OUDTVRD-F5d6HFWt.js} +1 -1
  64. package/dist/dashboard/assets/{layout-CThyY_Dn.js → layout-CotqU0S9.js} +1 -1
  65. package/dist/dashboard/assets/{linear-DBRj6V2K.js → linear-Dqv87Scf.js} +1 -1
  66. package/dist/dashboard/assets/{lt-LT-XHIRWOB4-B97DldtT.js → lt-LT-XHIRWOB4-BCCuaPbS.js} +1 -1
  67. package/dist/dashboard/assets/{lv-LV-5QDEKY6T-yrPeKaL3.js → lv-LV-5QDEKY6T-NLGi-vJ6.js} +1 -1
  68. package/dist/dashboard/assets/{min-DHVsc_O1.js → min-BbJdnc3h.js} +1 -1
  69. package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-ta1H_Vv6.js → mindmap-definition-QFDTVHPH-Dk4QySu7.js} +1 -1
  70. package/dist/dashboard/assets/{mr-IN-CRQNXWMA-b3dApjRs.js → mr-IN-CRQNXWMA-BnGDIgVN.js} +1 -1
  71. package/dist/dashboard/assets/{my-MM-5M5IBNSE-BHIBHPam.js → my-MM-5M5IBNSE-CspgYE9_.js} +1 -1
  72. package/dist/dashboard/assets/{nb-NO-T6EIAALU-MhmUUkRf.js → nb-NO-T6EIAALU-BeRPw3hu.js} +1 -1
  73. package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-lff3Vuu6.js → nl-NL-IS3SIHDZ-C-G-bljM.js} +1 -1
  74. package/dist/dashboard/assets/{nn-NO-6E72VCQL-DXvDarQa.js → nn-NO-6E72VCQL-Ct7VZY8D.js} +1 -1
  75. package/dist/dashboard/assets/{oc-FR-POXYY2M6-Ckw3bKbR.js → oc-FR-POXYY2M6-Cv5-C4Qq.js} +1 -1
  76. package/dist/dashboard/assets/{pa-IN-N4M65BXN-B2_S0arL.js → pa-IN-N4M65BXN-DAgkIThL.js} +1 -1
  77. package/dist/dashboard/assets/{percentages-BXMCSKIN-B3ROetXt.js → percentages-BXMCSKIN-vidRYabK.js} +7 -7
  78. package/dist/dashboard/assets/{pica-g7PUwtlw.js → pica-Cy-Xl-mi.js} +1 -1
  79. package/dist/dashboard/assets/{pieDiagram-DEJITSTG-CjThCCvb.js → pieDiagram-DEJITSTG-BnP4-zwd.js} +1 -1
  80. package/dist/dashboard/assets/{pl-PL-T2D74RX3-DzkRcoZK.js → pl-PL-T2D74RX3-BuJQ3HD-.js} +1 -1
  81. package/dist/dashboard/assets/{pt-BR-5N22H2LF-D41OxsmY.js → pt-BR-5N22H2LF-BbAqsvD6.js} +1 -1
  82. package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-BuClZ87f.js → pt-PT-UZXXM6DQ-DzFJedU3.js} +1 -1
  83. package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-RD4818Y7.js → quadrantDiagram-34T5L4WZ-BXN88cHy.js} +1 -1
  84. package/dist/dashboard/assets/{requirementDiagram-MS252O5E-CXJidhho.js → requirementDiagram-MS252O5E-D34hL42a.js} +1 -1
  85. package/dist/dashboard/assets/{ro-RO-JPDTUUEW-DqTdk1yt.js → ro-RO-JPDTUUEW-BV2-sOiv.js} +1 -1
  86. package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-V4DgtGOD.js → ru-RU-B4JR7IUQ-BCL4N9Ej.js} +1 -1
  87. package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-C1sycfmk.js → sankeyDiagram-XADWPNL6-0mFeok-3.js} +1 -1
  88. package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-BsRhf00C.js → sequenceDiagram-FGHM5R23-C-5nW5j6.js} +1 -1
  89. package/dist/dashboard/assets/{si-LK-N5RQ5JYF-BkjJVIKw.js → si-LK-N5RQ5JYF-CNhaw4jx.js} +1 -1
  90. package/dist/dashboard/assets/{sk-SK-C5VTKIMK-CGyzVMuS.js → sk-SK-C5VTKIMK-mHCphOXu.js} +1 -1
  91. package/dist/dashboard/assets/{sl-SI-NN7IZMDC-B_v3LIOj.js → sl-SI-NN7IZMDC--lzgHthQ.js} +1 -1
  92. package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-AHgyeSSd.js → stateDiagram-FHFEXIEX-C50iDFqe.js} +1 -1
  93. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-eW9-s0Sm.js +1 -0
  94. package/dist/dashboard/assets/{subset-shared.chunk-Ci_oaXw-.js → subset-shared.chunk-DNsjL37s.js} +1 -1
  95. package/dist/dashboard/assets/{subset-worker.chunk-CVvKFWGY.js → subset-worker.chunk-BaV3r-bl.js} +1 -1
  96. package/dist/dashboard/assets/{sv-SE-XGPEYMSR-D5t6-bQC.js → sv-SE-XGPEYMSR-ckw8jfGN.js} +1 -1
  97. package/dist/dashboard/assets/{ta-IN-2NMHFXQM-DEKtK_gX.js → ta-IN-2NMHFXQM-CSeNmVhS.js} +1 -1
  98. package/dist/dashboard/assets/{th-TH-HPSO5L25-DRcU9LZ2.js → th-TH-HPSO5L25-Cvn1sg_3.js} +1 -1
  99. package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-PBxzQfC2.js → timeline-definition-GMOUNBTQ-DRYfuqHT.js} +1 -1
  100. package/dist/dashboard/assets/{tr-TR-DEFEU3FU-CBguuduX.js → tr-TR-DEFEU3FU-CyhY22TB.js} +1 -1
  101. package/dist/dashboard/assets/{uk-UA-QMV73CPH-i0PRyM7M.js → uk-UA-QMV73CPH-BvvAEO6U.js} +1 -1
  102. package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-YAtaCt6v.js → vennDiagram-DHZGUBPP-Crril7Cj.js} +1 -1
  103. package/dist/dashboard/assets/{vi-VN-M7AON7JQ-NwV9F7AH.js → vi-VN-M7AON7JQ-c7AwSUZ8.js} +1 -1
  104. package/dist/dashboard/assets/{wardley-RL74JXVD-fgxrOw2v.js → wardley-RL74JXVD-Da5AhSWU.js} +1 -1
  105. package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-Dpq96Mxt.js → wardleyDiagram-NUSXRM2D-C4GeB_Df.js} +1 -1
  106. package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-DiPx1Q_d.js → xychartDiagram-5P7HB3ND-BPCFKXqR.js} +1 -1
  107. package/dist/dashboard/assets/{zh-CN-LNUGB5OW-DkOI6Dmv.js → zh-CN-LNUGB5OW-BvNiZwKU.js} +1 -1
  108. package/dist/dashboard/assets/{zh-HK-E62DVLB3-lIsB7f8U.js → zh-HK-E62DVLB3-CCFtoCWb.js} +1 -1
  109. package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-DbxNlWLc.js → zh-TW-RAJ6MFWO-bYBr-stu.js} +1 -1
  110. package/dist/dashboard/index.html +2 -2
  111. package/dist/index.js +511 -312
  112. package/package.json +3 -3
  113. package/dist/dashboard/assets/channel-C8dyNz3Z.js +0 -1
  114. package/dist/dashboard/assets/classDiagram-6PBFFD2Q-BAOXjBRe.js +0 -1
  115. package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-BAOXjBRe.js +0 -1
  116. package/dist/dashboard/assets/clone-Cpvwh6xu.js +0 -1
  117. package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-XVTOYBBV.js +0 -1
package/dist/index.js CHANGED
@@ -28253,8 +28253,8 @@ var require_excerpt = __commonJS({
28253
28253
  if (sep18 == null && (opts.excerpt === false || opts.excerpt == null)) {
28254
28254
  return file;
28255
28255
  }
28256
- const delimiter = typeof opts.excerpt === "string" ? opts.excerpt : sep18 || opts.delimiters[0];
28257
- const idx = file.content.indexOf(delimiter);
28256
+ const delimiter2 = typeof opts.excerpt === "string" ? opts.excerpt : sep18 || opts.delimiters[0];
28257
+ const idx = file.content.indexOf(delimiter2);
28258
28258
  if (idx !== -1) {
28259
28259
  file.excerpt = file.content.slice(0, idx);
28260
28260
  }
@@ -38750,6 +38750,27 @@ function readGlobalGitHubLogin(home) {
38750
38750
  const v = readGlobalSecretsFile(home).github?.login;
38751
38751
  return v && v.trim() ? v.trim() : null;
38752
38752
  }
38753
+ function readGlobalGitHubNeedsReconnect(home) {
38754
+ const gh = readGlobalSecretsFile(home).github;
38755
+ return !!(gh?.token && gh.token.trim() && gh.needsReconnect === true);
38756
+ }
38757
+ function setGlobalGitHubAuthValid(valid, home) {
38758
+ const secrets = readGlobalSecretsFile(home);
38759
+ const gh = secrets.github;
38760
+ if (!gh?.token || !gh.token.trim()) return;
38761
+ const current = gh.needsReconnect === true;
38762
+ const next = !valid;
38763
+ if (current === next) return;
38764
+ if (next) gh.needsReconnect = true;
38765
+ else delete gh.needsReconnect;
38766
+ const path2 = globalSecretsPath(home);
38767
+ mkdirSync27(dirname23(path2), { recursive: true });
38768
+ writeFileSync32(path2, JSON.stringify(secrets, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38769
+ try {
38770
+ chmodSync3(path2, 384);
38771
+ } catch {
38772
+ }
38773
+ }
38753
38774
  function clearGlobalGitHubToken(home) {
38754
38775
  const path2 = globalSecretsPath(home);
38755
38776
  if (!existsSync45(path2)) return;
@@ -38757,6 +38778,7 @@ function clearGlobalGitHubToken(home) {
38757
38778
  if (secrets.github) {
38758
38779
  delete secrets.github.token;
38759
38780
  delete secrets.github.login;
38781
+ delete secrets.github.needsReconnect;
38760
38782
  }
38761
38783
  writeFileSync32(path2, JSON.stringify(secrets, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38762
38784
  try {
@@ -38920,7 +38942,7 @@ var init_brain_repo = __esm({
38920
38942
 
38921
38943
  // src/lib/git-sync/credentials.ts
38922
38944
  import { accessSync, chmodSync as chmodSync4, constants, existsSync as existsSync47, unlinkSync as unlinkSync5, writeFileSync as writeFileSync34 } from "fs";
38923
- import { join as join48 } from "path";
38945
+ import { delimiter, dirname as dirname24, join as join48 } from "path";
38924
38946
  import { tmpdir as tmpdir2 } from "os";
38925
38947
  import { randomUUID as randomUUID2 } from "crypto";
38926
38948
  import { fileURLToPath as fileURLToPath6 } from "url";
@@ -38943,6 +38965,13 @@ function resolveAskpassPath() {
38943
38965
  }
38944
38966
  throw new Error("askpass.cjs not found \u2014 the dreamcontext installation may be corrupt or incomplete.");
38945
38967
  }
38968
+ function withNodeDirOnPath(currentPath) {
38969
+ const nodeDir = dirname24(process.execPath);
38970
+ const base = currentPath ?? "";
38971
+ if (!nodeDir) return base;
38972
+ if (base.split(delimiter).includes(nodeDir)) return base;
38973
+ return base ? `${nodeDir}${delimiter}${base}` : nodeDir;
38974
+ }
38946
38975
  async function withGitCredentials(token, fn) {
38947
38976
  const tmpPath = join48(tmpdir2(), `dreamcontext-askpass-${randomUUID2()}`);
38948
38977
  writeFileSync34(tmpPath, token, { mode: 384 });
@@ -38952,6 +38981,15 @@ async function withGitCredentials(token, fn) {
38952
38981
  }
38953
38982
  const env2 = {
38954
38983
  ...process.env,
38984
+ // git execs the askpass helper (`#!/usr/bin/env node`) DIRECTLY, so `node`
38985
+ // must be resolvable on PATH at that instant. The desktop app spawns the
38986
+ // dashboard server with a minimal GUI PATH (`/usr/bin:/bin:/usr/sbin:/sbin`)
38987
+ // that has NO node — git then can't launch the helper ("env: node: No such
38988
+ // file or directory" → "could not read Username … terminal prompts disabled"),
38989
+ // and that failure gets MISCLASSIFIED as an expired GitHub sign-in. Guarantee
38990
+ // the helper can find node by prepending the directory of the CURRENT node
38991
+ // binary (dreamcontext always runs under node, so process.execPath IS node).
38992
+ PATH: withNodeDirOnPath(process.env.PATH),
38955
38993
  GIT_ASKPASS: resolveAskpassPath(),
38956
38994
  DREAMCONTEXT_ASKPASS_TOKEN_FILE: tmpPath,
38957
38995
  GIT_TERMINAL_PROMPT: "0"
@@ -38974,7 +39012,7 @@ var init_credentials = __esm({
38974
39012
  });
38975
39013
 
38976
39014
  // src/lib/git-sync/sync-engine.ts
38977
- import { dirname as dirname24 } from "path";
39015
+ import { dirname as dirname25 } from "path";
38978
39016
  function syncCommitMessage(ctx) {
38979
39017
  return ctx.mode === "full-repo" ? "chore: sync project (dreamcontext)" : "chore(brain): sync";
38980
39018
  }
@@ -39010,7 +39048,7 @@ function authorFor(ctx) {
39010
39048
  async function runBrainSync(opts, depsOverride = {}) {
39011
39049
  const d = { ...defaultDeps, ...depsOverride };
39012
39050
  const contextRoot = opts.cwd;
39013
- const projectRoot = dirname24(contextRoot);
39051
+ const projectRoot = dirname25(contextRoot);
39014
39052
  const config = readSetupConfig(projectRoot);
39015
39053
  const enabledResolution = resolveBrainSyncEnabled(projectRoot, config, d.git);
39016
39054
  if (!enabledResolution.enabled) {
@@ -39413,13 +39451,123 @@ var init_sync_engine = __esm({
39413
39451
  }
39414
39452
  });
39415
39453
 
39454
+ // src/lib/git-sync/failure.ts
39455
+ function githubSlug(s) {
39456
+ const m = s.match(/github\.com[/:]([^/\s]+\/[^/\s'".]+)/i);
39457
+ return m ? m[1].replace(/\.git$/, "") : void 0;
39458
+ }
39459
+ function extractRepo(message, fallbackRepo) {
39460
+ const perm = message.match(/Permission to ([^\s]+?)(?:\.git)? denied/i);
39461
+ if (perm) return perm[1];
39462
+ const fromMsg = githubSlug(message);
39463
+ if (fromMsg) return fromMsg;
39464
+ if (fallbackRepo) return githubSlug(fallbackRepo) ?? fallbackRepo;
39465
+ return void 0;
39466
+ }
39467
+ function classifySyncError(rawMessage, repoHint) {
39468
+ const m = rawMessage || "";
39469
+ const repo = extractRepo(m, repoHint);
39470
+ const named = repo ? ` on ${repo}` : "";
39471
+ if (/non-fast-forward.*twice|rejected.*non-fast-forward|Push rejected \(non-fast-forward\) twice/i.test(m)) {
39472
+ return {
39473
+ kind: "push-rejected",
39474
+ recovery: "retry",
39475
+ repo,
39476
+ message: "The team pushed while your sync was in flight. Retry \u2014 dreamcontext will merge their changes and push again."
39477
+ };
39478
+ }
39479
+ if (/Contents\b.*write|permission to .* denied|protected branch|not authorized|remote: Permission|must have push access|403\b/i.test(m)) {
39480
+ return {
39481
+ kind: "permission",
39482
+ recovery: "check-permissions",
39483
+ repo,
39484
+ message: `Your GitHub token can't write to${named || " this repo"}. Give it Contents (read & write) access${repo ? ` on ${repo}` : ""}, then retry.`
39485
+ };
39486
+ }
39487
+ if (/no github token found|no token found for the brain/i.test(m)) {
39488
+ return {
39489
+ kind: "no-token",
39490
+ recovery: "reconnect-github",
39491
+ repo,
39492
+ message: "Cloud sync needs a GitHub account. Connect GitHub to start syncing."
39493
+ };
39494
+ }
39495
+ if (/authentication failed|could not read Username|bad credentials|invalid credentials|401\b|terminal prompts disabled|Support for password authentication/i.test(m)) {
39496
+ return {
39497
+ kind: "auth",
39498
+ recovery: "reconnect-github",
39499
+ repo,
39500
+ message: "Your GitHub sign-in expired or is invalid. Reconnect GitHub to keep syncing."
39501
+ };
39502
+ }
39503
+ if (/could ?n[o']t resolve host|could not resolve host|connection timed out|failed to connect|network is unreachable|temporary failure in name resolution|unable to access .*(?:Could not resolve|timed out|Failed to connect)|getaddrinfo|ENOTFOUND|ETIMEDOUT/i.test(m)) {
39504
+ return {
39505
+ kind: "network",
39506
+ recovery: "wait-online",
39507
+ repo,
39508
+ message: "You're offline \u2014 sync will retry automatically when you're back online. Nothing was lost."
39509
+ };
39510
+ }
39511
+ if (/unrelated histories/i.test(m)) {
39512
+ return {
39513
+ kind: "unknown",
39514
+ recovery: "manual",
39515
+ repo,
39516
+ message: "The remote contains content that did not come from this brain (e.g. a README). Attach an empty repo or reconcile the histories manually."
39517
+ };
39518
+ }
39519
+ return {
39520
+ kind: "unknown",
39521
+ recovery: "retry",
39522
+ repo,
39523
+ message: rawMessage.trim() || "Sync failed. Retry, or check your connection and GitHub access."
39524
+ };
39525
+ }
39526
+ var init_failure = __esm({
39527
+ "src/lib/git-sync/failure.ts"() {
39528
+ "use strict";
39529
+ }
39530
+ });
39531
+
39532
+ // src/lib/git-sync/auth-reconcile.ts
39533
+ function reconcileBrainSyncSuccess(action) {
39534
+ if (AUTH_OK_ACTIONS.has(action)) setGlobalGitHubAuthValid(true);
39535
+ }
39536
+ function reconcileBrainSyncFailure(rawMessage, projectRoot, repoHint) {
39537
+ const failure = classifySyncError(rawMessage, repoHint);
39538
+ if (failure.kind === "permission") {
39539
+ setGlobalGitHubAuthValid(true);
39540
+ return;
39541
+ }
39542
+ if (failure.kind !== "auth") return;
39543
+ if (resolveBrainSyncToken(projectRoot)?.via === "global") setGlobalGitHubAuthValid(false);
39544
+ }
39545
+ var AUTH_OK_ACTIONS;
39546
+ var init_auth_reconcile = __esm({
39547
+ "src/lib/git-sync/auth-reconcile.ts"() {
39548
+ "use strict";
39549
+ init_auth_store();
39550
+ init_brain_repo();
39551
+ init_failure();
39552
+ AUTH_OK_ACTIONS = /* @__PURE__ */ new Set([
39553
+ "pulled",
39554
+ "pushed",
39555
+ "noop",
39556
+ "merged",
39557
+ "blocked-scrub",
39558
+ "awaiting-agent",
39559
+ "code-conflict"
39560
+ ]);
39561
+ }
39562
+ });
39563
+
39416
39564
  // src/cli/commands/brain.ts
39417
- import { dirname as dirname25 } from "path";
39565
+ import { dirname as dirname26 } from "path";
39418
39566
  function registerBrainCommand(program2) {
39419
39567
  const brain = program2.command("brain").description("Cloud collaboration \u2014 sync the whole project (code + brain) to your GitHub origin");
39420
39568
  brain.command("status").description("Show sync mode, remote, sync state, and the resolved cloud-sync switch").action(() => {
39421
39569
  const contextRoot = ensureContextRoot();
39422
- const projectRoot = dirname25(contextRoot);
39570
+ const projectRoot = dirname26(contextRoot);
39423
39571
  const config = readSetupConfig(projectRoot);
39424
39572
  const mode = resolveMode2(config);
39425
39573
  const enabledResolution = resolveBrainSyncEnabled(projectRoot, config);
@@ -39437,7 +39585,7 @@ function registerBrainCommand(program2) {
39437
39585
  });
39438
39586
  brain.command("enable").description("Turn cloud sync ON \u2014 sync the whole project (code + brain) to your GitHub origin").action(() => {
39439
39587
  const contextRoot = ensureContextRoot();
39440
- const projectRoot = dirname25(contextRoot);
39588
+ const projectRoot = dirname26(contextRoot);
39441
39589
  const config = readSetupConfig(projectRoot);
39442
39590
  const origin = isGitRepo(projectRoot) ? getRemoteUrl(projectRoot, "origin") : null;
39443
39591
  updateSetupConfig(projectRoot, {
@@ -39453,7 +39601,7 @@ function registerBrainCommand(program2) {
39453
39601
  });
39454
39602
  brain.command("disable").description("Turn cloud sync OFF \u2014 the brain is still committed in-tree locally, never pushed").action(() => {
39455
39603
  const contextRoot = ensureContextRoot();
39456
- const projectRoot = dirname25(contextRoot);
39604
+ const projectRoot = dirname26(contextRoot);
39457
39605
  const config = readSetupConfig(projectRoot);
39458
39606
  updateSetupConfig(projectRoot, {
39459
39607
  brainRepo: { ...config?.brainRepo ?? {}, mode: "in-tree", enabled: false }
@@ -39462,7 +39610,7 @@ function registerBrainCommand(program2) {
39462
39610
  });
39463
39611
  brain.command("scrub").description("Dry-run the scrub gate against the current staged tree").action(() => {
39464
39612
  const contextRoot = ensureContextRoot();
39465
- const projectRoot = dirname25(contextRoot);
39613
+ const projectRoot = dirname26(contextRoot);
39466
39614
  const hits = scrubStagedFiles(projectRoot);
39467
39615
  const { blocks, warns } = summarizeScrub(hits);
39468
39616
  if (blocks.length === 0 && warns.length === 0) {
@@ -39494,9 +39642,11 @@ function registerBrainCommand(program2) {
39494
39642
  continue: opts.continue,
39495
39643
  resume: opts.resume
39496
39644
  });
39645
+ reconcileBrainSyncSuccess(result.action);
39497
39646
  renderBrainSyncResult(result);
39498
39647
  if (result.action === "invalid-flag" || result.action === "blocked-scrub") process.exitCode = 1;
39499
39648
  } catch (err) {
39649
+ reconcileBrainSyncFailure(err.message, dirname26(contextRoot));
39500
39650
  if (err instanceof GitSyncError) {
39501
39651
  error(err.message);
39502
39652
  } else {
@@ -39554,6 +39704,7 @@ var init_brain = __esm({
39554
39704
  init_sync_engine();
39555
39705
  init_brain_repo();
39556
39706
  init_scrub();
39707
+ init_auth_reconcile();
39557
39708
  init_git();
39558
39709
  init_git();
39559
39710
  }
@@ -39854,7 +40005,7 @@ var init_session_digest = __esm({
39854
40005
 
39855
40006
  // src/lib/recall.ts
39856
40007
  import { existsSync as existsSync49, readFileSync as readFileSync36 } from "fs";
39857
- import { join as join50, basename as basename13, dirname as dirname26, relative as relative4 } from "path";
40008
+ import { join as join50, basename as basename13, dirname as dirname27, relative as relative4 } from "path";
39858
40009
  function isFederated(doc) {
39859
40010
  return doc.federated === true;
39860
40011
  }
@@ -40129,7 +40280,7 @@ function loadSkillDocs(skillsRoot) {
40129
40280
  try {
40130
40281
  const { data, content } = readFrontmatter(file);
40131
40282
  if (data.alwaysApply === true) continue;
40132
- const slug = typeof data.name === "string" && data.name ? data.name : basename13(dirname26(file));
40283
+ const slug = typeof data.name === "string" && data.name ? data.name : basename13(dirname27(file));
40133
40284
  const title = slug;
40134
40285
  const description = typeof data.description === "string" ? data.description : "";
40135
40286
  const tags = Array.isArray(data.tags) ? data.tags.map(String) : [];
@@ -41099,7 +41250,7 @@ var init_sleep_consolidation = __esm({
41099
41250
 
41100
41251
  // src/cli/commands/sleep.ts
41101
41252
  import { existsSync as existsSync52 } from "fs";
41102
- import { join as join53, dirname as dirname27 } from "path";
41253
+ import { join as join53, dirname as dirname28 } from "path";
41103
41254
  function getSleepPath(root) {
41104
41255
  return join53(root, "state", ".sleep.json");
41105
41256
  }
@@ -41295,7 +41446,7 @@ function registerSleepCommand(program2) {
41295
41446
  const decision = consolidationDepth(state.debt, { userRequestedDeep: !!opts.deep });
41296
41447
  state.consolidation_depth = decision.depth;
41297
41448
  state.pendingMigrationNotices = [];
41298
- const projectRoot = dirname27(root);
41449
+ const projectRoot = dirname28(root);
41299
41450
  const config = readSetupConfig(projectRoot);
41300
41451
  const fromVersion = config?.setupVersion ?? "0.0.0";
41301
41452
  const migResult = runMigrations(root, fromVersion, dreamcontextVersion());
@@ -41379,22 +41530,24 @@ function registerSleepCommand(program2) {
41379
41530
  warn(`Task sync: skipped \u2014 ${err.message ?? err}`);
41380
41531
  }
41381
41532
  try {
41382
- const cfg = readSetupConfig(dirname27(root));
41533
+ const cfg = readSetupConfig(dirname28(root));
41383
41534
  if (cfg?.brainRepo?.autoSync) {
41384
41535
  const result2 = await runBrainSync({ cwd: root, mode: "auto" });
41536
+ reconcileBrainSyncSuccess(result2.action);
41385
41537
  renderBrainSyncResult(result2);
41386
41538
  if (result2.action === "awaiting-agent" || result2.action === "already-awaiting-agent") {
41387
41539
  warn("Brain sync paused on a team merge \u2014 run /dream-sync to reconcile (it will resume or continue as needed).");
41388
41540
  }
41389
- if (result2.needsTaskSync || readBrainLocal(dirname27(root)).needsTaskSync) {
41541
+ if (result2.needsTaskSync || readBrainLocal(dirname28(root)).needsTaskSync) {
41390
41542
  const backend = getTaskBackend(root);
41391
41543
  if (backend.name !== "local") {
41392
41544
  await backend.sync("both");
41393
- writeBrainLocal(dirname27(root), { needsTaskSync: false });
41545
+ writeBrainLocal(dirname28(root), { needsTaskSync: false });
41394
41546
  }
41395
41547
  }
41396
41548
  }
41397
41549
  } catch (err) {
41550
+ reconcileBrainSyncFailure(err.message ?? String(err), dirname28(root));
41398
41551
  warn(`Brain sync: skipped \u2014 ${err.message ?? err}`);
41399
41552
  }
41400
41553
  try {
@@ -41498,6 +41651,7 @@ var init_sleep = __esm({
41498
41651
  init_manifest();
41499
41652
  init_file_lock();
41500
41653
  init_sync_engine();
41654
+ init_auth_reconcile();
41501
41655
  init_brain();
41502
41656
  init_recall();
41503
41657
  init_store();
@@ -41866,7 +42020,7 @@ import {
41866
42020
  renameSync as renameSync11,
41867
42021
  mkdirSync as mkdirSync31
41868
42022
  } from "fs";
41869
- import { join as join55, dirname as dirname28, resolve as resolve12, sep as sep8 } from "path";
42023
+ import { join as join55, dirname as dirname29, resolve as resolve12, sep as sep8 } from "path";
41870
42024
  function normalizeSlug2(raw) {
41871
42025
  return raw.trim().replace(/\\/g, "/").replace(/\.md$/i, "").replace(/^\/+|\/+$/g, "");
41872
42026
  }
@@ -41959,7 +42113,7 @@ ${srcBody}
41959
42113
  const newDstContent = import_gray_matter7.default.stringify(newDstBody, newDstData);
41960
42114
  const tmpPath = dstAbsPath + ".km-tmp";
41961
42115
  try {
41962
- mkdirSync31(dirname28(tmpPath), { recursive: true });
42116
+ mkdirSync31(dirname29(tmpPath), { recursive: true });
41963
42117
  writeFileSync38(tmpPath, newDstContent, "utf-8");
41964
42118
  renameSync11(tmpPath, dstAbsPath);
41965
42119
  } catch (e) {
@@ -42518,7 +42672,7 @@ var init_objectives_store = __esm({
42518
42672
  });
42519
42673
 
42520
42674
  // src/cli/commands/tasks.ts
42521
- import { join as join58, basename as basename16, dirname as dirname29 } from "path";
42675
+ import { join as join58, basename as basename16, dirname as dirname30 } from "path";
42522
42676
  function getStateDir() {
42523
42677
  const root = ensureContextRoot();
42524
42678
  return join58(root, "state");
@@ -42811,7 +42965,7 @@ function registerTasksCommand(program2) {
42811
42965
  const description = opts.description || name;
42812
42966
  const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
42813
42967
  if (opts.person && opts.person.trim()) {
42814
- const projectRoot = dirname29(ensureContextRoot());
42968
+ const projectRoot = dirname30(ensureContextRoot());
42815
42969
  if (isMultiPerson(readSetupConfig(projectRoot))) {
42816
42970
  const resolved = await resolvePersonSlug(backend, opts.person);
42817
42971
  if ("abort" in resolved) return;
@@ -43287,7 +43441,7 @@ function registerTasksCommand(program2) {
43287
43441
  return;
43288
43442
  }
43289
43443
  if (report.skipped !== "locked") {
43290
- writeBrainLocal(dirname29(root), { needsTaskSync: false });
43444
+ writeBrainLocal(dirname30(root), { needsTaskSync: false });
43291
43445
  }
43292
43446
  if (opts.json) {
43293
43447
  console.log(JSON.stringify(report, null, 2));
@@ -43378,7 +43532,7 @@ function registerTasksCommand(program2) {
43378
43532
  }
43379
43533
  });
43380
43534
  tasks.command("sync-hooks").argument("<action>", "install | uninstall").description("Install/uninstall best-effort git sync triggers (post-commit, pre-push)").action((action) => {
43381
- const projectRoot = dirname29(ensureContextRoot());
43535
+ const projectRoot = dirname30(ensureContextRoot());
43382
43536
  if (action === "install") {
43383
43537
  const res = installTaskSyncHooks(projectRoot);
43384
43538
  if (res.noGit) {
@@ -43780,7 +43934,7 @@ var init_roadmap_model = __esm({
43780
43934
 
43781
43935
  // src/cli/commands/roadmap.ts
43782
43936
  import { mkdirSync as mkdirSync33, writeFileSync as writeFileSync39 } from "fs";
43783
- import { join as join60, dirname as dirname30 } from "path";
43937
+ import { join as join60, dirname as dirname31 } from "path";
43784
43938
  function fmtDates(o) {
43785
43939
  const parts = [];
43786
43940
  if (o.target_date) parts.push(`target ${o.target_date}`);
@@ -43835,7 +43989,7 @@ function renderRoadmapBoard(model) {
43835
43989
  }
43836
43990
  function writeRoadmapBoard(contextRoot, model) {
43837
43991
  const path2 = join60(contextRoot, "knowledge", "roadmap", "board.md");
43838
- mkdirSync33(dirname30(path2), { recursive: true });
43992
+ mkdirSync33(dirname31(path2), { recursive: true });
43839
43993
  const slipping = model.objectives.filter((o) => o.slipping === true).map((o) => o.slug);
43840
43994
  const content = [
43841
43995
  "---",
@@ -43916,7 +44070,7 @@ function registerRoadmapCommand(program2) {
43916
44070
  printBoard(model);
43917
44071
  const path2 = writeRoadmapBoard(root, model);
43918
44072
  console.log();
43919
- success(`Board written: ${path2.replace(dirname30(root) + "/", "")}`);
44073
+ success(`Board written: ${path2.replace(dirname31(root) + "/", "")}`);
43920
44074
  });
43921
44075
  const objective = roadmap.command("objective").description("Manage objectives (create/list/show/edit/delete/depend)");
43922
44076
  objective.command("create").argument("<slug>", "Kebab-case objective slug (e.g. increase-retention-20)").description("Create an objective in core/objectives/<slug>.md").requiredOption("--title <title>", "One-line outcome statement").option("--target <date>", "Target date the PO commits to (YYYY-MM-DD)").option("--depends-on <slugs>", "Comma-separated slugs this objective depends on").option("--feature <slug>", "Backing feature PRD slug (optional)").option("--metric <label>", 'Track by a Key Result metric instead of tasks (e.g. "MRR")').option("--metric-target <n>", "The metric value that means 100% done (required with --metric)").option("--metric-baseline <n>", "Where the metric started (default 0)").option("--metric-current <n>", "Current metric value (default = baseline)").option("--metric-unit <unit>", 'Metric display unit (e.g. "USD")').option("--why <text>", "Why this outcome matters (seeds the ## Why section)").action((slug, opts) => {
@@ -44615,14 +44769,14 @@ var init_generic_http = __esm({
44615
44769
  });
44616
44770
 
44617
44771
  // src/lib/lab/adapters/custom-script.ts
44618
- import { dirname as dirname31, resolve as resolve13, sep as sep9 } from "path";
44772
+ import { dirname as dirname32, resolve as resolve13, sep as sep9 } from "path";
44619
44773
  import { pathToFileURL } from "url";
44620
44774
  function scriptFilePath(manifest) {
44621
44775
  const source = manifest.source;
44622
44776
  if (!source || source.adapter !== "script") {
44623
44777
  throw new LabError("Custom-script adapter requires a `script` source.");
44624
44778
  }
44625
- const labRoot = dirname31(dirname31(manifest.path));
44779
+ const labRoot = dirname32(dirname32(manifest.path));
44626
44780
  const abs = resolve13(labRoot, source.file);
44627
44781
  if (abs !== labRoot && !abs.startsWith(labRoot + sep9)) {
44628
44782
  throw new LabError(`Script path escapes lab/: ${source.file}`);
@@ -45042,9 +45196,9 @@ var init_sync = __esm({
45042
45196
  });
45043
45197
 
45044
45198
  // src/cli/commands/lab.ts
45045
- import { dirname as dirname32 } from "path";
45199
+ import { dirname as dirname33 } from "path";
45046
45200
  function projectRootFor(contextRoot) {
45047
- return dirname32(contextRoot);
45201
+ return dirname33(contextRoot);
45048
45202
  }
45049
45203
  function handleLabError(err) {
45050
45204
  if (err instanceof LabError) {
@@ -45640,17 +45794,17 @@ import {
45640
45794
  unlinkSync as unlinkSync8,
45641
45795
  readdirSync as readdirSync12
45642
45796
  } from "fs";
45643
- import { dirname as dirname33, join as join67 } from "path";
45797
+ import { dirname as dirname34, join as join67 } from "path";
45644
45798
  import { randomBytes as randomBytes2 } from "crypto";
45645
45799
  function atomicWriteFile(path2, data) {
45646
- mkdirSync37(dirname33(path2), { recursive: true });
45800
+ mkdirSync37(dirname34(path2), { recursive: true });
45647
45801
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
45648
45802
  writeFileSync43(tmp, data, "utf8");
45649
45803
  renameSync13(tmp, path2);
45650
45804
  }
45651
45805
  function writeJsonWithBridge(jsonPath, bridgePath, jsonValue, bridgeMarkdown) {
45652
- mkdirSync37(dirname33(jsonPath), { recursive: true });
45653
- mkdirSync37(dirname33(bridgePath), { recursive: true });
45806
+ mkdirSync37(dirname34(jsonPath), { recursive: true });
45807
+ mkdirSync37(dirname34(bridgePath), { recursive: true });
45654
45808
  const jsonStr = JSON.stringify(jsonValue, null, 2) + "\n";
45655
45809
  const jsonTmp = `${jsonPath}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
45656
45810
  const bridgeTmp = `${bridgePath}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
@@ -45779,7 +45933,7 @@ function beginRun(verb, inputs) {
45779
45933
  }
45780
45934
  function appendIndex(runId, verb, status) {
45781
45935
  const path2 = MARKETING_PATHS.runsIndex();
45782
- mkdirSync37(dirname33(path2), { recursive: true });
45936
+ mkdirSync37(dirname34(path2), { recursive: true });
45783
45937
  const ts = (/* @__PURE__ */ new Date()).toISOString();
45784
45938
  const line = `- \`${ts}\` **${verb}** (${status}) \u2014 [\`${runId}\`](./${runId}.json)
45785
45939
  `;
@@ -45903,10 +46057,10 @@ import {
45903
46057
  writeFileSync as writeFileSync44,
45904
46058
  renameSync as renameSync14
45905
46059
  } from "fs";
45906
- import { dirname as dirname34 } from "path";
46060
+ import { dirname as dirname35 } from "path";
45907
46061
  import { randomBytes as randomBytes3 } from "crypto";
45908
46062
  function atomicWriteFile2(path2, data) {
45909
- mkdirSync38(dirname34(path2), { recursive: true });
46063
+ mkdirSync38(dirname35(path2), { recursive: true });
45910
46064
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes3(4).toString("hex")}`;
45911
46065
  writeFileSync44(tmp, data, "utf8");
45912
46066
  renameSync14(tmp, path2);
@@ -46251,7 +46405,7 @@ var init_setup_drift = __esm({
46251
46405
 
46252
46406
  // src/lib/asset-drift-cache.ts
46253
46407
  import { existsSync as existsSync69, readFileSync as readFileSync47, writeFileSync as writeFileSync45, mkdirSync as mkdirSync39 } from "fs";
46254
- import { join as join69, dirname as dirname35 } from "path";
46408
+ import { join as join69, dirname as dirname36 } from "path";
46255
46409
  function assetDriftCachePath(contextRoot) {
46256
46410
  return join69(contextRoot, "state", ".asset-drift.json");
46257
46411
  }
@@ -46275,7 +46429,7 @@ function readAssetDriftCache(contextRoot) {
46275
46429
  }
46276
46430
  function writeAssetDriftCache(contextRoot, cache) {
46277
46431
  const p = assetDriftCachePath(contextRoot);
46278
- mkdirSync39(dirname35(p), { recursive: true });
46432
+ mkdirSync39(dirname36(p), { recursive: true });
46279
46433
  writeFileSync45(p, JSON.stringify(cache, null, 2) + "\n", "utf-8");
46280
46434
  }
46281
46435
  function cacheConfidentlyClean(cache, cliVersion, setupVersion) {
@@ -46300,7 +46454,7 @@ var init_federation_config = __esm({
46300
46454
  });
46301
46455
 
46302
46456
  // src/lib/federation-recall.ts
46303
- import { basename as basename20, dirname as dirname36 } from "path";
46457
+ import { basename as basename20, dirname as dirname37 } from "path";
46304
46458
  function namespacedKey(vault, type, slug) {
46305
46459
  return `${vault}::${type}/${slug}`;
46306
46460
  }
@@ -46325,7 +46479,7 @@ function crossVaultRecall(query, opts) {
46325
46479
  }
46326
46480
  const isCurrent = target.current === true;
46327
46481
  if (!isCurrent) {
46328
- const projectRoot = dirname36(contextRoot);
46482
+ const projectRoot = dirname37(contextRoot);
46329
46483
  if (!isShareable(projectRoot)) continue;
46330
46484
  }
46331
46485
  const corpus = buildCorpus(contextRoot, opts.types ? { types: opts.types } : {}).filter((doc) => !isFederated(doc));
@@ -46399,7 +46553,7 @@ var init_federation_recall = __esm({
46399
46553
 
46400
46554
  // src/lib/federation-peer-summary.ts
46401
46555
  import { existsSync as existsSync70, mkdirSync as mkdirSync40, readFileSync as readFileSync48, writeFileSync as writeFileSync46 } from "fs";
46402
- import { dirname as dirname37, join as join70 } from "path";
46556
+ import { dirname as dirname38, join as join70 } from "path";
46403
46557
  function peerSummaryCachePath(contextRoot) {
46404
46558
  return join70(contextRoot, CACHE_REL_PATH2);
46405
46559
  }
@@ -46556,7 +46710,7 @@ function readPinnedTitles(peerRoot) {
46556
46710
  return Array.from(seen).sort((a, b) => a.localeCompare(b)).slice(0, MAX_PINNED);
46557
46711
  }
46558
46712
  function refreshPeerSummaries(contextRoot, home) {
46559
- const { name, target } = currentVaultTarget(dirname37(contextRoot), home);
46713
+ const { name, target } = currentVaultTarget(dirname38(contextRoot), home);
46560
46714
  const targets = resolveConnectedVaults(target, contextRoot, home).filter(
46561
46715
  (t) => t.current !== true && t.name !== name
46562
46716
  );
@@ -46576,7 +46730,7 @@ function refreshPeerSummaries(contextRoot, home) {
46576
46730
  }
46577
46731
  function writePeerSummaryCache(contextRoot, cache) {
46578
46732
  const path2 = peerSummaryCachePath(contextRoot);
46579
- mkdirSync40(dirname37(path2), { recursive: true });
46733
+ mkdirSync40(dirname38(path2), { recursive: true });
46580
46734
  writeFileSync46(path2, JSON.stringify(cache, null, 2) + "\n", "utf-8");
46581
46735
  }
46582
46736
  var import_fast_glob18, CACHE_REL_PATH2, MAX_ACTIVITY, MAX_TAGS, MAX_PINNED, WHAT_IT_IS_CHARS;
@@ -46682,6 +46836,10 @@ function attachProjectOrigin(opts) {
46682
46836
  setProjectOrigin(opts.projectRoot, remote, opts.gitModule);
46683
46837
  return { remote, fullName: `${slug.owner}/${slug.repo}` };
46684
46838
  }
46839
+ function detachProjectOrigin(projectRoot, gitModule = git_exports) {
46840
+ if (!gitModule.isGitRepo(projectRoot)) return;
46841
+ if (gitModule.getRemoteUrl(projectRoot, "origin")) gitModule.removeRemote(projectRoot, "origin");
46842
+ }
46685
46843
  var REPO_NAME_RE;
46686
46844
  var init_origin_setup = __esm({
46687
46845
  "src/lib/git-sync/origin-setup.ts"() {
@@ -46696,7 +46854,7 @@ var init_origin_setup = __esm({
46696
46854
 
46697
46855
  // src/lib/linked-repos.ts
46698
46856
  import { existsSync as existsSync71, mkdirSync as mkdirSync41, readFileSync as readFileSync49, renameSync as renameSync15, statSync as statSync10, writeFileSync as writeFileSync47 } from "fs";
46699
- import { dirname as dirname38, isAbsolute as isAbsolute2, join as join71, resolve as resolve14, sep as sep10 } from "path";
46857
+ import { dirname as dirname39, isAbsolute as isAbsolute2, join as join71, resolve as resolve14, sep as sep10 } from "path";
46700
46858
  import { homedir as homedir5 } from "os";
46701
46859
  import { randomBytes as randomBytes4 } from "crypto";
46702
46860
  function linkedReposFilePath(home = homedir5()) {
@@ -46724,7 +46882,7 @@ function readLinkedRepoRegistry(home) {
46724
46882
  }
46725
46883
  function writeLinkedRepoRegistry(repos, home) {
46726
46884
  const filePath = linkedReposFilePath(home);
46727
- mkdirSync41(dirname38(filePath), { recursive: true });
46885
+ mkdirSync41(dirname39(filePath), { recursive: true });
46728
46886
  const registry = { repos };
46729
46887
  const tmp = `${filePath}.${process.pid}.${randomBytes4(6).toString("hex")}.tmp`;
46730
46888
  writeFileSync47(tmp, JSON.stringify(registry, null, 2) + "\n", "utf-8");
@@ -46816,7 +46974,7 @@ async function cloneLinkedRepo(projectRoot, name, opts = {}) {
46816
46974
  }
46817
46975
  const base = sanitizeRepoName(slug.repo);
46818
46976
  if (!base) throw new LinkedRepoError(`Refusing to clone "${name}": no safe folder name.`);
46819
- const parent = resolve14(opts.dir ?? dirname38(projectRoot));
46977
+ const parent = resolve14(opts.dir ?? dirname39(projectRoot));
46820
46978
  const dest = join71(parent, base);
46821
46979
  if (!resolve14(dest).startsWith(resolve14(parent) + sep10)) {
46822
46980
  throw new LinkedRepoError(`Refusing to clone "${name}": destination escapes ${parent}.`);
@@ -46961,7 +47119,7 @@ var init_snapshot_budget = __esm({
46961
47119
 
46962
47120
  // src/cli/commands/snapshot.ts
46963
47121
  import { readFileSync as readFileSync50, existsSync as existsSync72, statSync as statSync11 } from "fs";
46964
- import { join as join72, basename as basename21, dirname as dirname39 } from "path";
47122
+ import { join as join72, basename as basename21, dirname as dirname40 } from "path";
46965
47123
  function extractFirstParagraph(content) {
46966
47124
  const lines = content.split("\n");
46967
47125
  const paragraphLines = [];
@@ -47082,7 +47240,7 @@ function resolveActiveTaskPath(root) {
47082
47240
  return candidates[0].path;
47083
47241
  }
47084
47242
  function getActiveProductKnowledge(root) {
47085
- const config = readSetupConfig(dirname39(root));
47243
+ const config = readSetupConfig(dirname40(root));
47086
47244
  if (!config || !Array.isArray(config.multiProduct) || config.multiProduct.length === 0) {
47087
47245
  return [];
47088
47246
  }
@@ -47138,7 +47296,7 @@ function getActiveProductKnowledge(root) {
47138
47296
  }
47139
47297
  function getVersionNudge(root) {
47140
47298
  try {
47141
- const projectRoot = dirname39(root);
47299
+ const projectRoot = dirname40(root);
47142
47300
  const cache = readVersionCache(projectRoot);
47143
47301
  if (!cache || !isCacheFresh(cache)) return "";
47144
47302
  const installedCli = dreamcontextVersion();
@@ -47174,7 +47332,7 @@ Migrations applied since last session: ${notices.join("; ")}`;
47174
47332
  }
47175
47333
  function getDriftDirective(root) {
47176
47334
  try {
47177
- const projectRoot = dirname39(root);
47335
+ const projectRoot = dirname40(root);
47178
47336
  const config = readSetupConfig(projectRoot);
47179
47337
  if (!config) return "";
47180
47338
  const cliVersion = dreamcontextVersion();
@@ -47457,7 +47615,7 @@ function generateSnapshot(rootOverride) {
47457
47615
  const CHANGELOG_TIER2 = 10;
47458
47616
  const TIER1_BODY_CHARS = 300;
47459
47617
  const TIER2_LINE_CHARS = 140;
47460
- const multiPerson = isMultiPerson(readSetupConfig(dirname39(root)));
47618
+ const multiPerson = isMultiPerson(readSetupConfig(dirname40(root)));
47461
47619
  const authorSuffix = (e) => {
47462
47620
  if (!multiPerson) return "";
47463
47621
  const authors = Array.isArray(e.authors) ? e.authors.filter((a) => typeof a === "string") : [];
@@ -47806,7 +47964,7 @@ ${pendingFederation} legacy peer digest entr${pendingFederation === 1 ? "y" : "i
47806
47964
  flush("connected-projects", { neverEvict: true });
47807
47965
  }
47808
47966
  try {
47809
- const linked = resolveLinkedRepos(dirname39(root));
47967
+ const linked = resolveLinkedRepos(dirname40(root));
47810
47968
  if (linked.length > 0) {
47811
47969
  const lines = ["## Linked repos\n"];
47812
47970
  lines.push(
@@ -48346,7 +48504,7 @@ var init_salience = __esm({
48346
48504
 
48347
48505
  // src/lib/marketing/path-guards.ts
48348
48506
  import { existsSync as existsSync74, realpathSync } from "fs";
48349
- import { basename as basename22, dirname as dirname40, resolve as resolve15, sep as sep11 } from "path";
48507
+ import { basename as basename22, dirname as dirname41, resolve as resolve15, sep as sep11 } from "path";
48350
48508
  function isMarketingEnvPath(filePath, from) {
48351
48509
  if (!filePath) return false;
48352
48510
  const root = resolveContextRoot(from);
@@ -48370,7 +48528,7 @@ function realpathOfNearestAncestor(p) {
48370
48528
  const tail = [];
48371
48529
  while (current && current !== sep11 && !existsSync74(current)) {
48372
48530
  tail.unshift(basename22(current));
48373
- current = dirname40(current);
48531
+ current = dirname41(current);
48374
48532
  }
48375
48533
  if (!current || current === sep11) return p;
48376
48534
  try {
@@ -48665,7 +48823,7 @@ If pure greeting: {"skip":true}`;
48665
48823
  // src/cli/commands/asset-drift.ts
48666
48824
  import { mkdtempSync as mkdtempSync2, rmSync as rmSync8, existsSync as existsSync75, readFileSync as readFileSync52, readdirSync as readdirSync14 } from "fs";
48667
48825
  import { tmpdir as tmpdir3 } from "os";
48668
- import { join as join73, dirname as dirname41 } from "path";
48826
+ import { join as join73, dirname as dirname42 } from "path";
48669
48827
  function walkFiles(dir, base, out) {
48670
48828
  for (const entry of readdirSync14(dir, { withFileTypes: true })) {
48671
48829
  const abs = join73(dir, entry.name);
@@ -48700,7 +48858,7 @@ async function computeUsedAssetsChanged(projectRoot, config) {
48700
48858
  }
48701
48859
  }
48702
48860
  async function runAssetDriftRefresh(contextRoot) {
48703
- const projectRoot = dirname41(contextRoot);
48861
+ const projectRoot = dirname42(contextRoot);
48704
48862
  const config = readSetupConfig(projectRoot);
48705
48863
  if (!config) return;
48706
48864
  const cliVersion = dreamcontextVersion();
@@ -48731,7 +48889,7 @@ var init_asset_drift = __esm({
48731
48889
 
48732
48890
  // src/lib/initializer-detect.ts
48733
48891
  import { existsSync as existsSync76, statSync as statSync13, readdirSync as readdirSync15, readFileSync as readFileSync53 } from "fs";
48734
- import { join as join74, dirname as dirname42, basename as basename23, extname as extname2, isAbsolute as isAbsolute3, resolve as resolve16, sep as sep12 } from "path";
48892
+ import { join as join74, dirname as dirname43, basename as basename23, extname as extname2, isAbsolute as isAbsolute3, resolve as resolve16, sep as sep12 } from "path";
48735
48893
  import { homedir as homedir6 } from "os";
48736
48894
  function isUntouchedTemplateCore(root) {
48737
48895
  try {
@@ -48927,7 +49085,7 @@ function isOwnProject(absPath, contextRoot, cwd) {
48927
49085
  if (norm2 === resolve16(cwd)) return true;
48928
49086
  if (contextRoot) {
48929
49087
  const cr = resolve16(contextRoot);
48930
- const projectRoot = dirname42(cr);
49088
+ const projectRoot = dirname43(cr);
48931
49089
  if (norm2 === cr || norm2 === projectRoot) return true;
48932
49090
  if (norm2.startsWith(cr + sep12)) return true;
48933
49091
  }
@@ -49114,7 +49272,7 @@ var init_initializer_detect = __esm({
49114
49272
 
49115
49273
  // src/lib/agent-session-map.ts
49116
49274
  import { existsSync as existsSync77, lstatSync as lstatSync2, mkdirSync as mkdirSync42, readFileSync as readFileSync54, writeFileSync as writeFileSync48, renameSync as renameSync16, readdirSync as readdirSync16, unlinkSync as unlinkSync9, statSync as statSync14 } from "fs";
49117
- import { join as join75, dirname as dirname43, basename as basename24 } from "path";
49275
+ import { join as join75, dirname as dirname44, basename as basename24 } from "path";
49118
49276
  import { randomUUID as randomUUID3 } from "crypto";
49119
49277
  function mapDir(contextRoot) {
49120
49278
  return join75(contextRoot, MAP_DIR_REL);
@@ -49148,7 +49306,7 @@ function ensureMapDir(contextRoot) {
49148
49306
  if (existsSync77(dir) && !lstatSync2(dir).isDirectory()) return null;
49149
49307
  if (!existsSync77(dir)) {
49150
49308
  try {
49151
- ensureGitignoreEntries(dirname43(contextRoot), ["_dream_context/state/.agent-session-map/"], {
49309
+ ensureGitignoreEntries(dirname44(contextRoot), ["_dream_context/state/.agent-session-map/"], {
49152
49310
  comment: "dreamcontext: machine-local agent tab \u2192 live Claude session map"
49153
49311
  });
49154
49312
  } catch {
@@ -49262,7 +49420,7 @@ var init_agent_session_map = __esm({
49262
49420
  import { readFileSync as readFileSync55, existsSync as existsSync78, statSync as statSync15 } from "fs";
49263
49421
  import { execFileSync as execFileSync8, spawn as spawn3 } from "child_process";
49264
49422
  import { get as httpGet, request as httpRequest } from "http";
49265
- import { dirname as dirname44, resolve as resolve17, join as join76, extname as extname3, basename as basename25, relative as relative5 } from "path";
49423
+ import { dirname as dirname45, resolve as resolve17, join as join76, extname as extname3, basename as basename25, relative as relative5 } from "path";
49266
49424
  function readStdin() {
49267
49425
  if (process.stdin.isTTY) return null;
49268
49426
  try {
@@ -49376,7 +49534,7 @@ function isJsTsFile(filePath) {
49376
49534
  return JS_TS_EXTENSIONS.has(extname3(filePath).toLowerCase());
49377
49535
  }
49378
49536
  function findProjectConfig(filePath) {
49379
- let dir = dirname44(resolve17(filePath));
49537
+ let dir = dirname45(resolve17(filePath));
49380
49538
  let formatter = null;
49381
49539
  let tsconfig = null;
49382
49540
  for (let i = 0; i <= MAX_WALK_LEVELS; i++) {
@@ -49400,7 +49558,7 @@ function findProjectConfig(filePath) {
49400
49558
  tsconfig = join76(dir, "tsconfig.json");
49401
49559
  }
49402
49560
  if (formatter && tsconfig) break;
49403
- const parent = dirname44(dir);
49561
+ const parent = dirname45(dir);
49404
49562
  if (parent === dir) break;
49405
49563
  dir = parent;
49406
49564
  }
@@ -49450,7 +49608,7 @@ function runFormatter(detection, filePath) {
49450
49608
  }
49451
49609
  }
49452
49610
  function runTscCheckWithConfig(filePath, tsconfigPath) {
49453
- const projectRoot = dirname44(tsconfigPath);
49611
+ const projectRoot = dirname45(tsconfigPath);
49454
49612
  let tscOutput;
49455
49613
  try {
49456
49614
  const localBin = resolveLocalBin("tsc", projectRoot);
@@ -49885,7 +50043,7 @@ function registerHookCommand(program2) {
49885
50043
  }
49886
50044
  try {
49887
50045
  if (process.env.DREAMCONTEXT_BRAIN_SYNC !== "0") {
49888
- const projectRoot = dirname44(root);
50046
+ const projectRoot = dirname45(root);
49889
50047
  const cfg = readSetupConfig(projectRoot);
49890
50048
  const enabledResolution = resolveBrainSyncEnabled(projectRoot, cfg);
49891
50049
  if (enabledResolution.enabled && cfg?.brainRepo?.mode === "full-repo" && cfg?.brainRepo?.autoSync) {
@@ -50006,7 +50164,7 @@ function registerHookCommand(program2) {
50006
50164
  }
50007
50165
  if (process.env.DREAMCONTEXT_VERSION_CHECK !== "0") {
50008
50166
  try {
50009
- const projectRoot = dirname44(root);
50167
+ const projectRoot = dirname45(root);
50010
50168
  let vcache = readVersionCache(projectRoot);
50011
50169
  if (!isCacheFresh(vcache)) {
50012
50170
  const loaded = loadCatalog();
@@ -50077,7 +50235,7 @@ function registerHookCommand(program2) {
50077
50235
  if (bumped) writeSleepState(root, state);
50078
50236
  }
50079
50237
  try {
50080
- const { target: currentTarget } = currentVaultTarget(dirname44(root));
50238
+ const { target: currentTarget } = currentVaultTarget(dirname45(root));
50081
50239
  const peerTargets = resolveConnectedVaults(currentTarget, root).filter(
50082
50240
  (t) => t.current !== true
50083
50241
  );
@@ -50304,7 +50462,7 @@ var init_hook = __esm({
50304
50462
  // src/cli/commands/doctor.ts
50305
50463
  import { existsSync as existsSync79, readFileSync as readFileSync56, readdirSync as readdirSync17, statSync as statSync16 } from "fs";
50306
50464
  import { join as join77 } from "path";
50307
- import { dirname as dirname45 } from "path";
50465
+ import { dirname as dirname46 } from "path";
50308
50466
  function stripDocumentedMentions(content) {
50309
50467
  let result = content.replace(/```[\s\S]*?```/g, "");
50310
50468
  result = result.replace(/`[^`]*`/g, "");
@@ -50539,7 +50697,7 @@ function checkLab(root) {
50539
50697
  const insights = listInsights(root);
50540
50698
  const credentialsPath2 = join77(root, "lab", "credentials.json");
50541
50699
  if (existsSync79(credentialsPath2)) {
50542
- const projectRoot = dirname45(root);
50700
+ const projectRoot = dirname46(root);
50543
50701
  const covered = gitignoreCovers(projectRoot, ["_dream_context/lab/credentials.json"]);
50544
50702
  if (!covered) {
50545
50703
  results.push({
@@ -50914,6 +51072,109 @@ var init_static = __esm({
50914
51072
  }
50915
51073
  });
50916
51074
 
51075
+ // src/server/lifecycle.ts
51076
+ function trackChild(child) {
51077
+ const kill = typeof child === "function" ? child : () => {
51078
+ try {
51079
+ child.kill();
51080
+ } catch {
51081
+ }
51082
+ };
51083
+ liveChildren.add(kill);
51084
+ return () => liveChildren.delete(kill);
51085
+ }
51086
+ function killTrackedChildren() {
51087
+ for (const kill of liveChildren) {
51088
+ try {
51089
+ kill();
51090
+ } catch {
51091
+ }
51092
+ }
51093
+ liveChildren.clear();
51094
+ }
51095
+ function startVersionDriftWatch(startupVersion, readDiskVersion, onDrift, pollMs = 3e4) {
51096
+ if (process.env.DREAMCONTEXT_DESKTOP === "1") return void 0;
51097
+ if (!startupVersion || startupVersion === "0.0.0") return void 0;
51098
+ let fired = false;
51099
+ const timer = setInterval(() => {
51100
+ let disk = "0.0.0";
51101
+ try {
51102
+ disk = readDiskVersion();
51103
+ } catch {
51104
+ return;
51105
+ }
51106
+ if (disk !== "0.0.0" && disk !== startupVersion && !fired) {
51107
+ fired = true;
51108
+ clearInterval(timer);
51109
+ onDrift(disk);
51110
+ }
51111
+ }, pollMs);
51112
+ timer.unref?.();
51113
+ return () => clearInterval(timer);
51114
+ }
51115
+ function getUpgradeReadyVersion() {
51116
+ return upgradeReadyVersion;
51117
+ }
51118
+ function startUpgradeReadyWatch(startupVersion, readDiskVersion, pollMs = 3e4) {
51119
+ if (process.env.DREAMCONTEXT_DESKTOP !== "1") return void 0;
51120
+ if (!startupVersion || startupVersion === "0.0.0") return void 0;
51121
+ upgradeReadyVersion = null;
51122
+ const timer = setInterval(() => {
51123
+ let disk = "0.0.0";
51124
+ try {
51125
+ disk = readDiskVersion();
51126
+ } catch {
51127
+ return;
51128
+ }
51129
+ if (disk !== "0.0.0" && compareVersions(disk, startupVersion) > 0) {
51130
+ upgradeReadyVersion = disk;
51131
+ clearInterval(timer);
51132
+ }
51133
+ }, pollMs);
51134
+ timer.unref?.();
51135
+ return () => clearInterval(timer);
51136
+ }
51137
+ function registerShutdownHandler(fn) {
51138
+ shutdownHandler = fn;
51139
+ }
51140
+ function requestShutdown() {
51141
+ if (!shutdownHandler) return false;
51142
+ shutdownHandler();
51143
+ return true;
51144
+ }
51145
+ function startParentDeathWatch(onParentGone) {
51146
+ if (process.env.DREAMCONTEXT_DESKTOP !== "1") return void 0;
51147
+ const envPid = Number(process.env.DREAMCONTEXT_PARENT_PID);
51148
+ const parentPid = Number.isInteger(envPid) && envPid > 1 ? envPid : process.ppid;
51149
+ if (!Number.isInteger(parentPid) || parentPid <= 1) return void 0;
51150
+ let fired = false;
51151
+ const timer = setInterval(() => {
51152
+ let gone = false;
51153
+ try {
51154
+ process.kill(parentPid, 0);
51155
+ } catch (err) {
51156
+ gone = err.code === "ESRCH";
51157
+ }
51158
+ if (gone && !fired) {
51159
+ fired = true;
51160
+ clearInterval(timer);
51161
+ onParentGone();
51162
+ }
51163
+ }, 2e3);
51164
+ timer.unref?.();
51165
+ return () => clearInterval(timer);
51166
+ }
51167
+ var liveChildren, upgradeReadyVersion, shutdownHandler;
51168
+ var init_lifecycle = __esm({
51169
+ "src/server/lifecycle.ts"() {
51170
+ "use strict";
51171
+ init_version_check();
51172
+ liveChildren = /* @__PURE__ */ new Set();
51173
+ upgradeReadyVersion = null;
51174
+ shutdownHandler = null;
51175
+ }
51176
+ });
51177
+
50917
51178
  // src/server/routes/health.ts
50918
51179
  async function handleHealthGet(_req, res, _params, contextRoot) {
50919
51180
  sendJson(res, 200, {
@@ -50922,7 +51183,11 @@ async function handleHealthGet(_req, res, _params, contextRoot) {
50922
51183
  capabilities: CAPABILITIES,
50923
51184
  // The version this PROCESS is running (not what's on disk) — the bundle
50924
51185
  // and ensure-dashboard compare it against their own to detect skew.
50925
- version: dreamcontextVersion()
51186
+ version: dreamcontextVersion(),
51187
+ // Desktop self-heal: the newer on-disk version when an upgrade landed under
51188
+ // this running server (else null). The bundle uses it to auto-relaunch the
51189
+ // app onto the new version without any manual quit/reopen.
51190
+ upgradeReady: getUpgradeReadyVersion()
50926
51191
  });
50927
51192
  }
50928
51193
  var CAPABILITIES;
@@ -50931,6 +51196,7 @@ var init_health = __esm({
50931
51196
  "use strict";
50932
51197
  init_middleware();
50933
51198
  init_manifest();
51199
+ init_lifecycle();
50934
51200
  CAPABILITIES = [
50935
51201
  "tasks.members",
50936
51202
  "tasks.delete",
@@ -50955,7 +51221,7 @@ var init_change_tracker2 = __esm({
50955
51221
  });
50956
51222
 
50957
51223
  // src/server/routes/tasks.ts
50958
- import { dirname as dirname46 } from "path";
51224
+ import { dirname as dirname47 } from "path";
50959
51225
  function toApiTask(task) {
50960
51226
  const { raw: _raw, rawBody: _rawBody, ...api } = task;
50961
51227
  return api;
@@ -51222,7 +51488,7 @@ function slugToName(slug) {
51222
51488
  return slug.split("-").map((w) => w ? w[0].toUpperCase() + w.slice(1) : w).join(" ");
51223
51489
  }
51224
51490
  function rosterMembers(contextRoot) {
51225
- const config = readSetupConfig(dirname46(contextRoot));
51491
+ const config = readSetupConfig(dirname47(contextRoot));
51226
51492
  const people = config?.people ?? [];
51227
51493
  return people.map((slug) => ({
51228
51494
  slug,
@@ -58526,7 +58792,7 @@ var require_lib4 = __commonJS({
58526
58792
 
58527
58793
  // src/server/routes/knowledge.ts
58528
58794
  import { existsSync as existsSync82, readFileSync as readFileSync58, statSync as statSync18 } from "fs";
58529
- import { join as join80, dirname as dirname47, basename as basename26, extname as extname5 } from "path";
58795
+ import { join as join80, dirname as dirname48, basename as basename26, extname as extname5 } from "path";
58530
58796
  function getKnowledgeDir2(contextRoot) {
58531
58797
  return join80(contextRoot, "knowledge");
58532
58798
  }
@@ -58642,8 +58908,8 @@ async function handleKnowledgeAssets(_req, res, params, contextRoot) {
58642
58908
  }
58643
58909
  const { content } = readFrontmatter(filePath);
58644
58910
  const embedded = parseEmbeddedFiles(content);
58645
- const vaultRoot2 = dirname47(contextRoot);
58646
- const boardDir = dirname47(filePath);
58911
+ const vaultRoot2 = dirname48(contextRoot);
58912
+ const boardDir = dirname48(filePath);
58647
58913
  const imageCount = embedded.filter((e) => IMAGE_MIME[extname5(e.path).toLowerCase()]).length;
58648
58914
  const { maxDim, quality } = compressionFor(imageCount);
58649
58915
  const files = {};
@@ -59787,9 +60053,9 @@ var init_council2 = __esm({
59787
60053
  });
59788
60054
 
59789
60055
  // src/server/routes/config.ts
59790
- import { dirname as dirname48 } from "path";
60056
+ import { dirname as dirname49 } from "path";
59791
60057
  async function handleConfigGet(_req, res, _params, contextRoot) {
59792
- const config = readSetupConfig(dirname48(contextRoot));
60058
+ const config = readSetupConfig(dirname49(contextRoot));
59793
60059
  sendJson(res, 200, { config });
59794
60060
  }
59795
60061
  async function handleConfigUpdate(req, res, _params, contextRoot) {
@@ -59873,7 +60139,7 @@ async function handleConfigUpdate(req, res, _params, contextRoot) {
59873
60139
  }
59874
60140
  picked.changelogTarget = "comments";
59875
60141
  }
59876
- const existing = readSetupConfig(dirname48(contextRoot))?.clickup ?? {};
60142
+ const existing = readSetupConfig(dirname49(contextRoot))?.clickup ?? {};
59877
60143
  patch.clickup = { ...existing, ...picked };
59878
60144
  }
59879
60145
  if (body.github !== void 0) {
@@ -59899,14 +60165,14 @@ async function handleConfigUpdate(req, res, _params, contextRoot) {
59899
60165
  }
59900
60166
  picked.changelogTarget = "comments";
59901
60167
  }
59902
- const existing = readSetupConfig(dirname48(contextRoot))?.github ?? {};
60168
+ const existing = readSetupConfig(dirname49(contextRoot))?.github ?? {};
59903
60169
  patch.github = { ...existing, ...picked };
59904
60170
  }
59905
60171
  if (patch.platforms === void 0 && patch.packs === void 0 && patch.disableNativeMemory === void 0 && patch.taskBackend === void 0 && patch.cloudTaskManagement === void 0 && patch.clickup === void 0 && patch.github === void 0 && patch.shareable === void 0) {
59906
60172
  sendError(res, 400, "no_changes", "Provide at least one of: platforms, packs, disableNativeMemory, taskBackend, cloudTaskManagement, clickup, github, shareable.");
59907
60173
  return;
59908
60174
  }
59909
- const projectRoot = dirname48(contextRoot);
60175
+ const projectRoot = dirname49(contextRoot);
59910
60176
  if (patch.taskBackend === "clickup" || patch.taskBackend === "github") {
59911
60177
  try {
59912
60178
  ensureRemoteBackendGitignore(projectRoot);
@@ -59933,11 +60199,11 @@ var init_config = __esm({
59933
60199
  });
59934
60200
 
59935
60201
  // src/server/routes/vaults.ts
59936
- import { dirname as dirname49, resolve as resolve21 } from "path";
60202
+ import { dirname as dirname50, resolve as resolve21 } from "path";
59937
60203
  import { existsSync as existsSync88 } from "fs";
59938
60204
  async function handleVaultsGet(_req, res, _params, contextRoot) {
59939
60205
  const vaults = listVaults().map((v) => ({ ...v, exists: existsSync88(resolve21(v.path)) }));
59940
- const current = contextRoot ? vaults.find((v) => resolve21(v.path) === resolve21(dirname49(contextRoot)))?.name ?? null : null;
60206
+ const current = contextRoot ? vaults.find((v) => resolve21(v.path) === resolve21(dirname50(contextRoot)))?.name ?? null : null;
59941
60207
  sendJson(res, 200, { vaults, current });
59942
60208
  }
59943
60209
  var init_vaults2 = __esm({
@@ -59949,7 +60215,7 @@ var init_vaults2 = __esm({
59949
60215
  });
59950
60216
 
59951
60217
  // src/lib/vault-discovery.ts
59952
- import { dirname as dirname50 } from "path";
60218
+ import { dirname as dirname51 } from "path";
59953
60219
  function discoverVaults(root) {
59954
60220
  const matches = import_fast_glob21.default.sync("**/_dream_context", {
59955
60221
  cwd: root,
@@ -59960,7 +60226,7 @@ function discoverVaults(root) {
59960
60226
  suppressErrors: true
59961
60227
  });
59962
60228
  const projects = /* @__PURE__ */ new Set();
59963
- for (const ctx of matches) projects.add(dirname50(ctx));
60229
+ for (const ctx of matches) projects.add(dirname51(ctx));
59964
60230
  return Array.from(projects).sort();
59965
60231
  }
59966
60232
  async function discoverVaultsAsync(root) {
@@ -59973,7 +60239,7 @@ async function discoverVaultsAsync(root) {
59973
60239
  suppressErrors: true
59974
60240
  });
59975
60241
  const projects = /* @__PURE__ */ new Set();
59976
- for (const ctx of matches) projects.add(dirname50(ctx));
60242
+ for (const ctx of matches) projects.add(dirname51(ctx));
59977
60243
  return Array.from(projects).sort();
59978
60244
  }
59979
60245
  var import_fast_glob21;
@@ -60664,11 +60930,17 @@ async function handleLauncherRelaunch(_req, res, _params, _contextRoot) {
60664
60930
  sendJson(res, 200, { ok: false, reason: "app_not_installed" });
60665
60931
  return;
60666
60932
  }
60933
+ const now = Date.now();
60934
+ if (now - lastRelaunchArmedAt < RELAUNCH_ARM_TTL_MS) {
60935
+ sendJson(res, 200, { ok: true, alreadyArmed: true });
60936
+ return;
60937
+ }
60667
60938
  try {
60668
60939
  const child = spawn4("/bin/sh", ["-c", 'sleep 2; open "$0"', appPath], {
60669
60940
  detached: true,
60670
60941
  stdio: "ignore"
60671
60942
  });
60943
+ lastRelaunchArmedAt = now;
60672
60944
  child.on("error", () => {
60673
60945
  });
60674
60946
  child.unref();
@@ -60858,7 +61130,7 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
60858
61130
  sendError(res, 500, "shareable_failed", "Failed to update sharing.");
60859
61131
  }
60860
61132
  }
60861
- var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, sleepJobsInFlight, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, AGENT_UI_DEFAULTS, SLEEPY_MODES, upgradeRun, UPGRADE_MAX_MS, addOut, addIn, dropOut, dropIn;
61133
+ var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, sleepJobsInFlight, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, AGENT_UI_DEFAULTS, SLEEPY_MODES, upgradeRun, UPGRADE_MAX_MS, lastRelaunchArmedAt, RELAUNCH_ARM_TTL_MS, addOut, addIn, dropOut, dropIn;
60862
61134
  var init_launcher = __esm({
60863
61135
  "src/server/routes/launcher.ts"() {
60864
61136
  "use strict";
@@ -60913,6 +61185,8 @@ var init_launcher = __esm({
60913
61185
  SLEEPY_MODES = /* @__PURE__ */ new Set(["idle", "sleepy", "sleeps"]);
60914
61186
  upgradeRun = null;
60915
61187
  UPGRADE_MAX_MS = 12 * 60 * 1e3;
61188
+ lastRelaunchArmedAt = 0;
61189
+ RELAUNCH_ARM_TTL_MS = 1e4;
60916
61190
  addOut = (d) => d === "in" || d === "both" ? "both" : "out";
60917
61191
  addIn = (d) => d === "out" || d === "both" ? "both" : "in";
60918
61192
  dropOut = (d) => d === "both" ? "in" : d === "in" ? "in" : null;
@@ -60921,7 +61195,7 @@ var init_launcher = __esm({
60921
61195
  });
60922
61196
 
60923
61197
  // src/server/routes/ui-settings.ts
60924
- import { dirname as dirname51, join as join86 } from "path";
61198
+ import { dirname as dirname52, join as join86 } from "path";
60925
61199
  import { existsSync as existsSync90, mkdirSync as mkdirSync45, readFileSync as readFileSync63, writeFileSync as writeFileSync51 } from "fs";
60926
61200
  function settingsPath(contextRoot) {
60927
61201
  return join86(contextRoot, BRAIN_SETTINGS_REL_PATH);
@@ -60958,7 +61232,7 @@ async function handleBrainSettingsPut(req, res, _params, contextRoot) {
60958
61232
  }
60959
61233
  try {
60960
61234
  const path2 = settingsPath(contextRoot);
60961
- mkdirSync45(dirname51(path2), { recursive: true });
61235
+ mkdirSync45(dirname52(path2), { recursive: true });
60962
61236
  writeFileSync51(path2, serialized + "\n", "utf-8");
60963
61237
  sendJson(res, 200, { ok: true });
60964
61238
  } catch (err) {
@@ -61000,7 +61274,7 @@ function makeSettingsHandlers(relPath, logTag) {
61000
61274
  }
61001
61275
  try {
61002
61276
  const path2 = pathFor(contextRoot);
61003
- mkdirSync45(dirname51(path2), { recursive: true });
61277
+ mkdirSync45(dirname52(path2), { recursive: true });
61004
61278
  writeFileSync51(path2, serialized + "\n", "utf-8");
61005
61279
  sendJson(res, 200, { ok: true });
61006
61280
  } catch (err) {
@@ -61232,7 +61506,7 @@ var init_objectives = __esm({
61232
61506
  });
61233
61507
 
61234
61508
  // src/server/routes/lab.ts
61235
- import { dirname as dirname52 } from "path";
61509
+ import { dirname as dirname53 } from "path";
61236
61510
  function toPublicTweaks(m) {
61237
61511
  return m.tweaks.map((t) => ({
61238
61512
  key: t.key,
@@ -61410,7 +61684,7 @@ async function handleLabCredentialsSet(req, res, _params, contextRoot) {
61410
61684
  return;
61411
61685
  }
61412
61686
  try {
61413
- writeCredential(dirname52(contextRoot), contextRoot, key2, value);
61687
+ writeCredential(dirname53(contextRoot), contextRoot, key2, value);
61414
61688
  sendJson(res, 200, { keys: credentialKeyStatuses(contextRoot) });
61415
61689
  } catch (err) {
61416
61690
  const message = redactSecrets(err.message ?? String(err), [value]);
@@ -61458,7 +61732,7 @@ var init_lab2 = __esm({
61458
61732
  });
61459
61733
 
61460
61734
  // src/server/routes/board.ts
61461
- import { dirname as dirname53, join as join87 } from "path";
61735
+ import { dirname as dirname54, join as join87 } from "path";
61462
61736
  import { existsSync as existsSync91, mkdirSync as mkdirSync46, readFileSync as readFileSync64, writeFileSync as writeFileSync52 } from "fs";
61463
61737
  function sharedPath(contextRoot) {
61464
61738
  return join87(contextRoot, SHARED_REL_PATH);
@@ -61494,7 +61768,7 @@ function writeBlob(path2, board) {
61494
61768
  if (Buffer.byteLength(serialized, "utf-8") > MAX_BYTES2) {
61495
61769
  return "board payload is too large.";
61496
61770
  }
61497
- mkdirSync46(dirname53(path2), { recursive: true });
61771
+ mkdirSync46(dirname54(path2), { recursive: true });
61498
61772
  writeFileSync52(path2, serialized + "\n", "utf-8");
61499
61773
  return null;
61500
61774
  }
@@ -61547,7 +61821,7 @@ var init_board = __esm({
61547
61821
 
61548
61822
  // src/server/routes/sleepy-chat.ts
61549
61823
  import { spawn as spawn5 } from "child_process";
61550
- import { dirname as dirname54, join as join88 } from "path";
61824
+ import { dirname as dirname55, join as join88 } from "path";
61551
61825
  import { existsSync as existsSync92, mkdirSync as mkdirSync47, readFileSync as readFileSync65, writeFileSync as writeFileSync53 } from "fs";
61552
61826
  import { randomUUID as randomUUID5 } from "crypto";
61553
61827
  function modelFor(tier) {
@@ -61600,7 +61874,7 @@ function writeStore(contextRoot, store) {
61600
61874
  }
61601
61875
  }
61602
61876
  function projectRootOf(contextRoot) {
61603
- return contextRoot.endsWith("_dream_context") ? dirname54(contextRoot) : contextRoot;
61877
+ return contextRoot.endsWith("_dream_context") ? dirname55(contextRoot) : contextRoot;
61604
61878
  }
61605
61879
  function handleStreamLine(run3, obj) {
61606
61880
  const type = obj.type;
@@ -61900,85 +62174,6 @@ var init_desktop = __esm({
61900
62174
  }
61901
62175
  });
61902
62176
 
61903
- // src/server/lifecycle.ts
61904
- function trackChild(child) {
61905
- const kill = typeof child === "function" ? child : () => {
61906
- try {
61907
- child.kill();
61908
- } catch {
61909
- }
61910
- };
61911
- liveChildren.add(kill);
61912
- return () => liveChildren.delete(kill);
61913
- }
61914
- function killTrackedChildren() {
61915
- for (const kill of liveChildren) {
61916
- try {
61917
- kill();
61918
- } catch {
61919
- }
61920
- }
61921
- liveChildren.clear();
61922
- }
61923
- function startVersionDriftWatch(startupVersion, readDiskVersion, onDrift, pollMs = 3e4) {
61924
- if (process.env.DREAMCONTEXT_DESKTOP === "1") return void 0;
61925
- if (!startupVersion || startupVersion === "0.0.0") return void 0;
61926
- let fired = false;
61927
- const timer = setInterval(() => {
61928
- let disk = "0.0.0";
61929
- try {
61930
- disk = readDiskVersion();
61931
- } catch {
61932
- return;
61933
- }
61934
- if (disk !== "0.0.0" && disk !== startupVersion && !fired) {
61935
- fired = true;
61936
- clearInterval(timer);
61937
- onDrift(disk);
61938
- }
61939
- }, pollMs);
61940
- timer.unref?.();
61941
- return () => clearInterval(timer);
61942
- }
61943
- function registerShutdownHandler(fn) {
61944
- shutdownHandler = fn;
61945
- }
61946
- function requestShutdown() {
61947
- if (!shutdownHandler) return false;
61948
- shutdownHandler();
61949
- return true;
61950
- }
61951
- function startParentDeathWatch(onParentGone) {
61952
- if (process.env.DREAMCONTEXT_DESKTOP !== "1") return void 0;
61953
- const envPid = Number(process.env.DREAMCONTEXT_PARENT_PID);
61954
- const parentPid = Number.isInteger(envPid) && envPid > 1 ? envPid : process.ppid;
61955
- if (!Number.isInteger(parentPid) || parentPid <= 1) return void 0;
61956
- let fired = false;
61957
- const timer = setInterval(() => {
61958
- let gone = false;
61959
- try {
61960
- process.kill(parentPid, 0);
61961
- } catch (err) {
61962
- gone = err.code === "ESRCH";
61963
- }
61964
- if (gone && !fired) {
61965
- fired = true;
61966
- clearInterval(timer);
61967
- onParentGone();
61968
- }
61969
- }, 2e3);
61970
- timer.unref?.();
61971
- return () => clearInterval(timer);
61972
- }
61973
- var liveChildren, shutdownHandler;
61974
- var init_lifecycle = __esm({
61975
- "src/server/lifecycle.ts"() {
61976
- "use strict";
61977
- liveChildren = /* @__PURE__ */ new Set();
61978
- shutdownHandler = null;
61979
- }
61980
- });
61981
-
61982
62177
  // node_modules/ws/lib/constants.js
61983
62178
  var require_constants5 = __commonJS({
61984
62179
  "node_modules/ws/lib/constants.js"(exports2, module2) {
@@ -65691,13 +65886,13 @@ var init_wrapper = __esm({
65691
65886
  import { spawn as spawn6 } from "child_process";
65692
65887
  import { randomUUID as randomUUID6 } from "crypto";
65693
65888
  import { createRequire as createRequire2 } from "module";
65694
- import { basename as basename29, dirname as dirname55, join as join89 } from "path";
65889
+ import { basename as basename29, dirname as dirname56, join as join89 } from "path";
65695
65890
  import { existsSync as existsSync93, readdirSync as readdirSync20, statSync as statSync20, chmodSync as chmodSync6, readFileSync as readFileSync66 } from "fs";
65696
65891
  import { homedir as homedir8 } from "os";
65697
65892
  function ensurePtyHelperExecutable() {
65698
65893
  try {
65699
65894
  const require2 = createRequire2(import.meta.url);
65700
- const root = dirname55(dirname55(require2.resolve("node-pty")));
65895
+ const root = dirname56(dirname56(require2.resolve("node-pty")));
65701
65896
  const candidates = [join89(root, "build", "Release", "spawn-helper")];
65702
65897
  const prebuilds = join89(root, "prebuilds");
65703
65898
  if (existsSync93(prebuilds)) {
@@ -65753,7 +65948,7 @@ function detectOnPath(cmd, timeoutMs = 8e3) {
65753
65948
  });
65754
65949
  }
65755
65950
  function projectRootOf2(contextRoot) {
65756
- return contextRoot.endsWith("_dream_context") ? dirname55(contextRoot) : contextRoot;
65951
+ return contextRoot.endsWith("_dream_context") ? dirname56(contextRoot) : contextRoot;
65757
65952
  }
65758
65953
  function resolveVaultProjectRoot(name) {
65759
65954
  if (!name) return null;
@@ -65828,11 +66023,11 @@ function pruneInstallRuns() {
65828
66023
  }
65829
66024
  }
65830
66025
  function cliPackageRoot() {
65831
- let dir = process.argv[1] ? dirname55(process.argv[1]) : "";
66026
+ let dir = process.argv[1] ? dirname56(process.argv[1]) : "";
65832
66027
  if (!dir) return null;
65833
66028
  for (let i = 0; i < 8; i++) {
65834
66029
  if (existsSync93(join89(dir, "package.json"))) return dir;
65835
- const parent = dirname55(dir);
66030
+ const parent = dirname56(dir);
65836
66031
  if (parent === dir) break;
65837
66032
  dir = parent;
65838
66033
  }
@@ -66552,7 +66747,7 @@ var init_agent_drop = __esm({
66552
66747
  });
66553
66748
 
66554
66749
  // src/server/routes/agent-sessions.ts
66555
- import { join as join91, dirname as dirname56 } from "path";
66750
+ import { join as join91, dirname as dirname57 } from "path";
66556
66751
  import { existsSync as existsSync94, mkdirSync as mkdirSync49, readFileSync as readFileSync67, writeFileSync as writeFileSync55, renameSync as renameSync17 } from "fs";
66557
66752
  import { randomUUID as randomUUID8 } from "crypto";
66558
66753
  function storePath2(contextRoot) {
@@ -66587,7 +66782,7 @@ function readRoster(contextRoot) {
66587
66782
  }
66588
66783
  function writeRoster(contextRoot, sessions) {
66589
66784
  try {
66590
- ensureGitignoreEntries(dirname56(contextRoot), ["_dream_context/state/.agent-sessions.json"], {
66785
+ ensureGitignoreEntries(dirname57(contextRoot), ["_dream_context/state/.agent-sessions.json"], {
66591
66786
  comment: "dreamcontext: machine-local agent session roster (Claude resume ids)"
66592
66787
  });
66593
66788
  } catch {
@@ -66654,9 +66849,9 @@ var init_agent_sessions = __esm({
66654
66849
  });
66655
66850
 
66656
66851
  // src/server/routes/connections.ts
66657
- import { dirname as dirname57 } from "path";
66852
+ import { dirname as dirname58 } from "path";
66658
66853
  function currentVaultName(contextRoot) {
66659
- return currentVaultTarget(dirname57(contextRoot)).name;
66854
+ return currentVaultTarget(dirname58(contextRoot)).name;
66660
66855
  }
66661
66856
  async function handleConnectionsList(_req, res, _params, contextRoot) {
66662
66857
  sendJson(res, 200, { connections: listConnections(contextRoot) });
@@ -66853,7 +67048,7 @@ var init_federation_digest = __esm({
66853
67048
  });
66854
67049
 
66855
67050
  // src/server/routes/federation.ts
66856
- import { dirname as dirname58 } from "path";
67051
+ import { dirname as dirname59 } from "path";
66857
67052
  async function handleFederationInboxGet(_req, res, _params, contextRoot) {
66858
67053
  const { entries, quarantined } = drainInbox(contextRoot);
66859
67054
  const pending = entries.map((e) => e.entry);
@@ -66865,7 +67060,7 @@ async function handleFederationInboxGet(_req, res, _params, contextRoot) {
66865
67060
  });
66866
67061
  }
66867
67062
  async function handleFederationSyncPost(_req, res, _params, contextRoot) {
66868
- const senderName = currentVaultTarget(dirname58(contextRoot)).name;
67063
+ const senderName = currentVaultTarget(dirname59(contextRoot)).name;
66869
67064
  const outbound = listConnections(contextRoot).filter(
66870
67065
  (c) => (c.direction === "out" || c.direction === "both") && c.status !== "stale"
66871
67066
  );
@@ -66913,14 +67108,14 @@ var init_federation = __esm({
66913
67108
  });
66914
67109
 
66915
67110
  // src/server/routes/packs.ts
66916
- import { dirname as dirname59 } from "path";
67111
+ import { dirname as dirname60 } from "path";
66917
67112
  async function handlePacksGet(_req, res, _params, contextRoot) {
66918
67113
  const loaded = loadCatalog();
66919
67114
  if (!loaded) {
66920
67115
  sendJson(res, 200, { packs: [], standalone: [] });
66921
67116
  return;
66922
67117
  }
66923
- const projectRoot = dirname59(contextRoot);
67118
+ const projectRoot = dirname60(contextRoot);
66924
67119
  const packs = loaded.catalog.packs.map((p) => ({ ...p, installed: isSkillInstalled(projectRoot, p.name) }));
66925
67120
  const standalone = loaded.catalog.standalone.map((s) => ({ ...s, installed: isSkillInstalled(projectRoot, s.name) }));
66926
67121
  sendJson(res, 200, { packs, standalone });
@@ -66934,7 +67129,7 @@ var init_packs = __esm({
66934
67129
  });
66935
67130
 
66936
67131
  // src/server/routes/packs-install.ts
66937
- import { dirname as dirname60 } from "path";
67132
+ import { dirname as dirname61 } from "path";
66938
67133
  function validatePackName(name, contextRoot) {
66939
67134
  if (name.includes("/") || name.includes("\0") || safeChildPath2("/x", name) === null) {
66940
67135
  return { ok: false, status: 400, code: "invalid_name", message: "Invalid pack name." };
@@ -66947,7 +67142,7 @@ function validatePackName(name, contextRoot) {
66947
67142
  if (!known) {
66948
67143
  return { ok: false, status: 404, code: "unknown_pack", message: `Pack "${name}" not found.` };
66949
67144
  }
66950
- const projectRoot = dirname60(contextRoot);
67145
+ const projectRoot = dirname61(contextRoot);
66951
67146
  const config = readSetupConfig(projectRoot);
66952
67147
  const platforms = normalizePlatforms(config?.platforms ?? []);
66953
67148
  const resolved = platforms.length > 0 ? platforms : [...DEFAULT_PLATFORMS];
@@ -67020,13 +67215,14 @@ var init_packs_install = __esm({
67020
67215
  });
67021
67216
 
67022
67217
  // src/server/routes/version-check.ts
67023
- import { dirname as dirname61 } from "path";
67218
+ import { dirname as dirname62 } from "path";
67024
67219
  async function handleVersionCheckGet(_req, res, _params, contextRoot) {
67025
67220
  try {
67026
- const projectRoot = dirname61(contextRoot);
67221
+ const projectRoot = dirname62(contextRoot);
67027
67222
  const cache = readVersionCache(projectRoot);
67028
67223
  const fresh = isCacheFresh(cache);
67029
- const installedCli = dreamcontextVersion();
67224
+ const freshCli = readDreamcontextVersionFromDisk();
67225
+ const installedCli = freshCli === "0.0.0" ? dreamcontextVersion() : freshCli;
67030
67226
  const catalogPackNames = cache?.availablePacks ?? [];
67031
67227
  const installedPacks = catalogPackNames.filter((name) => isSkillInstalled(projectRoot, name));
67032
67228
  const newPacks = fresh ? catalogPackNames.filter((name) => !installedPacks.includes(name)) : [];
@@ -67344,6 +67540,7 @@ async function handleBrainAuthDevicePoll(req, res) {
67344
67540
  login = null;
67345
67541
  }
67346
67542
  if (login) setGlobalGitHubLogin(login, authHome);
67543
+ setGlobalGitHubAuthValid(true, authHome);
67347
67544
  deviceSessions.delete(sessionId);
67348
67545
  sendJson(res, 200, { status: "authorized", login });
67349
67546
  return;
@@ -67380,6 +67577,9 @@ async function handleBrainAuthStatus(req, res) {
67380
67577
  connected: true,
67381
67578
  login: readGlobalGitHubLogin(authHome) ?? void 0,
67382
67579
  source: "global",
67580
+ // Read straight off the shared truth the sync path writes — so this chip
67581
+ // and the sidebar sync surface can never disagree about the session.
67582
+ needsReconnect: readGlobalGitHubNeedsReconnect(authHome),
67383
67583
  oauthConfigured
67384
67584
  });
67385
67585
  return;
@@ -67414,7 +67614,8 @@ async function handleBrainAuthToken(req, res) {
67414
67614
  }
67415
67615
  writeGlobalGitHubToken(token, authHome);
67416
67616
  setGlobalGitHubLogin(login, authHome);
67417
- sendJson(res, 200, { connected: true, login, source: "global" });
67617
+ setGlobalGitHubAuthValid(true, authHome);
67618
+ sendJson(res, 200, { connected: true, login, source: "global", needsReconnect: false });
67418
67619
  }
67419
67620
  async function handleBrainAuthLogout(req, res) {
67420
67621
  if (!gate(res)) return;
@@ -67483,78 +67684,8 @@ var init_team_fetch = __esm({
67483
67684
  }
67484
67685
  });
67485
67686
 
67486
- // src/lib/git-sync/failure.ts
67487
- function githubSlug(s) {
67488
- const m = s.match(/github\.com[/:]([^/\s]+\/[^/\s'".]+)/i);
67489
- return m ? m[1].replace(/\.git$/, "") : void 0;
67490
- }
67491
- function extractRepo(message, fallbackRepo) {
67492
- const perm = message.match(/Permission to ([^\s]+?)(?:\.git)? denied/i);
67493
- if (perm) return perm[1];
67494
- const fromMsg = githubSlug(message);
67495
- if (fromMsg) return fromMsg;
67496
- if (fallbackRepo) return githubSlug(fallbackRepo) ?? fallbackRepo;
67497
- return void 0;
67498
- }
67499
- function classifySyncError(rawMessage, repoHint) {
67500
- const m = rawMessage || "";
67501
- const repo = extractRepo(m, repoHint);
67502
- const named = repo ? ` on ${repo}` : "";
67503
- if (/non-fast-forward.*twice|rejected.*non-fast-forward|Push rejected \(non-fast-forward\) twice/i.test(m)) {
67504
- return {
67505
- kind: "push-rejected",
67506
- recovery: "retry",
67507
- repo,
67508
- message: "The team pushed while your sync was in flight. Retry \u2014 dreamcontext will merge their changes and push again."
67509
- };
67510
- }
67511
- if (/Contents\b.*write|permission to .* denied|protected branch|not authorized|remote: Permission|must have push access|403\b/i.test(m)) {
67512
- return {
67513
- kind: "permission",
67514
- recovery: "check-permissions",
67515
- repo,
67516
- message: `Your GitHub token can't write to${named || " this repo"}. Give it Contents (read & write) access${repo ? ` on ${repo}` : ""}, then retry.`
67517
- };
67518
- }
67519
- if (/authentication failed|could not read Username|bad credentials|invalid credentials|401\b|terminal prompts disabled|Support for password authentication|no github token found/i.test(m)) {
67520
- return {
67521
- kind: "auth",
67522
- recovery: "reconnect-github",
67523
- repo,
67524
- message: "Your GitHub sign-in expired or is invalid. Reconnect GitHub to keep syncing."
67525
- };
67526
- }
67527
- if (/could ?n[o']t resolve host|could not resolve host|connection timed out|failed to connect|network is unreachable|temporary failure in name resolution|unable to access .*(?:Could not resolve|timed out|Failed to connect)|getaddrinfo|ENOTFOUND|ETIMEDOUT/i.test(m)) {
67528
- return {
67529
- kind: "network",
67530
- recovery: "wait-online",
67531
- repo,
67532
- message: "You're offline \u2014 sync will retry automatically when you're back online. Nothing was lost."
67533
- };
67534
- }
67535
- if (/unrelated histories/i.test(m)) {
67536
- return {
67537
- kind: "unknown",
67538
- recovery: "manual",
67539
- repo,
67540
- message: "The remote contains content that did not come from this brain (e.g. a README). Attach an empty repo or reconcile the histories manually."
67541
- };
67542
- }
67543
- return {
67544
- kind: "unknown",
67545
- recovery: "retry",
67546
- repo,
67547
- message: rawMessage.trim() || "Sync failed. Retry, or check your connection and GitHub access."
67548
- };
67549
- }
67550
- var init_failure = __esm({
67551
- "src/lib/git-sync/failure.ts"() {
67552
- "use strict";
67553
- }
67554
- });
67555
-
67556
67687
  // src/server/routes/brain.ts
67557
- import { basename as basename31, dirname as dirname62 } from "path";
67688
+ import { basename as basename31, dirname as dirname63 } from "path";
67558
67689
  function mergeKindFor(contextRoot, hasMergeHead2, pendingAgentMerge) {
67559
67690
  if (hasMergeHead2) {
67560
67691
  const report = readConflictReport(contextRoot);
@@ -67574,7 +67705,7 @@ function gate2(res) {
67574
67705
  }
67575
67706
  async function handleBrainStatus(_req, res, _params, contextRoot) {
67576
67707
  if (!gate2(res)) return;
67577
- const projectRoot = dirname62(contextRoot);
67708
+ const projectRoot = dirname63(contextRoot);
67578
67709
  const config = readSetupConfig(projectRoot);
67579
67710
  const mode = resolveMode2(config);
67580
67711
  const enabled = resolveBrainSyncEnabled(projectRoot, config);
@@ -67624,7 +67755,7 @@ async function handleBrainStatus(_req, res, _params, contextRoot) {
67624
67755
  }
67625
67756
  async function handleBrainSync(req, res, _params, contextRoot) {
67626
67757
  if (!gate2(res)) return;
67627
- const projectRoot = dirname62(contextRoot);
67758
+ const projectRoot = dirname63(contextRoot);
67628
67759
  const body = await parseJsonBody(req);
67629
67760
  const mode = body?.mode === "auto" ? "auto" : "pull-only";
67630
67761
  const foreground = body?.foreground !== false;
@@ -67634,6 +67765,7 @@ async function handleBrainSync(req, res, _params, contextRoot) {
67634
67765
  async function runSyncPayload(projectRoot, contextRoot, opts) {
67635
67766
  try {
67636
67767
  const result = await runBrainSync({ cwd: contextRoot, mode: opts.mode, foreground: opts.foreground, noCheckpoint: opts.noCheckpoint });
67768
+ reconcileBrainSyncSuccess(result.action);
67637
67769
  let failure;
67638
67770
  if (result.action === "no-remote" && /token/i.test(result.note ?? "")) {
67639
67771
  failure = classifySyncError(result.note ?? "no github token found", syncRepoHint(projectRoot));
@@ -67650,6 +67782,7 @@ async function runSyncPayload(projectRoot, contextRoot, opts) {
67650
67782
  };
67651
67783
  } catch (err) {
67652
67784
  const failure = classifySyncError(err.message, syncRepoHint(projectRoot));
67785
+ reconcileBrainSyncFailure(err.message, projectRoot, syncRepoHint(projectRoot));
67653
67786
  return {
67654
67787
  action: "error",
67655
67788
  pulledUpdates: 0,
@@ -67668,7 +67801,7 @@ function syncRepoHint(projectRoot, _result) {
67668
67801
  }
67669
67802
  async function handleBrainSettingsGet2(_req, res, _params, contextRoot) {
67670
67803
  if (!gate2(res)) return;
67671
- const projectRoot = dirname62(contextRoot);
67804
+ const projectRoot = dirname63(contextRoot);
67672
67805
  const config = readSetupConfig(projectRoot);
67673
67806
  const enabled = resolveBrainSyncEnabled(projectRoot, config);
67674
67807
  const mode = resolveMode2(config);
@@ -67683,7 +67816,7 @@ async function handleBrainSettingsGet2(_req, res, _params, contextRoot) {
67683
67816
  }
67684
67817
  async function handleBrainSettingsPost(req, res, _params, contextRoot) {
67685
67818
  if (!gate2(res)) return;
67686
- const projectRoot = dirname62(contextRoot);
67819
+ const projectRoot = dirname63(contextRoot);
67687
67820
  const body = await parseJsonBody(req);
67688
67821
  if (typeof body?.enabled !== "boolean") {
67689
67822
  sendError(res, 400, "invalid_body", "enabled (boolean) is required.");
@@ -67729,6 +67862,12 @@ function enableFullRepo(projectRoot) {
67729
67862
  });
67730
67863
  ensureFullRepoGitignore(projectRoot, config?.taskBackend);
67731
67864
  }
67865
+ function disableFullRepo(projectRoot) {
67866
+ const config = readSetupConfig(projectRoot);
67867
+ updateSetupConfig(projectRoot, {
67868
+ brainRepo: { ...config?.brainRepo ?? {}, mode: "in-tree", enabled: false }
67869
+ });
67870
+ }
67732
67871
  function currentOrigin(projectRoot) {
67733
67872
  try {
67734
67873
  return isGitRepo(projectRoot) ? getRemoteUrl(projectRoot, "origin") : null;
@@ -67738,7 +67877,7 @@ function currentOrigin(projectRoot) {
67738
67877
  }
67739
67878
  async function handleBrainOriginCreate(req, res, _params, contextRoot) {
67740
67879
  if (!gate2(res)) return;
67741
- const projectRoot = dirname62(contextRoot);
67880
+ const projectRoot = dirname63(contextRoot);
67742
67881
  const body = await parseJsonBody(req);
67743
67882
  if (!resolveBrainSyncToken(projectRoot)) {
67744
67883
  sendError(res, 401, "no_token", "Sign in with GitHub before creating a repo.");
@@ -67762,7 +67901,7 @@ async function handleBrainOriginCreate(req, res, _params, contextRoot) {
67762
67901
  }
67763
67902
  async function handleBrainOriginPreview(req, res, _params, contextRoot) {
67764
67903
  if (!gate2(res)) return;
67765
- const projectRoot = dirname62(contextRoot);
67904
+ const projectRoot = dirname63(contextRoot);
67766
67905
  const body = await parseJsonBody(req);
67767
67906
  const url = typeof body?.url === "string" ? body.url.trim() : "";
67768
67907
  if (!url) {
@@ -67774,7 +67913,7 @@ async function handleBrainOriginPreview(req, res, _params, contextRoot) {
67774
67913
  }
67775
67914
  async function handleBrainOriginAttach(req, res, _params, contextRoot) {
67776
67915
  if (!gate2(res)) return;
67777
- const projectRoot = dirname62(contextRoot);
67916
+ const projectRoot = dirname63(contextRoot);
67778
67917
  const body = await parseJsonBody(req);
67779
67918
  const url = typeof body?.url === "string" ? body.url.trim() : "";
67780
67919
  if (!url) {
@@ -67803,6 +67942,62 @@ async function handleBrainOriginAttach(req, res, _params, contextRoot) {
67803
67942
  sendError(res, 400, "attach_failed", err.message);
67804
67943
  }
67805
67944
  }
67945
+ async function handleBrainOriginUpdate(req, res, _params, contextRoot) {
67946
+ if (!gate2(res)) return;
67947
+ const projectRoot = dirname63(contextRoot);
67948
+ const body = await parseJsonBody(req);
67949
+ const url = typeof body?.url === "string" ? body.url.trim() : "";
67950
+ if (!url) {
67951
+ sendError(res, 400, "invalid_body", "url is required.");
67952
+ return;
67953
+ }
67954
+ if (!resolveBrainSyncToken(projectRoot)) {
67955
+ sendError(res, 401, "no_token", "Sign in with GitHub before changing the repo.");
67956
+ return;
67957
+ }
67958
+ if (!currentOrigin(projectRoot)) {
67959
+ sendError(res, 409, "no_origin", "This project has no git origin yet \u2014 use Connect to set one.");
67960
+ return;
67961
+ }
67962
+ const preview = await previewOrigin({ projectRoot, url });
67963
+ if (!preview.reachable) {
67964
+ sendError(res, 400, "unreachable", preview.reason ?? "That repo could not be reached with your GitHub account.");
67965
+ return;
67966
+ }
67967
+ const canonical = canonicalRemote(url);
67968
+ if (!canonical) {
67969
+ sendError(res, 400, "invalid_body", "That does not look like a GitHub repo URL.");
67970
+ return;
67971
+ }
67972
+ try {
67973
+ setProjectOrigin(projectRoot, canonical);
67974
+ disableFullRepo(projectRoot);
67975
+ sendJson(res, 200, { ok: true, remote: canonical, fullName: preview.fullName, private: preview.private, syncDisabled: true });
67976
+ } catch (err) {
67977
+ sendError(res, 400, "update_failed", err.message);
67978
+ }
67979
+ }
67980
+ async function handleBrainOriginDetach(_req, res, _params, contextRoot) {
67981
+ if (!gate2(res)) return;
67982
+ const projectRoot = dirname63(contextRoot);
67983
+ let mergeInProgress = false;
67984
+ try {
67985
+ mergeInProgress = isGitRepo(projectRoot) && hasMergeHead(projectRoot);
67986
+ } catch {
67987
+ mergeInProgress = false;
67988
+ }
67989
+ if (mergeInProgress) {
67990
+ sendError(res, 409, "merge_in_progress", "Finish or resolve the in-progress merge before disconnecting the origin.");
67991
+ return;
67992
+ }
67993
+ try {
67994
+ detachProjectOrigin(projectRoot);
67995
+ disableFullRepo(projectRoot);
67996
+ sendJson(res, 200, { ok: true, remote: null });
67997
+ } catch (err) {
67998
+ sendError(res, 400, "detach_failed", err.message);
67999
+ }
68000
+ }
67806
68001
  function isSafeToGitignore(relPath) {
67807
68002
  const p = relPath.replace(/\\/g, "/").trim();
67808
68003
  if (!p) return false;
@@ -67812,7 +68007,7 @@ function isSafeToGitignore(relPath) {
67812
68007
  }
67813
68008
  async function handleBrainScrubIgnore(req, res, _params, contextRoot) {
67814
68009
  if (!gate2(res)) return;
67815
- const projectRoot = dirname62(contextRoot);
68010
+ const projectRoot = dirname63(contextRoot);
67816
68011
  const body = await parseJsonBody(req);
67817
68012
  const rawPath = typeof body?.path === "string" ? body.path.trim() : "";
67818
68013
  if (!rawPath) {
@@ -67879,6 +68074,7 @@ var init_brain2 = __esm({
67879
68074
  init_team_fetch();
67880
68075
  init_conflict_report();
67881
68076
  init_failure();
68077
+ init_auth_reconcile();
67882
68078
  init_gitignore();
67883
68079
  init_vaults();
67884
68080
  SAFE_TO_GITIGNORE = /(^|\/)([^/]*\.env(\.[^/]+)?|[^/]*\.local\.[^/]+|[^/]*secrets?[^/]*\.(json|ya?ml|toml|env)|credentials?[^/]*\.(json|ya?ml|toml|env)|[^/]*\.(pem|key|p12|pfx|keystore|jks)|id_rsa[^/]*|id_ed25519[^/]*)$/i;
@@ -67886,7 +68082,7 @@ var init_brain2 = __esm({
67886
68082
  });
67887
68083
 
67888
68084
  // src/server/routes/linked-repos.ts
67889
- import { dirname as dirname63 } from "path";
68085
+ import { dirname as dirname64 } from "path";
67890
68086
  function gate3(res) {
67891
68087
  if (!isDesktop()) {
67892
68088
  sendError(res, 403, "desktop_only", "Linked repos are only available in the desktop app.");
@@ -67896,12 +68092,12 @@ function gate3(res) {
67896
68092
  }
67897
68093
  async function handleLinkedReposList(_req, res, _params, contextRoot) {
67898
68094
  if (!gate3(res)) return;
67899
- const projectRoot = dirname63(contextRoot);
68095
+ const projectRoot = dirname64(contextRoot);
67900
68096
  sendJson(res, 200, { repos: resolveLinkedRepos(projectRoot) });
67901
68097
  }
67902
68098
  async function handleLinkedReposLink(req, res, _params, contextRoot) {
67903
68099
  if (!gate3(res)) return;
67904
- const projectRoot = dirname63(contextRoot);
68100
+ const projectRoot = dirname64(contextRoot);
67905
68101
  const body = await parseJsonBody(req);
67906
68102
  const name = typeof body?.name === "string" ? body.name.trim() : "";
67907
68103
  const path2 = typeof body?.path === "string" ? body.path.trim() : "";
@@ -67923,7 +68119,7 @@ async function handleLinkedReposLink(req, res, _params, contextRoot) {
67923
68119
  }
67924
68120
  async function handleLinkedReposClone(req, res, _params, contextRoot) {
67925
68121
  if (!gate3(res)) return;
67926
- const projectRoot = dirname63(contextRoot);
68122
+ const projectRoot = dirname64(contextRoot);
67927
68123
  const body = await parseJsonBody(req);
67928
68124
  const name = typeof body?.name === "string" ? body.name.trim() : "";
67929
68125
  const dir = typeof body?.dir === "string" && body.dir.trim() ? body.dir.trim() : void 0;
@@ -67953,7 +68149,7 @@ async function handleLinkedReposClone(req, res, _params, contextRoot) {
67953
68149
  }
67954
68150
  async function handleLinkedReposUnlink(req, res, _params, contextRoot) {
67955
68151
  if (!gate3(res)) return;
67956
- const projectRoot = dirname63(contextRoot);
68152
+ const projectRoot = dirname64(contextRoot);
67957
68153
  const body = await parseJsonBody(req);
67958
68154
  const name = typeof body?.name === "string" ? body.name.trim() : "";
67959
68155
  if (!name) {
@@ -68048,6 +68244,8 @@ function buildRouter() {
68048
68244
  router.post("/api/brain/origin/create", handleBrainOriginCreate);
68049
68245
  router.post("/api/brain/origin/preview", handleBrainOriginPreview);
68050
68246
  router.post("/api/brain/origin/attach", handleBrainOriginAttach);
68247
+ router.post("/api/brain/origin/update", handleBrainOriginUpdate);
68248
+ router.post("/api/brain/origin/detach", handleBrainOriginDetach);
68051
68249
  router.post("/api/brain/scrub/ignore", handleBrainScrubIgnore);
68052
68250
  router.get("/api/linked-repos", handleLinkedReposList);
68053
68251
  router.post("/api/linked-repos/link", handleLinkedReposLink);
@@ -68247,6 +68445,7 @@ function startDashboardServer(options2) {
68247
68445
  dreamcontext was updated to v${diskVersion} \u2014 restarting the dashboard server is required. Exiting; the next session (or \`dreamcontext dashboard\`) starts the new version.`);
68248
68446
  shutdown();
68249
68447
  });
68448
+ startUpgradeReadyWatch(dreamcontextVersion(), readDreamcontextVersionFromDisk);
68250
68449
  });
68251
68450
  });
68252
68451
  }
@@ -68476,7 +68675,7 @@ var init_trigger = __esm({
68476
68675
 
68477
68676
  // src/lib/reflection.ts
68478
68677
  import { existsSync as existsSync96, mkdirSync as mkdirSync50, writeFileSync as writeFileSync56 } from "fs";
68479
- import { join as join95, dirname as dirname64 } from "path";
68678
+ import { join as join95, dirname as dirname65 } from "path";
68480
68679
  function buildExclusionSet(corpus, excludedExtra) {
68481
68680
  const excluded = new Set(excludedExtra);
68482
68681
  for (const doc of corpus) {
@@ -68656,7 +68855,7 @@ function reflectionPath(root) {
68656
68855
  }
68657
68856
  function writeReflection(root, md) {
68658
68857
  const outPath = reflectionPath(root);
68659
- const dir = dirname64(outPath);
68858
+ const dir = dirname65(outPath);
68660
68859
  if (!existsSync96(dir)) {
68661
68860
  mkdirSync50(dir, { recursive: true });
68662
68861
  }
@@ -69733,7 +69932,7 @@ var init_env_loader = __esm({
69733
69932
 
69734
69933
  // src/lib/marketing/config.ts
69735
69934
  import { existsSync as existsSync99, readFileSync as readFileSync72, writeFileSync as writeFileSync58, mkdirSync as mkdirSync52 } from "fs";
69736
- import { dirname as dirname65 } from "path";
69935
+ import { dirname as dirname66 } from "path";
69737
69936
  function readEnvFile() {
69738
69937
  const path2 = MARKETING_PATHS.envFile();
69739
69938
  if (!existsSync99(path2)) return {};
@@ -69798,7 +69997,7 @@ function loadConfig() {
69798
69997
  }
69799
69998
  function writeConfig(cfg) {
69800
69999
  const path2 = MARKETING_PATHS.configFile();
69801
- mkdirSync52(dirname65(path2), { recursive: true });
70000
+ mkdirSync52(dirname66(path2), { recursive: true });
69802
70001
  writeFileSync58(path2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
69803
70002
  }
69804
70003
  function ensureConfigFile() {
@@ -69855,7 +70054,7 @@ REINFLUENCE_BIN= # optional override; default uses .venv
69855
70054
  import { spawn as spawn7, spawnSync as spawnSync2 } from "child_process";
69856
70055
  import { existsSync as existsSync100, mkdirSync as mkdirSync53, cpSync as cpSync3 } from "fs";
69857
70056
  import { fileURLToPath as fileURLToPath9 } from "url";
69858
- import { dirname as dirname66, resolve as resolve24, join as join98 } from "path";
70057
+ import { dirname as dirname67, resolve as resolve24, join as join98 } from "path";
69859
70058
  function findBundledReinfluence() {
69860
70059
  const candidates = [
69861
70060
  // Installed npm package: dist/<chunk>.js -> ../tools/reinfluence
@@ -69986,7 +70185,7 @@ var init_bootstrap = __esm({
69986
70185
  "use strict";
69987
70186
  init_paths2();
69988
70187
  __filename = fileURLToPath9(import.meta.url);
69989
- __dirname7 = dirname66(__filename);
70188
+ __dirname7 = dirname67(__filename);
69990
70189
  }
69991
70190
  });
69992
70191
 
@@ -70056,7 +70255,7 @@ var init_init2 = __esm({
70056
70255
 
70057
70256
  // src/lib/marketing/vision.ts
70058
70257
  import { existsSync as existsSync101, readFileSync as readFileSync73, writeFileSync as writeFileSync59 } from "fs";
70059
- import { dirname as dirname67, join as join99 } from "path";
70258
+ import { dirname as dirname68, join as join99 } from "path";
70060
70259
  function pickVisionProvider(env2 = process.env) {
70061
70260
  const oai = env2.OPENAI_VISION_API_KEY;
70062
70261
  if (oai && oai.trim().length > 0) return { provider: "openai", apiKey: oai.trim() };
@@ -70191,7 +70390,7 @@ async function runVisionPassOnPost(postJsonPath, opts = {}) {
70191
70390
  writeFileSync59(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
70192
70391
  const fs = await import("fs");
70193
70392
  fs.renameSync(tmp, postJsonPath);
70194
- const mdPath = join99(dirname67(postJsonPath), `${shortcode}.md`);
70393
+ const mdPath = join99(dirname68(postJsonPath), `${shortcode}.md`);
70195
70394
  if (existsSync101(mdPath)) {
70196
70395
  try {
70197
70396
  const md = readFileSync73(mdPath, "utf-8");
@@ -70272,7 +70471,7 @@ Example output: ["talking-head","prop-driven"]`;
70272
70471
  import { spawn as spawn8 } from "child_process";
70273
70472
  import { spawnSync as spawnSync3 } from "child_process";
70274
70473
  import { existsSync as existsSync102, mkdirSync as mkdirSync55, statfsSync } from "fs";
70275
- import { dirname as dirname68, join as join100, basename as basename32, extname as extname6 } from "path";
70474
+ import { dirname as dirname69, join as join100, basename as basename32, extname as extname6 } from "path";
70276
70475
  function which(cmd) {
70277
70476
  const r = spawnSync3(process.platform === "win32" ? "where" : "which", [cmd], { encoding: "utf8" });
70278
70477
  if (r.status === 0) return (r.stdout || "").trim().split("\n")[0] || null;
@@ -70503,7 +70702,7 @@ First seen: ${(/* @__PURE__ */ new Date()).toISOString()}
70503
70702
  }
70504
70703
  function moveAsset(src, dest) {
70505
70704
  if (!existsSync102(src)) return dest;
70506
- mkdirSync55(dirname68(dest), { recursive: true });
70705
+ mkdirSync55(dirname69(dest), { recursive: true });
70507
70706
  const fs = __require("fs");
70508
70707
  try {
70509
70708
  fs.renameSync(src, dest);
@@ -70746,7 +70945,7 @@ var init_competitor = __esm({
70746
70945
 
70747
70946
  // src/lib/marketing/meta-fetch.ts
70748
70947
  import { existsSync as existsSync104, mkdirSync as mkdirSync56, readFileSync as readFileSync74, writeFileSync as writeFileSync60, statSync as statSync23, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
70749
- import { dirname as dirname69, basename as basename33 } from "path";
70948
+ import { dirname as dirname70, basename as basename33 } from "path";
70750
70949
  import { randomUUID as randomUUID10 } from "crypto";
70751
70950
  function getQueue(accountId) {
70752
70951
  let q = writeQueues.get(accountId);
@@ -70805,7 +71004,7 @@ function readIdem(key2) {
70805
71004
  }
70806
71005
  function writeIdem(rec) {
70807
71006
  const p = idemCachePath(rec.key);
70808
- mkdirSync56(dirname69(p), { recursive: true });
71007
+ mkdirSync56(dirname70(p), { recursive: true });
70809
71008
  writeFileSync60(p, JSON.stringify(rec, null, 2) + "\n", "utf8");
70810
71009
  }
70811
71010
  function backoffMs(attempt, hintSec) {
@@ -73356,7 +73555,7 @@ var init_ad = __esm({
73356
73555
 
73357
73556
  // src/lib/marketing/launch.ts
73358
73557
  import { existsSync as existsSync111, readFileSync as readFileSync80, writeFileSync as writeFileSync62, mkdirSync as mkdirSync58, renameSync as renameSync18, readdirSync as readdirSync26 } from "fs";
73359
- import { dirname as dirname70, join as join105, basename as basename34 } from "path";
73558
+ import { dirname as dirname71, join as join105, basename as basename34 } from "path";
73360
73559
  import { randomBytes as randomBytes6 } from "crypto";
73361
73560
  function buildLaunchSummary(cohortId) {
73362
73561
  const cohort = loadCohort(cohortId);
@@ -73400,7 +73599,7 @@ function isoTs2() {
73400
73599
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
73401
73600
  }
73402
73601
  function atomicWriteFile3(path2, data) {
73403
- mkdirSync58(dirname70(path2), { recursive: true });
73602
+ mkdirSync58(dirname71(path2), { recursive: true });
73404
73603
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes6(4).toString("hex")}`;
73405
73604
  writeFileSync62(tmp, data, "utf8");
73406
73605
  renameSync18(tmp, path2);
@@ -73878,10 +74077,10 @@ import {
73878
74077
  unlinkSync as unlinkSync11,
73879
74078
  renameSync as renameSync19
73880
74079
  } from "fs";
73881
- import { dirname as dirname71, join as join106 } from "path";
74080
+ import { dirname as dirname72, join as join106 } from "path";
73882
74081
  import { randomBytes as randomBytes7 } from "crypto";
73883
74082
  function atomicWriteFile4(path2, data) {
73884
- mkdirSync59(dirname71(path2), { recursive: true });
74083
+ mkdirSync59(dirname72(path2), { recursive: true });
73885
74084
  const tmp = `${path2}.tmp.${process.pid}.${randomBytes7(4).toString("hex")}`;
73886
74085
  writeFileSync63(tmp, data, "utf8");
73887
74086
  renameSync19(tmp, path2);
@@ -74286,7 +74485,7 @@ exec dreamcontext mk hooks check-staged
74286
74485
  // src/lib/marketing/council-personas.ts
74287
74486
  import { existsSync as existsSync115, readFileSync as readFileSync84, readdirSync as readdirSync28 } from "fs";
74288
74487
  import { fileURLToPath as fileURLToPath10 } from "url";
74289
- import { join as join108, dirname as dirname72 } from "path";
74488
+ import { join as join108, dirname as dirname73 } from "path";
74290
74489
  function findPersonasDir() {
74291
74490
  const candidates = [
74292
74491
  // dev: src/lib/marketing/council-personas.ts → ../../../skill-packs/...
@@ -74344,7 +74543,7 @@ var init_council_personas = __esm({
74344
74543
  import_gray_matter8 = __toESM(require_gray_matter(), 1);
74345
74544
  __dirname_local = (() => {
74346
74545
  try {
74347
- return dirname72(fileURLToPath10(import.meta.url));
74546
+ return dirname73(fileURLToPath10(import.meta.url));
74348
74547
  } catch {
74349
74548
  return process.cwd();
74350
74549
  }
@@ -74533,7 +74732,7 @@ var init_marketing = __esm({
74533
74732
 
74534
74733
  // src/cli/commands/memory.ts
74535
74734
  import { existsSync as existsSync117, unlinkSync as unlinkSync12 } from "fs";
74536
- import { join as join109, dirname as dirname73 } from "path";
74735
+ import { join as join109, dirname as dirname74 } from "path";
74537
74736
  function collectVault(value, previous) {
74538
74737
  return [...previous, value];
74539
74738
  }
@@ -74545,7 +74744,7 @@ function parseTypes2(value) {
74545
74744
  return filtered.length > 0 ? filtered : void 0;
74546
74745
  }
74547
74746
  function recallFederated(contextRoot, query, topK, types, opts) {
74548
- const projectRoot = dirname73(contextRoot);
74747
+ const projectRoot = dirname74(contextRoot);
74549
74748
  const { target: currentTarget } = currentVaultTarget(projectRoot);
74550
74749
  const byName = /* @__PURE__ */ new Map();
74551
74750
  const add = (t) => {
@@ -74637,7 +74836,7 @@ function registerMemoryCommand(program2) {
74637
74836
  recallFederated(root, query, topK, types, opts);
74638
74837
  return;
74639
74838
  }
74640
- const projectRoot = dirname73(root);
74839
+ const projectRoot = dirname74(root);
74641
74840
  const { target: currentTarget } = currentVaultTarget(projectRoot);
74642
74841
  const connectedTargets = resolveConnectedVaults(currentTarget, root);
74643
74842
  if (connectedTargets.length > 1) {
@@ -74963,7 +75162,7 @@ var init_embed = __esm({
74963
75162
 
74964
75163
  // src/cli/commands/upgrade.ts
74965
75164
  import { execFileSync as execFileSync11 } from "child_process";
74966
- import { dirname as dirname74 } from "path";
75165
+ import { dirname as dirname75 } from "path";
74967
75166
  import { existsSync as existsSync119 } from "fs";
74968
75167
  function defaultInstaller(args) {
74969
75168
  execFileSync11("npm", args, { stdio: "inherit" });
@@ -74998,7 +75197,7 @@ function defaultAppUpdater() {
74998
75197
  }
74999
75198
  function projectRootForCache() {
75000
75199
  const contextDir = resolveContextRoot();
75001
- return contextDir ? dirname74(contextDir) : process.cwd();
75200
+ return contextDir ? dirname75(contextDir) : process.cwd();
75002
75201
  }
75003
75202
  function defaultLiveLatest() {
75004
75203
  let latest = null;
@@ -75461,7 +75660,7 @@ var init_vaults3 = __esm({
75461
75660
  });
75462
75661
 
75463
75662
  // src/cli/commands/connections.ts
75464
- import { dirname as dirname75 } from "path";
75663
+ import { dirname as dirname76 } from "path";
75465
75664
  function refreshPeerSummariesQuietly(contextRoot) {
75466
75665
  try {
75467
75666
  refreshPeerSummaries(contextRoot);
@@ -75469,7 +75668,7 @@ function refreshPeerSummariesQuietly(contextRoot) {
75469
75668
  }
75470
75669
  }
75471
75670
  function currentVaultName2(contextRoot) {
75472
- return currentVaultTarget(dirname75(contextRoot)).name;
75671
+ return currentVaultTarget(dirname76(contextRoot)).name;
75473
75672
  }
75474
75673
  function registerConnectionsCommand(program2) {
75475
75674
  program2.command("connect <vault>").description("Connect this vault to read a peer (live reference; out is a read edge)").option("-d, --direction <direction>", "Connection direction: out | in | both (out = read)", "out").option("--topics <list>", "Comma-separated topic filter (default: all topics)").action((vault, opts) => {
@@ -75763,12 +75962,12 @@ var init_people = __esm({
75763
75962
  });
75764
75963
 
75765
75964
  // src/cli/commands/config.ts
75766
- import { dirname as dirname76 } from "path";
75965
+ import { dirname as dirname77 } from "path";
75767
75966
  import { existsSync as existsSync120, readFileSync as readFileSync87, writeFileSync as writeFileSync66 } from "fs";
75768
75967
  import { join as join112 } from "path";
75769
75968
  function resolveProjectRoot() {
75770
75969
  const contextRoot = resolveContextRoot();
75771
- return contextRoot ? dirname76(contextRoot) : null;
75970
+ return contextRoot ? dirname77(contextRoot) : null;
75772
75971
  }
75773
75972
  function requireProjectRoot() {
75774
75973
  const projectRoot = resolveProjectRoot();
@@ -76636,12 +76835,12 @@ var init_feedback2 = __esm({
76636
76835
  });
76637
76836
 
76638
76837
  // src/cli/commands/migrations.ts
76639
- import { dirname as dirname77 } from "path";
76838
+ import { dirname as dirname78 } from "path";
76640
76839
  function registerMigrationsCommand(program2) {
76641
76840
  const migrations = program2.command("migrations").description("Inspect and record brain structure migrations");
76642
76841
  migrations.command("pending").description("Print pending agent task instructions for any unfinished migrations").action(() => {
76643
76842
  const root = ensureContextRoot();
76644
- const projectRoot = dirname77(root);
76843
+ const projectRoot = dirname78(root);
76645
76844
  const config = readSetupConfig(projectRoot);
76646
76845
  const fromVersion = config?.setupVersion ?? "0.0.0";
76647
76846
  const toVersion = dreamcontextVersion();
@@ -76757,9 +76956,9 @@ var init_migrations2 = __esm({
76757
76956
  });
76758
76957
 
76759
76958
  // src/cli/commands/link.ts
76760
- import { dirname as dirname78 } from "path";
76959
+ import { dirname as dirname79 } from "path";
76761
76960
  function runLinkLs() {
76762
- const projectRoot = dirname78(ensureContextRoot());
76961
+ const projectRoot = dirname79(ensureContextRoot());
76763
76962
  const repos = resolveLinkedRepos(projectRoot);
76764
76963
  if (repos.length === 0) {
76765
76964
  console.log(source_default.dim("(no linked repos)"));
@@ -76776,7 +76975,7 @@ function runLinkLs() {
76776
76975
  console.log(formatTable(["Name", "URL", "Status", "Local path"], rows, { statusCol: 2 }));
76777
76976
  }
76778
76977
  function runLinkRm(name) {
76779
- const projectRoot = dirname78(ensureContextRoot());
76978
+ const projectRoot = dirname79(ensureContextRoot());
76780
76979
  if (unlinkRepo(projectRoot, name)) {
76781
76980
  success(`Unlinked "${name}" (the local path stays registered on this machine).`);
76782
76981
  } else {
@@ -76787,7 +76986,7 @@ function runLinkRm(name) {
76787
76986
  function registerLinkCommand(program2) {
76788
76987
  const link = program2.command("link").description("Govern bare code repos: bind, clone, list, and unlink linked repos");
76789
76988
  link.command("add <name> <path>").description("Bind a local checkout of a linked repo (records name+URL shared, path machine-local)").option("--url <url>", "Explicit GitHub URL (required when the repo has no origin)").action((name, path2, opts) => {
76790
- const projectRoot = dirname78(ensureContextRoot());
76989
+ const projectRoot = dirname79(ensureContextRoot());
76791
76990
  try {
76792
76991
  const entry = linkRepo(projectRoot, name, path2, { url: opts.url });
76793
76992
  success(`Linked "${entry.name}" \u2192 ${entry.gitRemoteUrl}`);
@@ -76799,7 +76998,7 @@ function registerLinkCommand(program2) {
76799
76998
  }
76800
76999
  });
76801
77000
  link.command("clone <name>").description("Clone a MISSING linked repo (trust-gated \u2014 the URL is team-writable)").option("--dir <dir>", "Parent directory for the clone (default: alongside the project)").option("--yes", "Confirm the clone (required \u2014 see the trust warning)").action(async (name, opts) => {
76802
- const projectRoot = dirname78(ensureContextRoot());
77001
+ const projectRoot = dirname79(ensureContextRoot());
76803
77002
  warn("This URL comes from the shared config and could have been set by any teammate.");
76804
77003
  info("dreamcontext clones it over HTTPS with transport hardening (ext:: refused, options terminated).");
76805
77004
  if (!opts.yes) {