dreamcontext 0.14.1 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/assets/{BrainCanvas3D-iDGz4HV0.js → BrainCanvas3D-B1Ia2HWN.js} +1 -1
- package/dist/dashboard/assets/{_baseUniq-BKTLnguK.js → _baseUniq-B74oJzMc.js} +1 -1
- package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-WxRw8CvG.js → ar-SA-G6X2FPQ2-DOKHn365.js} +1 -1
- package/dist/dashboard/assets/{arc-CXFvfgn5.js → arc-B-uBpPoM.js} +1 -1
- package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-CgpaMT3q.js → architectureDiagram-Q4EWVU46-D2lyk9NB.js} +1 -1
- package/dist/dashboard/assets/{az-AZ-76LH7QW2-Tml7S2e-.js → az-AZ-76LH7QW2-CgyZJLLo.js} +1 -1
- package/dist/dashboard/assets/{bg-BG-XCXSNQG7-C3fv9p_Z.js → bg-BG-XCXSNQG7-BPLlwY2s.js} +1 -1
- package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-CeVR1IHD.js → blockDiagram-DXYQGD6D-Df8Y7Srr.js} +1 -1
- package/dist/dashboard/assets/{bn-BD-2XOGV67Q-qnJuYH4H.js → bn-BD-2XOGV67Q-CY-dhlzi.js} +1 -1
- package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-xcFu2zZM.js → c4Diagram-AHTNJAMY-D7TG6J6Q.js} +1 -1
- package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-4tyHbEgd.js → ca-ES-6MX7JW3Y-DFf13e9p.js} +1 -1
- package/dist/dashboard/assets/channel-CqCT8-qB.js +1 -0
- package/dist/dashboard/assets/{chunk-4BX2VUAB-J7mFJb__.js → chunk-4BX2VUAB-DCA-ERlu.js} +1 -1
- package/dist/dashboard/assets/{chunk-4TB4RGXK-DqrxE_QA.js → chunk-4TB4RGXK-Bczdxdod.js} +1 -1
- package/dist/dashboard/assets/{chunk-55IACEB6-D8eCITwq.js → chunk-55IACEB6-B3649L4a.js} +1 -1
- package/dist/dashboard/assets/{chunk-EDXVE4YY-DBzJ4Kk6.js → chunk-EDXVE4YY-Bwj1fYhG.js} +1 -1
- package/dist/dashboard/assets/{chunk-FMBD7UC4-5rx_crEA.js → chunk-FMBD7UC4-oY1KO--2.js} +1 -1
- package/dist/dashboard/assets/{chunk-OYMX7WX6-CLE6jH1t.js → chunk-OYMX7WX6-B4MPzc-c.js} +1 -1
- package/dist/dashboard/assets/{chunk-QZHKN3VN-OS-irsoP.js → chunk-QZHKN3VN-mVSSFcuA.js} +1 -1
- package/dist/dashboard/assets/{chunk-YZCP3GAM-Bucdr9No.js → chunk-YZCP3GAM-DeRyq2BY.js} +1 -1
- package/dist/dashboard/assets/classDiagram-6PBFFD2Q-C9WQPvu9.js +1 -0
- package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-C9WQPvu9.js +1 -0
- package/dist/dashboard/assets/clone-B0kf3g9o.js +1 -0
- package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-0zXaPrUS.js → cose-bilkent-S5V4N54A-BTtdOgy5.js} +1 -1
- package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-BTejWsyZ.js → cs-CZ-2BRQDIVT-BzC5Rf0R.js} +1 -1
- package/dist/dashboard/assets/{da-DK-5WZEPLOC-DWf9m3vM.js → da-DK-5WZEPLOC-gF4jrIY7.js} +1 -1
- package/dist/dashboard/assets/{dagre-KV5264BT-B_fWcb4P.js → dagre-KV5264BT-8Cpaf4My.js} +1 -1
- package/dist/dashboard/assets/{de-DE-XR44H4JA-6DFCnmxt.js → de-DE-XR44H4JA-BzHDEugW.js} +1 -1
- package/dist/dashboard/assets/{diagram-5BDNPKRD-BDjjAQT6.js → diagram-5BDNPKRD-BUa2eqbA.js} +1 -1
- package/dist/dashboard/assets/{diagram-G4DWMVQ6-CgDZIIvU.js → diagram-G4DWMVQ6-CsHVo990.js} +1 -1
- package/dist/dashboard/assets/{diagram-MMDJMWI5-OsjvtQBN.js → diagram-MMDJMWI5-CFdSOuIW.js} +1 -1
- package/dist/dashboard/assets/{diagram-TYMM5635-DOB390r8.js → diagram-TYMM5635-Cv2e3TBK.js} +1 -1
- package/dist/dashboard/assets/{el-GR-BZB4AONW-BCXqQAzU.js → el-GR-BZB4AONW-Bw-xG8H1.js} +1 -1
- package/dist/dashboard/assets/{erDiagram-SMLLAGMA-uT8z1D4S.js → erDiagram-SMLLAGMA-Di1x3Ld5.js} +1 -1
- package/dist/dashboard/assets/{es-ES-U4NZUMDT-daNwi4rl.js → es-ES-U4NZUMDT-BgdmgnEL.js} +1 -1
- package/dist/dashboard/assets/{eu-ES-A7QVB2H4-CP2B7v-S.js → eu-ES-A7QVB2H4-C_-W1jiT.js} +1 -1
- package/dist/dashboard/assets/{fa-IR-HGAKTJCU-B7fyLZjD.js → fa-IR-HGAKTJCU-D-Z42ygz.js} +1 -1
- package/dist/dashboard/assets/{fi-FI-Z5N7JZ37--r4W4BJL.js → fi-FI-Z5N7JZ37-CKqV9a_l.js} +1 -1
- package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-BAfgGiph.js → flowDiagram-DWJPFMVM-C0HsaC5L.js} +1 -1
- package/dist/dashboard/assets/{fr-FR-RHASNOE6-D_z2sz4o.js → fr-FR-RHASNOE6-DPDm5F3m.js} +1 -1
- package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-C493I8Kn.js → ganttDiagram-T4ZO3ILL-T-R79Oea.js} +1 -1
- package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-DD3Jw4hy.js → gitGraphDiagram-UUTBAWPF-DmdlPMiD.js} +1 -1
- package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-3iPIpzVQ.js → gl-ES-HMX3MZ6V-c2pDP6q3.js} +1 -1
- package/dist/dashboard/assets/{graph-CJvnKdzN.js → graph-55sHob5M.js} +1 -1
- package/dist/dashboard/assets/{he-IL-6SHJWFNN-BnseHvRA.js → he-IL-6SHJWFNN-QzeRcOiz.js} +1 -1
- package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-Cdvylq2s.js → hi-IN-IWLTKZ5I-CmRjYfDv.js} +1 -1
- package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-cYA2nqI5.js → hu-HU-A5ZG7DT2-DQS4XtgQ.js} +1 -1
- package/dist/dashboard/assets/{id-ID-SAP4L64H-ByI8qeN-.js → id-ID-SAP4L64H-D-BFw5MU.js} +1 -1
- package/dist/dashboard/assets/{index-DRgJ1sc2.js → index-C2j0AERU.js} +1 -1
- package/dist/dashboard/assets/{index-CdlG9S--.css → index-MPnw9upZ.css} +2 -2
- package/dist/dashboard/assets/{index-D85kugqO.js → index-pZP-3m96.js} +205 -205
- package/dist/dashboard/assets/{infoDiagram-42DDH7IO-BJyNzQje.js → infoDiagram-42DDH7IO-BaT4J3uc.js} +1 -1
- package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-DWwmai-U.js → ishikawaDiagram-UXIWVN3A-DsizYWBB.js} +1 -1
- package/dist/dashboard/assets/{it-IT-JPQ66NNP-Cm3-aA2z.js → it-IT-JPQ66NNP-CFAPcTjk.js} +1 -1
- package/dist/dashboard/assets/{ja-JP-DBVTYXUO-BtKUGXop.js → ja-JP-DBVTYXUO-Bzs_hBtx.js} +1 -1
- package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-CWpo_QlB.js → journeyDiagram-VCZTEJTY-B9kB5yN9.js} +1 -1
- package/dist/dashboard/assets/{kaa-6HZHGXH3-Cz-3C5qm.js → kaa-6HZHGXH3-CqRi76QS.js} +1 -1
- package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-CquppFs3.js → kab-KAB-ZGHBKWFO-wSqF6nkL.js} +1 -1
- package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-CZisoM6K.js → kanban-definition-6JOO6SKY-DasidrnL.js} +1 -1
- package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-B2l0aVOL.js → kk-KZ-P5N5QNE5-ins4bRlm.js} +1 -1
- package/dist/dashboard/assets/{km-KH-HSX4SM5Z-gnd97XjM.js → km-KH-HSX4SM5Z-BjJepDRC.js} +1 -1
- package/dist/dashboard/assets/{ko-KR-MTYHY66A-CZ7y0WRr.js → ko-KR-MTYHY66A-Cmak8rUq.js} +1 -1
- package/dist/dashboard/assets/{ku-TR-6OUDTVRD-cJLiwVTI.js → ku-TR-6OUDTVRD-Dbz6ljVD.js} +1 -1
- package/dist/dashboard/assets/{layout-ZskR1t-z.js → layout-DMQli9Le.js} +1 -1
- package/dist/dashboard/assets/{linear-nhlpqszd.js → linear-B6VVSyMW.js} +1 -1
- package/dist/dashboard/assets/{lt-LT-XHIRWOB4-Ij6EZ9jl.js → lt-LT-XHIRWOB4-CEmAxA9u.js} +1 -1
- package/dist/dashboard/assets/{lv-LV-5QDEKY6T-o1fSS6fk.js → lv-LV-5QDEKY6T-CJR-At7g.js} +1 -1
- package/dist/dashboard/assets/{min-DWO9jrZ-.js → min-CqkwiHUc.js} +1 -1
- package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-hvcnCi0m.js → mindmap-definition-QFDTVHPH-bsYCrNtj.js} +1 -1
- package/dist/dashboard/assets/{mr-IN-CRQNXWMA-CbMNXet8.js → mr-IN-CRQNXWMA-P4spwjT8.js} +1 -1
- package/dist/dashboard/assets/{my-MM-5M5IBNSE-BLZNRrAe.js → my-MM-5M5IBNSE-a1rvArEV.js} +1 -1
- package/dist/dashboard/assets/{nb-NO-T6EIAALU-B3vJdKTo.js → nb-NO-T6EIAALU-Dw_J2QCA.js} +1 -1
- package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-B6D5z-iI.js → nl-NL-IS3SIHDZ-DyJZtP9s.js} +1 -1
- package/dist/dashboard/assets/{nn-NO-6E72VCQL-5zTuWq4x.js → nn-NO-6E72VCQL-4acyfJJj.js} +1 -1
- package/dist/dashboard/assets/{oc-FR-POXYY2M6-CjWsH2WL.js → oc-FR-POXYY2M6-D8pDlGpO.js} +1 -1
- package/dist/dashboard/assets/{pa-IN-N4M65BXN-BoIcIn-E.js → pa-IN-N4M65BXN-CUXWRM9Z.js} +1 -1
- package/dist/dashboard/assets/{percentages-BXMCSKIN-F5X-Tg4w.js → percentages-BXMCSKIN-jDtw9CS_.js} +7 -7
- package/dist/dashboard/assets/{pica-kqAcDU9z.js → pica-D2k8QhiT.js} +1 -1
- package/dist/dashboard/assets/{pieDiagram-DEJITSTG-nYd2z-pn.js → pieDiagram-DEJITSTG-BY5lDpxM.js} +1 -1
- package/dist/dashboard/assets/{pl-PL-T2D74RX3-GchO6UuX.js → pl-PL-T2D74RX3-BTVl1PaU.js} +1 -1
- package/dist/dashboard/assets/{pt-BR-5N22H2LF-BUsepHJF.js → pt-BR-5N22H2LF-CRV4c2FR.js} +1 -1
- package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-CCrWB7t1.js → pt-PT-UZXXM6DQ-Ciz73XBG.js} +1 -1
- package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-CyQyFV43.js → quadrantDiagram-34T5L4WZ-CkCyPark.js} +1 -1
- package/dist/dashboard/assets/{requirementDiagram-MS252O5E-DzDNbaAz.js → requirementDiagram-MS252O5E-pkDzqMen.js} +1 -1
- package/dist/dashboard/assets/{ro-RO-JPDTUUEW-Bg8qasSV.js → ro-RO-JPDTUUEW-B5tB2ZMk.js} +1 -1
- package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-l7KGf_aH.js → ru-RU-B4JR7IUQ-CjaSKApe.js} +1 -1
- package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-t78W7pty.js → sankeyDiagram-XADWPNL6-CrziMmSl.js} +1 -1
- package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-C-A4YWsY.js → sequenceDiagram-FGHM5R23-D5zUE04i.js} +1 -1
- package/dist/dashboard/assets/{si-LK-N5RQ5JYF-Bvh5jeZQ.js → si-LK-N5RQ5JYF-QK81fzaG.js} +1 -1
- package/dist/dashboard/assets/{sk-SK-C5VTKIMK-Cw6feZYR.js → sk-SK-C5VTKIMK-TANqzQvg.js} +1 -1
- package/dist/dashboard/assets/{sl-SI-NN7IZMDC-B-NqJ9YS.js → sl-SI-NN7IZMDC-Dht86ddT.js} +1 -1
- package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-DIcQEopN.js → stateDiagram-FHFEXIEX-CcR_Q14Z.js} +1 -1
- package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-DIVPLDRd.js +1 -0
- package/dist/dashboard/assets/{subset-shared.chunk-w-9tnfIy.js → subset-shared.chunk-NAGN_SBv.js} +1 -1
- package/dist/dashboard/assets/{subset-worker.chunk-BF01ymYz.js → subset-worker.chunk-wsRwU71V.js} +1 -1
- package/dist/dashboard/assets/{sv-SE-XGPEYMSR-Ktas5ybY.js → sv-SE-XGPEYMSR-DidGUaol.js} +1 -1
- package/dist/dashboard/assets/{ta-IN-2NMHFXQM-WVntmT4J.js → ta-IN-2NMHFXQM-YZmBodpj.js} +1 -1
- package/dist/dashboard/assets/{th-TH-HPSO5L25-DP9jkhxy.js → th-TH-HPSO5L25-CVvvXQFu.js} +1 -1
- package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-CQLRxE6-.js → timeline-definition-GMOUNBTQ-B8I1QieK.js} +1 -1
- package/dist/dashboard/assets/{tr-TR-DEFEU3FU-DUBzAzD0.js → tr-TR-DEFEU3FU-DjyXDfoR.js} +1 -1
- package/dist/dashboard/assets/{uk-UA-QMV73CPH-DBIjqvxV.js → uk-UA-QMV73CPH-1pRnjZIi.js} +1 -1
- package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-ChnhJ1dN.js → vennDiagram-DHZGUBPP-BsBRDs0e.js} +1 -1
- package/dist/dashboard/assets/{vi-VN-M7AON7JQ-D47IGQ3F.js → vi-VN-M7AON7JQ-CualwmWX.js} +1 -1
- package/dist/dashboard/assets/{wardley-RL74JXVD-CnuAa4Oy.js → wardley-RL74JXVD-BP4Ewc0H.js} +1 -1
- package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-D63qjR_j.js → wardleyDiagram-NUSXRM2D-B_WTb-rg.js} +1 -1
- package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-BUdyr5Wc.js → xychartDiagram-5P7HB3ND-vB-uMt25.js} +1 -1
- package/dist/dashboard/assets/{zh-CN-LNUGB5OW-_ICN38Lj.js → zh-CN-LNUGB5OW-CQjWtZ9Y.js} +1 -1
- package/dist/dashboard/assets/{zh-HK-E62DVLB3-Bjez10pk.js → zh-HK-E62DVLB3-DzC49dFs.js} +1 -1
- package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-Do-CPv3_.js → zh-TW-RAJ6MFWO-C4KJuhZE.js} +1 -1
- package/dist/dashboard/index.html +2 -2
- package/dist/index.js +1034 -364
- package/package.json +1 -1
- package/skill/SKILL.md +4 -3
- package/skill/references/brain-sync.md +131 -0
- package/skill/references/integrations.md +7 -4
- package/skill/references/sleep.md +1 -1
- package/skill-sync/references/merge-rules.md +68 -2
- package/dist/dashboard/assets/channel-CTaS69UP.js +0 -1
- package/dist/dashboard/assets/classDiagram-6PBFFD2Q-DYWavBQh.js +0 -1
- package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-DYWavBQh.js +0 -1
- package/dist/dashboard/assets/clone-Dpdgvgqp.js +0 -1
- package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-CFAZrDsQ.js +0 -1
package/dist/index.js
CHANGED
|
@@ -17951,7 +17951,7 @@ function sanitizeGitHub(raw) {
|
|
|
17951
17951
|
function sanitizeBrainRepo(raw) {
|
|
17952
17952
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
17953
17953
|
const o = raw;
|
|
17954
|
-
const mode = o.mode === "separate" ? "separate" : "in-tree";
|
|
17954
|
+
const mode = o.mode === "separate" ? "separate" : o.mode === "full-repo" ? "full-repo" : "in-tree";
|
|
17955
17955
|
const out = { mode };
|
|
17956
17956
|
if (typeof o.enabled === "boolean") out.enabled = o.enabled;
|
|
17957
17957
|
if (typeof o.remote === "string") out.remote = o.remote;
|
|
@@ -38063,6 +38063,7 @@ __export(git_exports, {
|
|
|
38063
38063
|
attemptMerge: () => attemptMerge,
|
|
38064
38064
|
clone: () => clone,
|
|
38065
38065
|
commit: () => commit,
|
|
38066
|
+
currentBranch: () => currentBranch,
|
|
38066
38067
|
currentSha: () => currentSha,
|
|
38067
38068
|
fetch: () => fetch2,
|
|
38068
38069
|
getRemoteUrl: () => getRemoteUrl,
|
|
@@ -38134,6 +38135,14 @@ function currentSha(cwd) {
|
|
|
38134
38135
|
return null;
|
|
38135
38136
|
}
|
|
38136
38137
|
}
|
|
38138
|
+
function currentBranch(cwd) {
|
|
38139
|
+
try {
|
|
38140
|
+
const branch = run2(cwd, ["symbolic-ref", "--short", "HEAD"]).trim();
|
|
38141
|
+
return branch && branch !== "HEAD" ? branch : null;
|
|
38142
|
+
} catch {
|
|
38143
|
+
return null;
|
|
38144
|
+
}
|
|
38145
|
+
}
|
|
38137
38146
|
function addRemote(cwd, name, url) {
|
|
38138
38147
|
run2(cwd, ["remote", "add", name, url]);
|
|
38139
38148
|
}
|
|
@@ -38381,6 +38390,34 @@ function scrubStagedFiles(cwd, opts) {
|
|
|
38381
38390
|
}
|
|
38382
38391
|
return hits;
|
|
38383
38392
|
}
|
|
38393
|
+
function scrubCommitRange(cwd, range) {
|
|
38394
|
+
let raw;
|
|
38395
|
+
try {
|
|
38396
|
+
raw = execFileSync6("git", ["diff", "--name-only", "-z", range], {
|
|
38397
|
+
cwd,
|
|
38398
|
+
encoding: "utf-8",
|
|
38399
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
38400
|
+
});
|
|
38401
|
+
} catch {
|
|
38402
|
+
return [];
|
|
38403
|
+
}
|
|
38404
|
+
const files = raw.split("\0").filter((p) => p.length > 0);
|
|
38405
|
+
const hits = [];
|
|
38406
|
+
for (const relPath of files) {
|
|
38407
|
+
let content;
|
|
38408
|
+
try {
|
|
38409
|
+
content = execFileSync6("git", ["show", `HEAD:${relPath}`], {
|
|
38410
|
+
cwd,
|
|
38411
|
+
encoding: "utf-8",
|
|
38412
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
38413
|
+
});
|
|
38414
|
+
} catch {
|
|
38415
|
+
continue;
|
|
38416
|
+
}
|
|
38417
|
+
hits.push(...scrubContent(relPath, content));
|
|
38418
|
+
}
|
|
38419
|
+
return hits;
|
|
38420
|
+
}
|
|
38384
38421
|
function summarizeScrub(hits) {
|
|
38385
38422
|
return {
|
|
38386
38423
|
blocks: hits.filter((h) => h.severity === "block"),
|
|
@@ -38595,10 +38632,20 @@ function mergeMarkdownDoc(base, ours, theirs) {
|
|
|
38595
38632
|
if (result.conflictSections.length > 0) return { merged: null, needsAgent: true };
|
|
38596
38633
|
return { merged: result.merged, needsAgent: false };
|
|
38597
38634
|
}
|
|
38598
|
-
function
|
|
38635
|
+
function isCodePath(relPath, opts) {
|
|
38636
|
+
if (!opts.fullRepo) return false;
|
|
38637
|
+
const norm2 = relPath.replace(/\\/g, "/");
|
|
38638
|
+
return !norm2.startsWith("_dream_context/");
|
|
38639
|
+
}
|
|
38640
|
+
function resolveConflicts(cwd, conflicts, opts = {}) {
|
|
38599
38641
|
const resolved = [];
|
|
38600
38642
|
const deferredToAgent = [];
|
|
38643
|
+
const deferredToHuman = [];
|
|
38601
38644
|
for (const relPath of conflicts) {
|
|
38645
|
+
if (isCodePath(relPath, opts)) {
|
|
38646
|
+
deferredToHuman.push({ path: relPath, class: "code" });
|
|
38647
|
+
continue;
|
|
38648
|
+
}
|
|
38602
38649
|
const cls = classifyPath(relPath);
|
|
38603
38650
|
const { base, ours, theirs } = readOursTheirsBase(cwd, relPath);
|
|
38604
38651
|
let mergedContent = null;
|
|
@@ -38636,7 +38683,7 @@ function resolveConflicts(cwd, conflicts) {
|
|
|
38636
38683
|
resolved.push(relPath);
|
|
38637
38684
|
}
|
|
38638
38685
|
}
|
|
38639
|
-
return { resolved, deferredToAgent };
|
|
38686
|
+
return { resolved, deferredToAgent, deferredToHuman };
|
|
38640
38687
|
}
|
|
38641
38688
|
var import_gray_matter7, STATUS_ORDER2;
|
|
38642
38689
|
var init_semantic_merge = __esm({
|
|
@@ -38679,6 +38726,7 @@ function writeConflictReport(contextRoot, input2) {
|
|
|
38679
38726
|
remoteRef: input2.remoteRef,
|
|
38680
38727
|
resolvedByCli: input2.resolvedByCli,
|
|
38681
38728
|
deferred,
|
|
38729
|
+
...input2.codeConflicts && input2.codeConflicts.length > 0 ? { codeConflicts: input2.codeConflicts } : {},
|
|
38682
38730
|
status: "awaiting-agent"
|
|
38683
38731
|
};
|
|
38684
38732
|
writeFileSync33(reportPath(contextRoot), `${JSON.stringify(report, null, 2)}
|
|
@@ -39013,7 +39061,10 @@ function isOwnRepoRoot(contextRoot, gitModule = git_exports) {
|
|
|
39013
39061
|
}
|
|
39014
39062
|
}
|
|
39015
39063
|
function resolveMode2(config) {
|
|
39016
|
-
|
|
39064
|
+
const mode = config?.brainRepo?.mode;
|
|
39065
|
+
if (mode === "separate") return "separate";
|
|
39066
|
+
if (mode === "full-repo") return "full-repo";
|
|
39067
|
+
return "in-tree";
|
|
39017
39068
|
}
|
|
39018
39069
|
function resolveBrainSyncEnabled(projectRoot, config, gitModule = git_exports) {
|
|
39019
39070
|
const explicit = config?.brainRepo?.enabled;
|
|
@@ -39080,6 +39131,17 @@ function buildBrainGitignore(taskBackend) {
|
|
|
39080
39131
|
return `${lines.join("\n")}
|
|
39081
39132
|
`;
|
|
39082
39133
|
}
|
|
39134
|
+
function ensureFullRepoGitignore(projectRoot, taskBackend) {
|
|
39135
|
+
const entries = [...FULL_REPO_LOCAL_GITIGNORE_ENTRIES];
|
|
39136
|
+
if (taskBackend && taskBackend !== "local") entries.push("_dream_context/state/*.md");
|
|
39137
|
+
try {
|
|
39138
|
+
return ensureGitignoreEntries(projectRoot, entries, {
|
|
39139
|
+
comment: "dreamcontext full-repo sync \u2014 machine-local brain state + secrets (never sync)"
|
|
39140
|
+
});
|
|
39141
|
+
} catch {
|
|
39142
|
+
return [];
|
|
39143
|
+
}
|
|
39144
|
+
}
|
|
39083
39145
|
async function bootstrapBrainRepo(opts) {
|
|
39084
39146
|
const g = opts.gitModule ?? git_exports;
|
|
39085
39147
|
const scrub = opts.scrubStagedFilesImpl ?? scrubStagedFiles;
|
|
@@ -39246,7 +39308,7 @@ function releaseBrainLock(contextRoot) {
|
|
|
39246
39308
|
function currentTaskBackend(projectRoot) {
|
|
39247
39309
|
return readSetupConfig(projectRoot)?.taskBackend;
|
|
39248
39310
|
}
|
|
39249
|
-
var BRAIN_MARKER_TOPIC, BRAIN_MARKER_FILE, FALLBACK_AUTHOR, BRAIN_LOCK_STALE_MS;
|
|
39311
|
+
var BRAIN_MARKER_TOPIC, BRAIN_MARKER_FILE, FALLBACK_AUTHOR, FULL_REPO_LOCAL_GITIGNORE_ENTRIES, BRAIN_LOCK_STALE_MS;
|
|
39250
39312
|
var init_brain_repo = __esm({
|
|
39251
39313
|
"src/lib/git-sync/brain-repo.ts"() {
|
|
39252
39314
|
"use strict";
|
|
@@ -39264,15 +39326,52 @@ var init_brain_repo = __esm({
|
|
|
39264
39326
|
BRAIN_MARKER_TOPIC = "dreamcontext-brain";
|
|
39265
39327
|
BRAIN_MARKER_FILE = ".dreamcontext-brain";
|
|
39266
39328
|
FALLBACK_AUTHOR = { name: "dreamcontext-sync", email: "noreply@dreamcontext.local" };
|
|
39329
|
+
FULL_REPO_LOCAL_GITIGNORE_ENTRIES = [
|
|
39330
|
+
// Secrets — never sync, regardless of anything else.
|
|
39331
|
+
"_dream_context/state/.secrets.json",
|
|
39332
|
+
"_dream_context/**/.env",
|
|
39333
|
+
// Machine-local brain runtime — per-machine; must never sync (merge churn, or
|
|
39334
|
+
// in the sync lock's case, cross-machine lock contention).
|
|
39335
|
+
"_dream_context/state/.brain-merge/",
|
|
39336
|
+
"_dream_context/state/.brain-local.json",
|
|
39337
|
+
"_dream_context/state/.sleep.json",
|
|
39338
|
+
"_dream_context/state/.sleep-history.json",
|
|
39339
|
+
"_dream_context/state/.agent-sessions.json",
|
|
39340
|
+
"_dream_context/state/.agent-session-map/",
|
|
39341
|
+
"_dream_context/state/.session-digests/",
|
|
39342
|
+
"_dream_context/state/.conflicts/",
|
|
39343
|
+
"_dream_context/state/.version-check.json",
|
|
39344
|
+
"_dream_context/state/.auto-upgrade.json",
|
|
39345
|
+
"_dream_context/state/.lab-prefs.json",
|
|
39346
|
+
"_dream_context/state/.tasks-sync.lock",
|
|
39347
|
+
"_dream_context/state/.tasks-sync.json",
|
|
39348
|
+
"_dream_context/state/.tasks-queue.json",
|
|
39349
|
+
"_dream_context/tmp/",
|
|
39350
|
+
// Lab analytics credentials — the example (key names only) still syncs.
|
|
39351
|
+
"_dream_context/lab/credentials.json",
|
|
39352
|
+
"_dream_context/lab/credentials.*",
|
|
39353
|
+
"!_dream_context/lab/credentials.example.json"
|
|
39354
|
+
];
|
|
39267
39355
|
BRAIN_LOCK_STALE_MS = 5 * 6e4;
|
|
39268
39356
|
}
|
|
39269
39357
|
});
|
|
39270
39358
|
|
|
39271
39359
|
// src/lib/git-sync/sync-engine.ts
|
|
39272
39360
|
import { dirname as dirname25 } from "path";
|
|
39361
|
+
function syncCommitMessage(ctx) {
|
|
39362
|
+
return ctx.mode === "full-repo" ? "chore: sync project (dreamcontext)" : "chore(brain): sync";
|
|
39363
|
+
}
|
|
39364
|
+
function autoCheckpointMessage(ctx) {
|
|
39365
|
+
return ctx.mode === "full-repo" ? "chore: checkpoint local edits before team merge (dreamcontext)" : "chore(brain): auto-checkpoint local edits before team merge";
|
|
39366
|
+
}
|
|
39273
39367
|
function isBlockingScrub(scrub, strict) {
|
|
39274
39368
|
return scrub.blocks.length > 0 || strict && scrub.warns.length > 0;
|
|
39275
39369
|
}
|
|
39370
|
+
function codeConflictNote(paths) {
|
|
39371
|
+
const first = paths[0] ?? "a code file";
|
|
39372
|
+
const more = paths.length > 1 ? ` (+${paths.length - 1} more)` : "";
|
|
39373
|
+
return `Code conflict in ${first}${more} \u2014 the team changed it too. Resolve it in your editor, commit the merge, then run sync again.`;
|
|
39374
|
+
}
|
|
39276
39375
|
function computeNeedsTaskSync(config, paths) {
|
|
39277
39376
|
if (config?.taskBackend !== "github" && config?.taskBackend !== "clickup") return false;
|
|
39278
39377
|
return paths.some((p) => {
|
|
@@ -39306,7 +39405,6 @@ async function runBrainSync(opts, depsOverride = {}) {
|
|
|
39306
39405
|
}
|
|
39307
39406
|
const mode = resolveMode2(config);
|
|
39308
39407
|
const gitCwd = mode === "separate" ? contextRoot : projectRoot;
|
|
39309
|
-
const ctx = { d, contextRoot, gitCwd, projectRoot, config, strict: !!opts.strict };
|
|
39310
39408
|
if (!d.git.isGitRepo(gitCwd)) {
|
|
39311
39409
|
return {
|
|
39312
39410
|
action: "no-remote",
|
|
@@ -39314,6 +39412,32 @@ async function runBrainSync(opts, depsOverride = {}) {
|
|
|
39314
39412
|
note: "No git repository found for the brain. Run `dreamcontext brain init` or `brain attach` first."
|
|
39315
39413
|
};
|
|
39316
39414
|
}
|
|
39415
|
+
let branch = DEFAULT_BRANCH;
|
|
39416
|
+
if (mode === "full-repo") {
|
|
39417
|
+
const live = d.git.currentBranch(gitCwd);
|
|
39418
|
+
if (!live) {
|
|
39419
|
+
return {
|
|
39420
|
+
action: "detached-head",
|
|
39421
|
+
scrub: EMPTY_SCRUB,
|
|
39422
|
+
note: "You're on a detached HEAD \u2014 check out a branch before syncing the whole project."
|
|
39423
|
+
};
|
|
39424
|
+
}
|
|
39425
|
+
branch = live;
|
|
39426
|
+
}
|
|
39427
|
+
const ctx = {
|
|
39428
|
+
d,
|
|
39429
|
+
contextRoot,
|
|
39430
|
+
gitCwd,
|
|
39431
|
+
projectRoot,
|
|
39432
|
+
config,
|
|
39433
|
+
mode,
|
|
39434
|
+
branch,
|
|
39435
|
+
remoteRef: `${REMOTE_NAME}/${branch}`,
|
|
39436
|
+
strict: !!opts.strict,
|
|
39437
|
+
foreground: !!opts.foreground,
|
|
39438
|
+
noCheckpoint: !!opts.noCheckpoint
|
|
39439
|
+
};
|
|
39440
|
+
if (mode === "full-repo") ensureFullRepoGitignore(projectRoot, config?.taskBackend);
|
|
39317
39441
|
if (mode === "in-tree") {
|
|
39318
39442
|
if (!d.acquireBrainLock(contextRoot)) return { action: "locked", scrub: EMPTY_SCRUB };
|
|
39319
39443
|
try {
|
|
@@ -39339,6 +39463,24 @@ async function runBrainSync(opts, depsOverride = {}) {
|
|
|
39339
39463
|
return { action: "invalid-flag", scrub: EMPTY_SCRUB, note: "No pending team-merge handoff to resume." };
|
|
39340
39464
|
}
|
|
39341
39465
|
if (hasMerge && !opts.continue) {
|
|
39466
|
+
const report = readConflictReport(contextRoot);
|
|
39467
|
+
if (!report) {
|
|
39468
|
+
return {
|
|
39469
|
+
action: "user-merge-in-progress",
|
|
39470
|
+
scrub: EMPTY_SCRUB,
|
|
39471
|
+
note: "Finish your in-progress git merge first, then run sync again."
|
|
39472
|
+
};
|
|
39473
|
+
}
|
|
39474
|
+
if (report.codeConflicts && report.codeConflicts.length > 0) {
|
|
39475
|
+
return {
|
|
39476
|
+
action: "code-conflict",
|
|
39477
|
+
scrub: EMPTY_SCRUB,
|
|
39478
|
+
conflicts: report.codeConflicts,
|
|
39479
|
+
codeConflicts: report.codeConflicts,
|
|
39480
|
+
report: "state/.brain-merge/report.json",
|
|
39481
|
+
note: codeConflictNote(report.codeConflicts)
|
|
39482
|
+
};
|
|
39483
|
+
}
|
|
39342
39484
|
return { action: "already-awaiting-agent", scrub: EMPTY_SCRUB, note: "A team merge is awaiting resolution \u2014 run /dream-sync to reconcile." };
|
|
39343
39485
|
}
|
|
39344
39486
|
if (pending && !hasMerge && !opts.resume) {
|
|
@@ -39355,7 +39497,7 @@ async function runBrainSync(opts, depsOverride = {}) {
|
|
|
39355
39497
|
else if (opts.mode === "pull-only") result = await pullOnlySync(ctx);
|
|
39356
39498
|
else if (opts.mode === "push-only") result = await pushOnlySync(ctx);
|
|
39357
39499
|
else result = await autoSync(ctx);
|
|
39358
|
-
healPlatformLinksBestEffort(projectRoot, contextRoot);
|
|
39500
|
+
if (mode !== "full-repo") healPlatformLinksBestEffort(projectRoot, contextRoot);
|
|
39359
39501
|
return result;
|
|
39360
39502
|
} finally {
|
|
39361
39503
|
d.releaseBrainLock(contextRoot);
|
|
@@ -39389,8 +39531,8 @@ function withMergeOutcome(result, preMergeScrub) {
|
|
|
39389
39531
|
async function fetchRemoteIfExists(ctx, token) {
|
|
39390
39532
|
const { d, gitCwd } = ctx;
|
|
39391
39533
|
return d.withGitCredentials(token, async (env2) => {
|
|
39392
|
-
const exists = d.git.remoteBranchExists(gitCwd, REMOTE_NAME,
|
|
39393
|
-
if (exists) d.git.fetch(gitCwd, REMOTE_NAME,
|
|
39534
|
+
const exists = d.git.remoteBranchExists(gitCwd, REMOTE_NAME, ctx.branch, env2);
|
|
39535
|
+
if (exists) d.git.fetch(gitCwd, REMOTE_NAME, ctx.branch, env2);
|
|
39394
39536
|
return exists;
|
|
39395
39537
|
});
|
|
39396
39538
|
}
|
|
@@ -39398,7 +39540,7 @@ function mergeAndMaybeDefer(ctx, opts) {
|
|
|
39398
39540
|
const { d, gitCwd, contextRoot, projectRoot, config } = ctx;
|
|
39399
39541
|
let mergeResult;
|
|
39400
39542
|
try {
|
|
39401
|
-
mergeResult = d.git.attemptMerge(gitCwd,
|
|
39543
|
+
mergeResult = d.git.attemptMerge(gitCwd, ctx.remoteRef);
|
|
39402
39544
|
} catch (err) {
|
|
39403
39545
|
if (err instanceof Error && /unrelated histories/i.test(err.message)) {
|
|
39404
39546
|
throw new GitSyncError(
|
|
@@ -39411,11 +39553,39 @@ function mergeAndMaybeDefer(ctx, opts) {
|
|
|
39411
39553
|
const blocked2 = scrubAndCommitMerge(ctx, !!opts.effectiveStrict, MERGE_COMMIT_MESSAGE);
|
|
39412
39554
|
return { result: blocked2, needsTaskSync: false };
|
|
39413
39555
|
}
|
|
39414
|
-
const resolution = d.resolveConflicts(gitCwd, mergeResult.conflicts);
|
|
39556
|
+
const resolution = d.resolveConflicts(gitCwd, mergeResult.conflicts, { fullRepo: ctx.mode === "full-repo" });
|
|
39415
39557
|
const needsTaskSync = computeNeedsTaskSync(config, resolution.resolved);
|
|
39558
|
+
if (resolution.deferredToHuman.length > 0) {
|
|
39559
|
+
const codePaths = resolution.deferredToHuman.map((x) => x.path);
|
|
39560
|
+
if (ctx.foreground) {
|
|
39561
|
+
writeConflictReport(contextRoot, {
|
|
39562
|
+
remoteRef: ctx.remoteRef,
|
|
39563
|
+
resolvedByCli: resolution.resolved,
|
|
39564
|
+
deferred: resolution.deferredToAgent.map((x) => {
|
|
39565
|
+
const snap = d.git.readOursTheirsBase(gitCwd, x.path);
|
|
39566
|
+
return { path: x.path, class: x.class, reason: "overlapping edits to same section", ...snap };
|
|
39567
|
+
}),
|
|
39568
|
+
codeConflicts: codePaths
|
|
39569
|
+
});
|
|
39570
|
+
} else {
|
|
39571
|
+
d.git.abortMerge(gitCwd);
|
|
39572
|
+
}
|
|
39573
|
+
return {
|
|
39574
|
+
result: {
|
|
39575
|
+
action: "code-conflict",
|
|
39576
|
+
scrub: EMPTY_SCRUB,
|
|
39577
|
+
conflicts: codePaths,
|
|
39578
|
+
codeConflicts: codePaths,
|
|
39579
|
+
report: ctx.foreground ? "state/.brain-merge/report.json" : void 0,
|
|
39580
|
+
note: codeConflictNote(codePaths),
|
|
39581
|
+
needsTaskSync
|
|
39582
|
+
},
|
|
39583
|
+
needsTaskSync
|
|
39584
|
+
};
|
|
39585
|
+
}
|
|
39416
39586
|
if (resolution.deferredToAgent.length > 0) {
|
|
39417
39587
|
writeConflictReport(contextRoot, {
|
|
39418
|
-
remoteRef:
|
|
39588
|
+
remoteRef: ctx.remoteRef,
|
|
39419
39589
|
resolvedByCli: resolution.resolved,
|
|
39420
39590
|
deferred: resolution.deferredToAgent.map((x) => {
|
|
39421
39591
|
const snap = d.git.readOursTheirsBase(gitCwd, x.path);
|
|
@@ -39447,7 +39617,7 @@ async function pushWithRetry(ctx, scrub) {
|
|
|
39447
39617
|
const tryPush = async () => {
|
|
39448
39618
|
try {
|
|
39449
39619
|
await d.withGitCredentials(token.token, async (env2) => {
|
|
39450
|
-
d.git.push(gitCwd, REMOTE_NAME,
|
|
39620
|
+
d.git.push(gitCwd, REMOTE_NAME, ctx.branch, env2);
|
|
39451
39621
|
});
|
|
39452
39622
|
return true;
|
|
39453
39623
|
} catch {
|
|
@@ -39469,17 +39639,18 @@ async function autoSync(ctx) {
|
|
|
39469
39639
|
const token = d.resolveBrainSyncToken(projectRoot);
|
|
39470
39640
|
if (!token) return { action: "no-remote", scrub: EMPTY_SCRUB, note: "No GitHub token found for the brain repo (per-project secrets or GITHUB_TOKEN/GH_TOKEN env)." };
|
|
39471
39641
|
const remoteExists = await fetchRemoteIfExists(ctx, token.token);
|
|
39472
|
-
const aheadCount = remoteExists ? d.git.revListCount(gitCwd, `HEAD..${
|
|
39642
|
+
const aheadCount = remoteExists ? d.git.revListCount(gitCwd, `HEAD..${ctx.remoteRef}`) : 0;
|
|
39643
|
+
const localAhead = remoteExists ? d.git.revListCount(gitCwd, `${ctx.remoteRef}..HEAD`) : 0;
|
|
39473
39644
|
const dirty = d.git.statusPorcelainTracked(gitCwd);
|
|
39474
39645
|
const needsBootstrapPush = !remoteExists && !!d.git.currentSha(gitCwd);
|
|
39475
|
-
if (aheadCount === 0 && dirty.length === 0 && !needsBootstrapPush) return { action: "noop", scrub: EMPTY_SCRUB };
|
|
39646
|
+
if (aheadCount === 0 && localAhead === 0 && dirty.length === 0 && !needsBootstrapPush) return { action: "noop", scrub: EMPTY_SCRUB };
|
|
39476
39647
|
let scrub = EMPTY_SCRUB;
|
|
39477
39648
|
if (dirty.length > 0) {
|
|
39478
39649
|
d.git.stageAll(gitCwd);
|
|
39479
39650
|
const hits = d.scrubStagedFiles(gitCwd);
|
|
39480
39651
|
scrub = summarizeScrub(hits);
|
|
39481
39652
|
if (isBlockingScrub(scrub, ctx.strict)) return { action: "blocked-scrub", scrub };
|
|
39482
|
-
d.git.commit(gitCwd,
|
|
39653
|
+
d.git.commit(gitCwd, syncCommitMessage(ctx), authorFor(ctx));
|
|
39483
39654
|
}
|
|
39484
39655
|
let needsTaskSync = false;
|
|
39485
39656
|
if (aheadCount > 0) {
|
|
@@ -39487,6 +39658,11 @@ async function autoSync(ctx) {
|
|
|
39487
39658
|
if (outcome.result) return withMergeOutcome(outcome.result, scrub);
|
|
39488
39659
|
needsTaskSync = outcome.needsTaskSync;
|
|
39489
39660
|
}
|
|
39661
|
+
if (remoteExists && localAhead > 0) {
|
|
39662
|
+
const rangeScrub = summarizeScrub(d.scrubCommitRange(gitCwd, `${ctx.remoteRef}..HEAD`));
|
|
39663
|
+
if (isBlockingScrub(rangeScrub, ctx.strict)) return { action: "blocked-scrub", scrub: rangeScrub };
|
|
39664
|
+
if (rangeScrub.blocks.length > 0 || rangeScrub.warns.length > 0) scrub = rangeScrub;
|
|
39665
|
+
}
|
|
39490
39666
|
const pushResult = await pushWithRetry(ctx, scrub);
|
|
39491
39667
|
return { ...pushResult, needsTaskSync: needsTaskSync || pushResult.needsTaskSync };
|
|
39492
39668
|
}
|
|
@@ -39498,24 +39674,33 @@ async function pullOnlySync(ctx) {
|
|
|
39498
39674
|
return { action: "noop", scrub: EMPTY_SCRUB, note: "Remote brain repo is empty \u2014 nothing to pull yet. Run `dreamcontext brain sync` to push the first commit." };
|
|
39499
39675
|
}
|
|
39500
39676
|
const beforeSha = d.git.currentSha(gitCwd);
|
|
39501
|
-
const aheadCount = d.git.revListCount(gitCwd, `HEAD..${
|
|
39677
|
+
const aheadCount = d.git.revListCount(gitCwd, `HEAD..${ctx.remoteRef}`);
|
|
39502
39678
|
if (aheadCount === 0) return { action: "noop", scrub: EMPTY_SCRUB };
|
|
39503
39679
|
const dirty = d.git.statusPorcelainTracked(gitCwd);
|
|
39504
39680
|
let scrub = EMPTY_SCRUB;
|
|
39681
|
+
let checkpointSha;
|
|
39505
39682
|
if (dirty.length > 0) {
|
|
39683
|
+
if (ctx.noCheckpoint) {
|
|
39684
|
+
return {
|
|
39685
|
+
action: "noop",
|
|
39686
|
+
scrub: EMPTY_SCRUB,
|
|
39687
|
+
note: "You have uncommitted local edits and auto-checkpoint-on-open is off \u2014 skipped the pull so your WIP is untouched. Sync from the sidebar when ready."
|
|
39688
|
+
};
|
|
39689
|
+
}
|
|
39506
39690
|
d.git.stageAll(gitCwd);
|
|
39507
39691
|
const hits = d.scrubStagedFiles(gitCwd);
|
|
39508
39692
|
scrub = summarizeScrub(hits);
|
|
39509
|
-
|
|
39693
|
+
const blocks = ctx.foreground ? scrub.blocks.length > 0 : scrub.blocks.length > 0 || scrub.warns.length > 0;
|
|
39694
|
+
if (blocks) {
|
|
39510
39695
|
return {
|
|
39511
39696
|
action: "blocked-scrub",
|
|
39512
39697
|
scrub,
|
|
39513
|
-
note: "Your local
|
|
39698
|
+
note: "Your local edits contain something that looks sensitive \u2014 review and run sync manually."
|
|
39514
39699
|
};
|
|
39515
39700
|
}
|
|
39516
|
-
d.git.commit(gitCwd,
|
|
39701
|
+
checkpointSha = d.git.commit(gitCwd, autoCheckpointMessage(ctx), authorFor(ctx)) ?? void 0;
|
|
39517
39702
|
}
|
|
39518
|
-
const outcome = mergeAndMaybeDefer(ctx, { abortOnDefer: true, markPendingOnDefer: true, effectiveStrict:
|
|
39703
|
+
const outcome = mergeAndMaybeDefer(ctx, { abortOnDefer: true, markPendingOnDefer: true, effectiveStrict: !ctx.foreground });
|
|
39519
39704
|
if (outcome.result) return withMergeOutcome(outcome.result, scrub);
|
|
39520
39705
|
const afterSha = d.git.currentSha(gitCwd);
|
|
39521
39706
|
const pulledUpdates = beforeSha && afterSha ? d.git.revListCount(gitCwd, `${beforeSha}..${afterSha}`) : aheadCount;
|
|
@@ -39525,15 +39710,19 @@ async function pullOnlySync(ctx) {
|
|
|
39525
39710
|
pendingAgentMerge: false,
|
|
39526
39711
|
needsTaskSync: outcome.needsTaskSync
|
|
39527
39712
|
});
|
|
39528
|
-
return { action: "pulled", scrub, pulledUpdates, needsTaskSync: outcome.needsTaskSync };
|
|
39713
|
+
return { action: "pulled", scrub, pulledUpdates, needsTaskSync: outcome.needsTaskSync, checkpointed: !!checkpointSha, checkpointSha };
|
|
39529
39714
|
}
|
|
39530
39715
|
async function pushOnlySync(ctx) {
|
|
39531
39716
|
const { d, gitCwd } = ctx;
|
|
39532
39717
|
d.git.stageAll(gitCwd);
|
|
39533
39718
|
const hits = d.scrubStagedFiles(gitCwd);
|
|
39534
|
-
|
|
39719
|
+
let scrub = summarizeScrub(hits);
|
|
39535
39720
|
if (isBlockingScrub(scrub, ctx.strict)) return { action: "blocked-scrub", scrub };
|
|
39536
|
-
d.git.commit(gitCwd,
|
|
39721
|
+
d.git.commit(gitCwd, syncCommitMessage(ctx), authorFor(ctx));
|
|
39722
|
+
const base = d.git.revParse(gitCwd, ctx.remoteRef) ? ctx.remoteRef : EMPTY_TREE_SHA;
|
|
39723
|
+
const rangeScrub = summarizeScrub(d.scrubCommitRange(gitCwd, `${base}..HEAD`));
|
|
39724
|
+
if (isBlockingScrub(rangeScrub, ctx.strict)) return { action: "blocked-scrub", scrub: rangeScrub };
|
|
39725
|
+
if (rangeScrub.blocks.length > 0 || rangeScrub.warns.length > 0) scrub = rangeScrub;
|
|
39537
39726
|
return pushWithRetry(ctx, scrub);
|
|
39538
39727
|
}
|
|
39539
39728
|
async function continueMerge(ctx) {
|
|
@@ -39563,7 +39752,7 @@ async function resumeHandoff(ctx) {
|
|
|
39563
39752
|
const hits = d.scrubStagedFiles(gitCwd);
|
|
39564
39753
|
const s = summarizeScrub(hits);
|
|
39565
39754
|
if (isBlockingScrub(s, ctx.strict)) return { action: "blocked-scrub", scrub: s };
|
|
39566
|
-
d.git.commit(gitCwd,
|
|
39755
|
+
d.git.commit(gitCwd, syncCommitMessage(ctx), authorFor(ctx));
|
|
39567
39756
|
}
|
|
39568
39757
|
const outcome = mergeAndMaybeDefer(ctx, { abortOnDefer: false, markPendingOnDefer: false });
|
|
39569
39758
|
if (outcome.result) return withMergeOutcome(outcome.result, scrub);
|
|
@@ -39573,7 +39762,7 @@ async function resumeHandoff(ctx) {
|
|
|
39573
39762
|
}
|
|
39574
39763
|
return pushResult;
|
|
39575
39764
|
}
|
|
39576
|
-
var REMOTE_NAME,
|
|
39765
|
+
var REMOTE_NAME, DEFAULT_BRANCH, EMPTY_TREE_SHA, MERGE_COMMIT_MESSAGE, AGENT_MERGE_COMMIT_MESSAGE, EMPTY_SCRUB, defaultDeps;
|
|
39577
39766
|
var init_sync_engine = __esm({
|
|
39578
39767
|
"src/lib/git-sync/sync-engine.ts"() {
|
|
39579
39768
|
"use strict";
|
|
@@ -39590,9 +39779,8 @@ var init_sync_engine = __esm({
|
|
|
39590
39779
|
init_identity();
|
|
39591
39780
|
init_id();
|
|
39592
39781
|
REMOTE_NAME = "origin";
|
|
39593
|
-
|
|
39594
|
-
|
|
39595
|
-
AUTO_CHECKPOINT_MESSAGE = "chore(brain): auto-checkpoint local edits before team merge";
|
|
39782
|
+
DEFAULT_BRANCH = "main";
|
|
39783
|
+
EMPTY_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
39596
39784
|
MERGE_COMMIT_MESSAGE = "chore(brain): merge team updates";
|
|
39597
39785
|
AGENT_MERGE_COMMIT_MESSAGE = "chore(brain): merge team updates (agent-resolved)";
|
|
39598
39786
|
EMPTY_SCRUB = { blocks: [], warns: [] };
|
|
@@ -39600,6 +39788,7 @@ var init_sync_engine = __esm({
|
|
|
39600
39788
|
git: git_exports,
|
|
39601
39789
|
resolveConflicts,
|
|
39602
39790
|
scrubStagedFiles,
|
|
39791
|
+
scrubCommitRange,
|
|
39603
39792
|
resolveBrainSyncToken,
|
|
39604
39793
|
withGitCredentials,
|
|
39605
39794
|
acquireBrainLock,
|
|
@@ -39764,8 +39953,8 @@ function registerBrainCommand(program2) {
|
|
|
39764
39953
|
const local = readBrainLocal(projectRoot);
|
|
39765
39954
|
console.log(header("Brain Repo Status"));
|
|
39766
39955
|
info(`Cloud sync: ${enabledResolution.enabled ? "ON" : "OFF"} (${enabledResolution.source})`);
|
|
39767
|
-
info(`Mode: ${mode}`);
|
|
39768
|
-
if (mode
|
|
39956
|
+
info(`Mode: ${mode}${mode === "full-repo" ? " (whole project \u2192 origin)" : ""}`);
|
|
39957
|
+
if (mode !== "in-tree") {
|
|
39769
39958
|
const remote = isGitRepo(gitCwd) ? getRemoteUrl(gitCwd, "origin") : null;
|
|
39770
39959
|
info(`Remote: ${remote ?? "(none configured)"}`);
|
|
39771
39960
|
}
|
|
@@ -39867,7 +40056,7 @@ function registerBrainCommand(program2) {
|
|
|
39867
40056
|
const projectRoot = dirname26(contextRoot);
|
|
39868
40057
|
const config = readSetupConfig(projectRoot);
|
|
39869
40058
|
if (!opts.status && resolveMode2(config) !== "separate") {
|
|
39870
|
-
warn("The platform layer only helps in separate mode \u2014 in-tree brains already live in the code repo, so CLAUDE.md/.claude
|
|
40059
|
+
warn("The platform layer only helps in separate mode \u2014 in-tree and full-repo brains already live in the code repo, so CLAUDE.md/.claude sync as-is.");
|
|
39871
40060
|
info("Set up a separate brain repo first (`dreamcontext brain init` / `brain attach`).");
|
|
39872
40061
|
process.exitCode = 1;
|
|
39873
40062
|
return;
|
|
@@ -41162,19 +41351,93 @@ var init_chunker = __esm({
|
|
|
41162
41351
|
});
|
|
41163
41352
|
|
|
41164
41353
|
// src/lib/embeddings/embedder.ts
|
|
41354
|
+
import { existsSync as existsSync53 } from "fs";
|
|
41355
|
+
import { createRequire } from "module";
|
|
41165
41356
|
import { homedir as homedir4 } from "os";
|
|
41166
41357
|
import { join as join54 } from "path";
|
|
41358
|
+
function recordProgress(p) {
|
|
41359
|
+
if (!p.file) return;
|
|
41360
|
+
const prev = modelStatus.files.get(p.file);
|
|
41361
|
+
modelStatus.files.set(p.file, {
|
|
41362
|
+
file: p.file,
|
|
41363
|
+
status: p.status,
|
|
41364
|
+
loaded: p.loaded ?? prev?.loaded ?? 0,
|
|
41365
|
+
total: p.total ?? prev?.total ?? 0,
|
|
41366
|
+
progress: p.status === "done" ? 100 : p.progress ?? prev?.progress ?? 0
|
|
41367
|
+
});
|
|
41368
|
+
}
|
|
41369
|
+
function isEmbedPackageInstalled() {
|
|
41370
|
+
if (pkgInstalledCache !== null) return pkgInstalledCache;
|
|
41371
|
+
try {
|
|
41372
|
+
createRequire(import.meta.url).resolve("@huggingface/transformers");
|
|
41373
|
+
pkgInstalledCache = true;
|
|
41374
|
+
} catch {
|
|
41375
|
+
pkgInstalledCache = false;
|
|
41376
|
+
}
|
|
41377
|
+
return pkgInstalledCache;
|
|
41378
|
+
}
|
|
41379
|
+
function isEmbedModelDownloaded() {
|
|
41380
|
+
const root = join54(EMBED_MODEL_CACHE_DIR, EMBED_MODEL);
|
|
41381
|
+
return existsSync53(join54(root, "onnx", "model_quantized.onnx")) && existsSync53(join54(root, "config.json")) && existsSync53(join54(root, "tokenizer.json"));
|
|
41382
|
+
}
|
|
41383
|
+
function getEmbedModelStatus() {
|
|
41384
|
+
const downloaded = isEmbedModelDownloaded();
|
|
41385
|
+
const files = [...modelStatus.files.values()];
|
|
41386
|
+
const totalBytes = files.reduce((s, f) => s + (f.total || 0), 0);
|
|
41387
|
+
const loadedBytes = files.reduce((s, f) => s + (f.loaded || 0), 0);
|
|
41388
|
+
let state;
|
|
41389
|
+
if (modelStatus.state === "error") state = "error";
|
|
41390
|
+
else if (downloaded) state = "ready";
|
|
41391
|
+
else if (modelStatus.state === "downloading") state = "downloading";
|
|
41392
|
+
else state = "not_downloaded";
|
|
41393
|
+
const progress = state === "ready" ? 100 : totalBytes > 0 ? Math.min(99, Math.round(loadedBytes / totalBytes * 100)) : 0;
|
|
41394
|
+
return {
|
|
41395
|
+
model: EMBED_MODEL,
|
|
41396
|
+
state,
|
|
41397
|
+
downloaded,
|
|
41398
|
+
packageInstalled: isEmbedPackageInstalled(),
|
|
41399
|
+
progress,
|
|
41400
|
+
loadedBytes,
|
|
41401
|
+
totalBytes,
|
|
41402
|
+
files,
|
|
41403
|
+
error: modelStatus.error ?? null,
|
|
41404
|
+
errorCode: modelStatus.errorCode ?? null
|
|
41405
|
+
};
|
|
41406
|
+
}
|
|
41407
|
+
function startEmbedModelDownload() {
|
|
41408
|
+
if (modelStatus.state === "not_downloaded" || modelStatus.state === "error") {
|
|
41409
|
+
extractorPromise = null;
|
|
41410
|
+
modelStatus.files.clear();
|
|
41411
|
+
modelStatus.error = void 0;
|
|
41412
|
+
modelStatus.errorCode = void 0;
|
|
41413
|
+
}
|
|
41414
|
+
void getExtractor();
|
|
41415
|
+
return getEmbedModelStatus();
|
|
41416
|
+
}
|
|
41167
41417
|
async function getExtractor() {
|
|
41168
41418
|
if (extractorPromise === null) {
|
|
41419
|
+
modelStatus.state = "downloading";
|
|
41420
|
+
modelStatus.startedAt = Date.now();
|
|
41421
|
+
modelStatus.endedAt = void 0;
|
|
41169
41422
|
extractorPromise = (async () => {
|
|
41170
41423
|
try {
|
|
41171
41424
|
const tf = await import("@huggingface/transformers");
|
|
41172
|
-
tf.env.cacheDir =
|
|
41173
|
-
const pipe = await tf.pipeline("feature-extraction", EMBED_MODEL, {
|
|
41425
|
+
tf.env.cacheDir = EMBED_MODEL_CACHE_DIR;
|
|
41426
|
+
const pipe = await tf.pipeline("feature-extraction", EMBED_MODEL, {
|
|
41427
|
+
dtype: "q8",
|
|
41428
|
+
progress_callback: recordProgress
|
|
41429
|
+
});
|
|
41430
|
+
modelStatus.state = "ready";
|
|
41431
|
+
modelStatus.endedAt = Date.now();
|
|
41174
41432
|
return pipe;
|
|
41175
41433
|
} catch (err) {
|
|
41434
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41435
|
+
modelStatus.state = "error";
|
|
41436
|
+
modelStatus.error = msg;
|
|
41437
|
+
modelStatus.errorCode = /cannot find (module|package)|ERR_MODULE_NOT_FOUND/i.test(msg) ? "package_missing" : "download_failed";
|
|
41438
|
+
modelStatus.endedAt = Date.now();
|
|
41176
41439
|
if (process.env.DREAMCONTEXT_DEBUG) {
|
|
41177
|
-
console.error(`[embed] model load failed: ${
|
|
41440
|
+
console.error(`[embed] model load failed: ${msg}`);
|
|
41178
41441
|
}
|
|
41179
41442
|
return null;
|
|
41180
41443
|
}
|
|
@@ -41185,7 +41448,7 @@ async function getExtractor() {
|
|
|
41185
41448
|
async function embeddingsAvailable() {
|
|
41186
41449
|
return await getExtractor() !== null;
|
|
41187
41450
|
}
|
|
41188
|
-
async function embedPassages(texts) {
|
|
41451
|
+
async function embedPassages(texts, onProgress) {
|
|
41189
41452
|
const extractor = await getExtractor();
|
|
41190
41453
|
if (extractor === null) return null;
|
|
41191
41454
|
const out = [];
|
|
@@ -41196,6 +41459,7 @@ async function embedPassages(texts) {
|
|
|
41196
41459
|
for (let j = 0; j < batch.length; j++) {
|
|
41197
41460
|
out.push(res.data.slice(j * dims, (j + 1) * dims));
|
|
41198
41461
|
}
|
|
41462
|
+
onProgress?.(Math.min(i + BATCH_SIZE, texts.length), texts.length);
|
|
41199
41463
|
}
|
|
41200
41464
|
return out;
|
|
41201
41465
|
}
|
|
@@ -41205,18 +41469,21 @@ async function embedQuery(text) {
|
|
|
41205
41469
|
const res = await extractor(`query: ${text}`, { pooling: "mean", normalize: true });
|
|
41206
41470
|
return res.data.slice(0, res.dims[res.dims.length - 1]);
|
|
41207
41471
|
}
|
|
41208
|
-
var EMBED_MODEL, BATCH_SIZE, extractorPromise;
|
|
41472
|
+
var EMBED_MODEL, EMBED_MODEL_CACHE_DIR, BATCH_SIZE, extractorPromise, modelStatus, pkgInstalledCache;
|
|
41209
41473
|
var init_embedder = __esm({
|
|
41210
41474
|
"src/lib/embeddings/embedder.ts"() {
|
|
41211
41475
|
"use strict";
|
|
41212
41476
|
EMBED_MODEL = process.env.DREAMCONTEXT_EMBED_MODEL ?? "Xenova/multilingual-e5-small";
|
|
41477
|
+
EMBED_MODEL_CACHE_DIR = join54(homedir4(), ".dreamcontext", "models");
|
|
41213
41478
|
BATCH_SIZE = 16;
|
|
41214
41479
|
extractorPromise = null;
|
|
41480
|
+
modelStatus = { state: "not_downloaded", files: /* @__PURE__ */ new Map() };
|
|
41481
|
+
pkgInstalledCache = null;
|
|
41215
41482
|
}
|
|
41216
41483
|
});
|
|
41217
41484
|
|
|
41218
41485
|
// src/lib/embeddings/store.ts
|
|
41219
|
-
import { existsSync as
|
|
41486
|
+
import { existsSync as existsSync54, mkdirSync as mkdirSync31, readFileSync as readFileSync39, renameSync as renameSync12, statSync as statSync9, writeFileSync as writeFileSync39 } from "fs";
|
|
41220
41487
|
import { join as join55 } from "path";
|
|
41221
41488
|
function encodeVector(v) {
|
|
41222
41489
|
return Buffer.from(v.buffer, v.byteOffset, v.byteLength).toString("base64");
|
|
@@ -41231,7 +41498,7 @@ function cachePath2(contextRoot) {
|
|
|
41231
41498
|
function loadCache(contextRoot) {
|
|
41232
41499
|
const empty = { version: CACHE_VERSION, model: EMBED_MODEL, docs: {}, vectors: {} };
|
|
41233
41500
|
const path2 = cachePath2(contextRoot);
|
|
41234
|
-
if (!
|
|
41501
|
+
if (!existsSync54(path2)) return empty;
|
|
41235
41502
|
try {
|
|
41236
41503
|
const parsed = JSON.parse(readFileSync39(path2, "utf-8"));
|
|
41237
41504
|
if (parsed.version !== CACHE_VERSION || parsed.model !== EMBED_MODEL) return empty;
|
|
@@ -41245,7 +41512,7 @@ function saveCache(contextRoot, cache) {
|
|
|
41245
41512
|
const dir = join55(contextRoot, CACHE_DIR);
|
|
41246
41513
|
mkdirSync31(dir, { recursive: true });
|
|
41247
41514
|
const ignorePath = join55(dir, ".gitignore");
|
|
41248
|
-
if (!
|
|
41515
|
+
if (!existsSync54(ignorePath)) writeFileSync39(ignorePath, "*\n");
|
|
41249
41516
|
const tmp = cachePath2(contextRoot) + ".tmp";
|
|
41250
41517
|
writeFileSync39(tmp, JSON.stringify(cache));
|
|
41251
41518
|
renameSync12(tmp, cachePath2(contextRoot));
|
|
@@ -41259,7 +41526,36 @@ function statOf(path2) {
|
|
|
41259
41526
|
}
|
|
41260
41527
|
}
|
|
41261
41528
|
function embeddingCacheExists(contextRoot) {
|
|
41262
|
-
return
|
|
41529
|
+
return existsSync54(cachePath2(contextRoot));
|
|
41530
|
+
}
|
|
41531
|
+
function embeddingCacheChunkCount(contextRoot) {
|
|
41532
|
+
try {
|
|
41533
|
+
const cache = loadCache(contextRoot);
|
|
41534
|
+
let n = 0;
|
|
41535
|
+
for (const doc of Object.values(cache.docs)) n += doc.hashes.length;
|
|
41536
|
+
return n;
|
|
41537
|
+
} catch {
|
|
41538
|
+
return 0;
|
|
41539
|
+
}
|
|
41540
|
+
}
|
|
41541
|
+
function embeddingCacheUsable(contextRoot) {
|
|
41542
|
+
const path2 = cachePath2(contextRoot);
|
|
41543
|
+
let mtimeMs;
|
|
41544
|
+
try {
|
|
41545
|
+
mtimeMs = statSync9(path2).mtimeMs;
|
|
41546
|
+
} catch {
|
|
41547
|
+
usableMemo.delete(path2);
|
|
41548
|
+
return false;
|
|
41549
|
+
}
|
|
41550
|
+
const memo = usableMemo.get(path2);
|
|
41551
|
+
if (memo && memo.mtimeMs === mtimeMs) return memo.usable;
|
|
41552
|
+
const usable = Object.keys(loadCache(contextRoot).vectors).length > 0;
|
|
41553
|
+
usableMemo.set(path2, { mtimeMs, usable });
|
|
41554
|
+
if (usableMemo.size > USABLE_MEMO_MAX) {
|
|
41555
|
+
const oldest = usableMemo.keys().next().value;
|
|
41556
|
+
if (oldest !== void 0) usableMemo.delete(oldest);
|
|
41557
|
+
}
|
|
41558
|
+
return usable;
|
|
41263
41559
|
}
|
|
41264
41560
|
async function refreshEmbeddings(contextRoot, corpus, embed = embedPassages, opts = {}) {
|
|
41265
41561
|
const cache = loadCache(contextRoot);
|
|
@@ -41303,28 +41599,36 @@ async function refreshEmbeddings(contextRoot, corpus, embed = embedPassages, opt
|
|
|
41303
41599
|
let embeddedCount = 0;
|
|
41304
41600
|
if (missing.length > 0) {
|
|
41305
41601
|
const texts = missing.map((h) => chunkTextByHash.get(h) ?? "");
|
|
41306
|
-
const vectors = await embed(texts);
|
|
41602
|
+
const vectors = await embed(texts, opts.onProgress);
|
|
41307
41603
|
if (vectors === null) return null;
|
|
41308
41604
|
for (let i = 0; i < missing.length; i++) {
|
|
41309
41605
|
cache.vectors[missing[i]] = encodeVector(vectors[i]);
|
|
41310
41606
|
}
|
|
41311
41607
|
embeddedCount = missing.length;
|
|
41312
41608
|
}
|
|
41313
|
-
const referenced = /* @__PURE__ */ new Set();
|
|
41314
|
-
const newDocs = {};
|
|
41315
|
-
for (const [key2, { entry }] of wanted) {
|
|
41316
|
-
newDocs[key2] = entry;
|
|
41317
|
-
for (const h of entry.hashes) referenced.add(h);
|
|
41318
|
-
}
|
|
41319
41609
|
let evicted = 0;
|
|
41320
|
-
|
|
41321
|
-
|
|
41322
|
-
|
|
41323
|
-
|
|
41324
|
-
|
|
41325
|
-
|
|
41326
|
-
|
|
41327
|
-
|
|
41610
|
+
let docsChanged = false;
|
|
41611
|
+
if (opts.additive) {
|
|
41612
|
+
for (const [key2, { entry }] of wanted) {
|
|
41613
|
+
if (cache.docs[key2] !== entry) docsChanged = true;
|
|
41614
|
+
cache.docs[key2] = entry;
|
|
41615
|
+
}
|
|
41616
|
+
} else {
|
|
41617
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
41618
|
+
const newDocs = {};
|
|
41619
|
+
for (const [key2, { entry }] of wanted) {
|
|
41620
|
+
newDocs[key2] = entry;
|
|
41621
|
+
for (const h of entry.hashes) referenced.add(h);
|
|
41622
|
+
}
|
|
41623
|
+
const newVectors = {};
|
|
41624
|
+
for (const [h, v] of Object.entries(cache.vectors)) {
|
|
41625
|
+
if (referenced.has(h)) newVectors[h] = v;
|
|
41626
|
+
else evicted++;
|
|
41627
|
+
}
|
|
41628
|
+
docsChanged = Object.keys(newDocs).length !== Object.keys(cache.docs).length || Object.keys(newDocs).some((k) => cache.docs[k] !== newDocs[k]);
|
|
41629
|
+
cache.docs = newDocs;
|
|
41630
|
+
cache.vectors = newVectors;
|
|
41631
|
+
}
|
|
41328
41632
|
if (embeddedCount > 0 || evicted > 0 || docsChanged) saveCache(contextRoot, cache);
|
|
41329
41633
|
const chunks = [];
|
|
41330
41634
|
let dims = 0;
|
|
@@ -41338,12 +41642,13 @@ async function refreshEmbeddings(contextRoot, corpus, embed = embedPassages, opt
|
|
|
41338
41642
|
chunks.push({ docKey: key2, seq, hash, vector });
|
|
41339
41643
|
}
|
|
41340
41644
|
}
|
|
41645
|
+
const distinctHashes = new Set(chunks.map((c) => c.hash)).size;
|
|
41341
41646
|
return {
|
|
41342
41647
|
index: { chunks, dims },
|
|
41343
|
-
stats: { embedded: embeddedCount, reused:
|
|
41648
|
+
stats: { embedded: embeddedCount, reused: Math.max(0, distinctHashes - embeddedCount), evicted }
|
|
41344
41649
|
};
|
|
41345
41650
|
}
|
|
41346
|
-
var CACHE_VERSION, CACHE_DIR, CACHE_FILE;
|
|
41651
|
+
var CACHE_VERSION, CACHE_DIR, CACHE_FILE, usableMemo, USABLE_MEMO_MAX;
|
|
41347
41652
|
var init_store = __esm({
|
|
41348
41653
|
"src/lib/embeddings/store.ts"() {
|
|
41349
41654
|
"use strict";
|
|
@@ -41353,6 +41658,8 @@ var init_store = __esm({
|
|
|
41353
41658
|
CACHE_VERSION = 1;
|
|
41354
41659
|
CACHE_DIR = ".embeddings";
|
|
41355
41660
|
CACHE_FILE = "cache.json";
|
|
41661
|
+
usableMemo = /* @__PURE__ */ new Map();
|
|
41662
|
+
USABLE_MEMO_MAX = 32;
|
|
41356
41663
|
}
|
|
41357
41664
|
});
|
|
41358
41665
|
|
|
@@ -41534,7 +41841,7 @@ var init_sleep_consolidation = __esm({
|
|
|
41534
41841
|
});
|
|
41535
41842
|
|
|
41536
41843
|
// src/cli/commands/sleep.ts
|
|
41537
|
-
import { existsSync as
|
|
41844
|
+
import { existsSync as existsSync55 } from "fs";
|
|
41538
41845
|
import { join as join56, dirname as dirname28 } from "path";
|
|
41539
41846
|
function getSleepPath(root) {
|
|
41540
41847
|
return join56(root, "state", ".sleep.json");
|
|
@@ -41565,7 +41872,7 @@ function freshDefaults() {
|
|
|
41565
41872
|
}
|
|
41566
41873
|
function readSleepState(root) {
|
|
41567
41874
|
const filePath = getSleepPath(root);
|
|
41568
|
-
if (!
|
|
41875
|
+
if (!existsSync55(filePath)) {
|
|
41569
41876
|
return freshDefaults();
|
|
41570
41877
|
}
|
|
41571
41878
|
try {
|
|
@@ -41574,7 +41881,7 @@ function readSleepState(root) {
|
|
|
41574
41881
|
const historyPath = getSleepHistoryPath(root);
|
|
41575
41882
|
let existing = [];
|
|
41576
41883
|
try {
|
|
41577
|
-
if (
|
|
41884
|
+
if (existsSync55(historyPath)) {
|
|
41578
41885
|
existing = readJsonArray(historyPath);
|
|
41579
41886
|
}
|
|
41580
41887
|
} catch {
|
|
@@ -41601,7 +41908,7 @@ function readSleepState(root) {
|
|
|
41601
41908
|
}
|
|
41602
41909
|
function readSleepHistory(root) {
|
|
41603
41910
|
const filePath = getSleepHistoryPath(root);
|
|
41604
|
-
if (!
|
|
41911
|
+
if (!existsSync55(filePath)) return [];
|
|
41605
41912
|
try {
|
|
41606
41913
|
return readJsonArray(filePath);
|
|
41607
41914
|
} catch {
|
|
@@ -41858,6 +42165,11 @@ function registerSleepCommand(program2) {
|
|
|
41858
42165
|
${source_default.dim(`${history.length} total consolidation(s)`)}`);
|
|
41859
42166
|
});
|
|
41860
42167
|
}
|
|
42168
|
+
function resolveRecallMode(root) {
|
|
42169
|
+
const env2 = process.env.DREAMCONTEXT_RECALL_MODE;
|
|
42170
|
+
if (env2 && RECALL_MODES.includes(env2)) return env2;
|
|
42171
|
+
return readSleepState(root).recall_mode ?? "haiku";
|
|
42172
|
+
}
|
|
41861
42173
|
function registerRecallCommand(program2) {
|
|
41862
42174
|
const recall = program2.command("recall").description("Control memory recall mode (haiku / raw / hybrid / off)");
|
|
41863
42175
|
recall.command("status").description("Show current recall mode").action(() => {
|
|
@@ -41902,6 +42214,7 @@ function registerRecallCommand(program2) {
|
|
|
41902
42214
|
success("Recall mode set to hybrid \u2014 BM25 + dense RRF fusion (experimental; falls back to BM25 if the embedding model is unavailable)");
|
|
41903
42215
|
});
|
|
41904
42216
|
}
|
|
42217
|
+
var RECALL_MODES;
|
|
41905
42218
|
var init_sleep = __esm({
|
|
41906
42219
|
"src/cli/commands/sleep.ts"() {
|
|
41907
42220
|
"use strict";
|
|
@@ -41920,11 +42233,12 @@ var init_sleep = __esm({
|
|
|
41920
42233
|
init_recall();
|
|
41921
42234
|
init_store();
|
|
41922
42235
|
init_sleep_consolidation();
|
|
42236
|
+
RECALL_MODES = ["haiku", "raw", "hybrid", "off"];
|
|
41923
42237
|
}
|
|
41924
42238
|
});
|
|
41925
42239
|
|
|
41926
42240
|
// src/cli/commands/knowledge.ts
|
|
41927
|
-
import { existsSync as
|
|
42241
|
+
import { existsSync as existsSync56 } from "fs";
|
|
41928
42242
|
import { join as join57 } from "path";
|
|
41929
42243
|
function getKnowledgeDir() {
|
|
41930
42244
|
const root = ensureContextRoot();
|
|
@@ -41936,7 +42250,7 @@ function registerKnowledgeCommand(program2) {
|
|
|
41936
42250
|
const dir = getKnowledgeDir();
|
|
41937
42251
|
const slug = slugify(name);
|
|
41938
42252
|
const filePath = join57(dir, `${slug}.md`);
|
|
41939
|
-
if (
|
|
42253
|
+
if (existsSync56(filePath)) {
|
|
41940
42254
|
error(`Knowledge file already exists: ${slug}.md`);
|
|
41941
42255
|
return;
|
|
41942
42256
|
}
|
|
@@ -42076,7 +42390,7 @@ ${content || "(Content to be added)"}
|
|
|
42076
42390
|
knowledge.command("touch").argument("<slug>", "Knowledge file slug").description("Record access to a knowledge file (for decay tracking)").action((slug) => {
|
|
42077
42391
|
const root = ensureContextRoot();
|
|
42078
42392
|
const knowledgePath2 = join57(root, "knowledge", `${slug}.md`);
|
|
42079
|
-
if (!
|
|
42393
|
+
if (!existsSync56(knowledgePath2)) {
|
|
42080
42394
|
error(`Knowledge file not found: ${slug}.md`);
|
|
42081
42395
|
return;
|
|
42082
42396
|
}
|
|
@@ -42131,7 +42445,7 @@ var init_member_match = __esm({
|
|
|
42131
42445
|
});
|
|
42132
42446
|
|
|
42133
42447
|
// src/lib/objectives-store.ts
|
|
42134
|
-
import { existsSync as
|
|
42448
|
+
import { existsSync as existsSync57, mkdirSync as mkdirSync32, unlinkSync as unlinkSync7 } from "fs";
|
|
42135
42449
|
import { join as join58, basename as basename14 } from "path";
|
|
42136
42450
|
function objectivesDir(contextRoot) {
|
|
42137
42451
|
return join58(contextRoot, "core", "objectives");
|
|
@@ -42230,7 +42544,7 @@ function readObjectiveFile(filePath) {
|
|
|
42230
42544
|
}
|
|
42231
42545
|
function listObjectives(contextRoot) {
|
|
42232
42546
|
const dir = objectivesDir(contextRoot);
|
|
42233
|
-
if (!
|
|
42547
|
+
if (!existsSync57(dir)) return [];
|
|
42234
42548
|
const files = import_fast_glob12.default.sync("*.md", { cwd: dir, absolute: true }).sort();
|
|
42235
42549
|
const out = [];
|
|
42236
42550
|
for (const file of files) {
|
|
@@ -42243,7 +42557,7 @@ function listObjectives(contextRoot) {
|
|
|
42243
42557
|
}
|
|
42244
42558
|
function getObjective(contextRoot, slug) {
|
|
42245
42559
|
const path2 = objectivePath(contextRoot, slug);
|
|
42246
|
-
if (!isSafeObjectiveSlug(slug) || !
|
|
42560
|
+
if (!isSafeObjectiveSlug(slug) || !existsSync57(path2)) return null;
|
|
42247
42561
|
try {
|
|
42248
42562
|
return readObjectiveFile(path2);
|
|
42249
42563
|
} catch {
|
|
@@ -42286,7 +42600,7 @@ function createObjective(contextRoot, input2) {
|
|
|
42286
42600
|
);
|
|
42287
42601
|
}
|
|
42288
42602
|
const path2 = objectivePath(contextRoot, slug);
|
|
42289
|
-
if (
|
|
42603
|
+
if (existsSync57(path2)) {
|
|
42290
42604
|
throw new ObjectiveError(`Objective already exists: ${slug}`);
|
|
42291
42605
|
}
|
|
42292
42606
|
validateDateRange(input2.start_date, input2.target_date);
|
|
@@ -42391,7 +42705,7 @@ function deleteObjective(contextRoot, slug) {
|
|
|
42391
42705
|
}
|
|
42392
42706
|
const unhealedTasks = [];
|
|
42393
42707
|
const stateDir = join58(contextRoot, "state");
|
|
42394
|
-
if (
|
|
42708
|
+
if (existsSync57(stateDir)) {
|
|
42395
42709
|
for (const file of import_fast_glob12.default.sync("*.md", { cwd: stateDir, absolute: true })) {
|
|
42396
42710
|
let objectives;
|
|
42397
42711
|
try {
|
|
@@ -43410,7 +43724,7 @@ var init_tasks = __esm({
|
|
|
43410
43724
|
});
|
|
43411
43725
|
|
|
43412
43726
|
// src/lib/roadmap-model.ts
|
|
43413
|
-
import { existsSync as
|
|
43727
|
+
import { existsSync as existsSync58 } from "fs";
|
|
43414
43728
|
import { join as join60, basename as basename16 } from "path";
|
|
43415
43729
|
function strOrNull3(v) {
|
|
43416
43730
|
if (v === void 0 || v === null) return null;
|
|
@@ -43419,7 +43733,7 @@ function strOrNull3(v) {
|
|
|
43419
43733
|
}
|
|
43420
43734
|
function loadTaskRefs(contextRoot) {
|
|
43421
43735
|
const stateDir = join60(contextRoot, "state");
|
|
43422
|
-
if (!
|
|
43736
|
+
if (!existsSync58(stateDir)) return [];
|
|
43423
43737
|
const files = import_fast_glob14.default.sync("*.md", { cwd: stateDir, absolute: true }).sort();
|
|
43424
43738
|
const out = [];
|
|
43425
43739
|
for (const file of files) {
|
|
@@ -43948,7 +44262,7 @@ var init_roadmap = __esm({
|
|
|
43948
44262
|
});
|
|
43949
44263
|
|
|
43950
44264
|
// src/lib/lab/required-credentials.ts
|
|
43951
|
-
import { existsSync as
|
|
44265
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync34, writeFileSync as writeFileSync41 } from "fs";
|
|
43952
44266
|
import { join as join62 } from "path";
|
|
43953
44267
|
function requiredCredentialKeys(manifest) {
|
|
43954
44268
|
const keys = /* @__PURE__ */ new Set();
|
|
@@ -43980,7 +44294,7 @@ function collectRequiredCredentialKeys(contextRoot) {
|
|
|
43980
44294
|
function writeCredentialsExample(contextRoot) {
|
|
43981
44295
|
const keys = collectRequiredCredentialKeys(contextRoot);
|
|
43982
44296
|
const path2 = join62(contextRoot, "lab", "credentials.example.json");
|
|
43983
|
-
if (keys.length === 0 && !
|
|
44297
|
+
if (keys.length === 0 && !existsSync60(path2)) return;
|
|
43984
44298
|
const example = {};
|
|
43985
44299
|
for (const key2 of keys) example[key2] = "";
|
|
43986
44300
|
mkdirSync34(join62(contextRoot, "lab"), { recursive: true });
|
|
@@ -44012,7 +44326,7 @@ var init_types2 = __esm({
|
|
|
44012
44326
|
});
|
|
44013
44327
|
|
|
44014
44328
|
// src/lib/lab/store.ts
|
|
44015
|
-
import { existsSync as
|
|
44329
|
+
import { existsSync as existsSync61, mkdirSync as mkdirSync35, readFileSync as readFileSync40, renameSync as renameSync13, writeFileSync as writeFileSync42 } from "fs";
|
|
44016
44330
|
import { join as join63, basename as basename17 } from "path";
|
|
44017
44331
|
function labDir(contextRoot) {
|
|
44018
44332
|
return join63(contextRoot, "lab");
|
|
@@ -44143,7 +44457,7 @@ function readInsightFile(filePath) {
|
|
|
44143
44457
|
}
|
|
44144
44458
|
function listInsights(contextRoot) {
|
|
44145
44459
|
const dir = insightsDir(contextRoot);
|
|
44146
|
-
if (!
|
|
44460
|
+
if (!existsSync61(dir)) return [];
|
|
44147
44461
|
const files = import_fast_glob15.default.sync("*.md", { cwd: dir, absolute: true }).sort();
|
|
44148
44462
|
const out = [];
|
|
44149
44463
|
for (const file of files) {
|
|
@@ -44156,7 +44470,7 @@ function listInsights(contextRoot) {
|
|
|
44156
44470
|
}
|
|
44157
44471
|
function getInsight(contextRoot, slug) {
|
|
44158
44472
|
const path2 = insightPath(contextRoot, slug);
|
|
44159
|
-
if (!isSafeInsightSlug(slug) || !
|
|
44473
|
+
if (!isSafeInsightSlug(slug) || !existsSync61(path2)) return null;
|
|
44160
44474
|
try {
|
|
44161
44475
|
return readInsightFile(path2);
|
|
44162
44476
|
} catch {
|
|
@@ -44165,7 +44479,7 @@ function getInsight(contextRoot, slug) {
|
|
|
44165
44479
|
}
|
|
44166
44480
|
function readCache(contextRoot, slug) {
|
|
44167
44481
|
const path2 = cachePath3(contextRoot, slug);
|
|
44168
|
-
if (!
|
|
44482
|
+
if (!existsSync61(path2)) return null;
|
|
44169
44483
|
try {
|
|
44170
44484
|
const parsed = JSON.parse(readFileSync40(path2, "utf-8"));
|
|
44171
44485
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
@@ -44202,7 +44516,7 @@ function createInsight(contextRoot, input2) {
|
|
|
44202
44516
|
validateManifestForWrite(input2);
|
|
44203
44517
|
const slug = input2.slug.trim();
|
|
44204
44518
|
const path2 = insightPath(contextRoot, slug);
|
|
44205
|
-
if (
|
|
44519
|
+
if (existsSync61(path2)) throw new LabError(`Insight already exists: ${slug}`);
|
|
44206
44520
|
const adapter = input2.adapter ?? "http";
|
|
44207
44521
|
const source = adapter === "script" ? { adapter: "script", script: { file: `scripts/${slug}.mjs` } } : {
|
|
44208
44522
|
adapter: "http",
|
|
@@ -44295,14 +44609,14 @@ var init_store2 = __esm({
|
|
|
44295
44609
|
});
|
|
44296
44610
|
|
|
44297
44611
|
// src/lib/lab/credentials.ts
|
|
44298
|
-
import { chmodSync as chmodSync5, existsSync as
|
|
44612
|
+
import { chmodSync as chmodSync5, existsSync as existsSync62, mkdirSync as mkdirSync36, readFileSync as readFileSync41, writeFileSync as writeFileSync43 } from "fs";
|
|
44299
44613
|
import { join as join64 } from "path";
|
|
44300
44614
|
function credentialsPath(contextRoot) {
|
|
44301
44615
|
return join64(contextRoot, "lab", "credentials.json");
|
|
44302
44616
|
}
|
|
44303
44617
|
function readCredentials(contextRoot) {
|
|
44304
44618
|
const path2 = credentialsPath(contextRoot);
|
|
44305
|
-
if (!
|
|
44619
|
+
if (!existsSync62(path2)) return {};
|
|
44306
44620
|
try {
|
|
44307
44621
|
const parsed = JSON.parse(readFileSync41(path2, "utf-8"));
|
|
44308
44622
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
@@ -44719,7 +45033,7 @@ var init_rollup = __esm({
|
|
|
44719
45033
|
|
|
44720
45034
|
// src/lib/lab/sync.ts
|
|
44721
45035
|
import { createHash as createHash5 } from "crypto";
|
|
44722
|
-
import { existsSync as
|
|
45036
|
+
import { existsSync as existsSync63, readFileSync as readFileSync42 } from "fs";
|
|
44723
45037
|
function appendHistory(prior, event) {
|
|
44724
45038
|
const bounded = event.error && event.error.length > HISTORY_ERROR_MAX ? { ...event, error: `${event.error.slice(0, HISTORY_ERROR_MAX)}\u2026` } : event;
|
|
44725
45039
|
const priorHistory = Array.isArray(prior?.history) ? prior.history : [];
|
|
@@ -44745,7 +45059,7 @@ function computeScriptHash(manifest) {
|
|
|
44745
45059
|
if (!manifest.source || manifest.source.adapter !== "script") return null;
|
|
44746
45060
|
try {
|
|
44747
45061
|
const abs = scriptFilePath(manifest);
|
|
44748
|
-
if (!
|
|
45062
|
+
if (!existsSync63(abs)) return null;
|
|
44749
45063
|
return createHash5("sha256").update(readFileSync42(abs)).digest("hex");
|
|
44750
45064
|
} catch {
|
|
44751
45065
|
return null;
|
|
@@ -45104,7 +45418,7 @@ var init_lab = __esm({
|
|
|
45104
45418
|
});
|
|
45105
45419
|
|
|
45106
45420
|
// src/cli/commands/update.ts
|
|
45107
|
-
import { existsSync as
|
|
45421
|
+
import { existsSync as existsSync64, readdirSync as readdirSync12, rmSync as rmSync8 } from "fs";
|
|
45108
45422
|
import { join as join65 } from "path";
|
|
45109
45423
|
function buildUpdateSummary(input2) {
|
|
45110
45424
|
const { platforms, installedCount, packs, removed, setupVersion } = input2;
|
|
@@ -45128,7 +45442,7 @@ function buildUpdateSummary(input2) {
|
|
|
45128
45442
|
}
|
|
45129
45443
|
function detectInstalledPlatforms(projectRoot) {
|
|
45130
45444
|
return SUPPORTED_PLATFORMS.filter(
|
|
45131
|
-
(p) =>
|
|
45445
|
+
(p) => existsSync64(join65(platformSkillRoot(projectRoot, p), "dreamcontext", "SKILL.md"))
|
|
45132
45446
|
);
|
|
45133
45447
|
}
|
|
45134
45448
|
function detectInstalledPacks(projectRoot, platforms) {
|
|
@@ -45141,11 +45455,11 @@ function detectInstalledPacks(projectRoot, platforms) {
|
|
|
45141
45455
|
const found = /* @__PURE__ */ new Set();
|
|
45142
45456
|
for (const platform2 of platforms) {
|
|
45143
45457
|
const root = platformSkillRoot(projectRoot, platform2);
|
|
45144
|
-
if (!
|
|
45458
|
+
if (!existsSync64(root)) continue;
|
|
45145
45459
|
for (const name of readdirSync12(root)) {
|
|
45146
45460
|
if (name === "dreamcontext") continue;
|
|
45147
45461
|
if (!knownNames.has(name)) continue;
|
|
45148
|
-
if (
|
|
45462
|
+
if (existsSync64(join65(root, name, "SKILL.md"))) found.add(name);
|
|
45149
45463
|
}
|
|
45150
45464
|
}
|
|
45151
45465
|
return [...found].sort();
|
|
@@ -45353,11 +45667,11 @@ var init_update = __esm({
|
|
|
45353
45667
|
});
|
|
45354
45668
|
|
|
45355
45669
|
// src/lib/core-index.ts
|
|
45356
|
-
import { existsSync as
|
|
45670
|
+
import { existsSync as existsSync65 } from "fs";
|
|
45357
45671
|
import { join as join66, basename as basename18 } from "path";
|
|
45358
45672
|
function buildCoreIndex(contextRoot) {
|
|
45359
45673
|
const coreDir = join66(contextRoot, "core");
|
|
45360
|
-
if (!
|
|
45674
|
+
if (!existsSync65(coreDir)) return [];
|
|
45361
45675
|
const files = import_fast_glob16.default.sync("[3-9]*", { cwd: coreDir, absolute: true });
|
|
45362
45676
|
const entries = [];
|
|
45363
45677
|
for (const file of files) {
|
|
@@ -45499,7 +45813,7 @@ var init_secrets2 = __esm({
|
|
|
45499
45813
|
|
|
45500
45814
|
// src/lib/marketing/store.ts
|
|
45501
45815
|
import {
|
|
45502
|
-
existsSync as
|
|
45816
|
+
existsSync as existsSync66,
|
|
45503
45817
|
mkdirSync as mkdirSync37,
|
|
45504
45818
|
openSync,
|
|
45505
45819
|
closeSync,
|
|
@@ -45557,7 +45871,7 @@ function pidAlive(pid) {
|
|
|
45557
45871
|
function acquireLock() {
|
|
45558
45872
|
const lockPath = MARKETING_PATHS.lockFile();
|
|
45559
45873
|
mkdirSync37(marketingRoot(), { recursive: true });
|
|
45560
|
-
if (
|
|
45874
|
+
if (existsSync66(lockPath)) {
|
|
45561
45875
|
const heldRaw = readFileSync43(lockPath, "utf8").trim();
|
|
45562
45876
|
const heldPid = Number.parseInt(heldRaw, 10);
|
|
45563
45877
|
if (pidAlive(heldPid)) {
|
|
@@ -45574,7 +45888,7 @@ function acquireLock() {
|
|
|
45574
45888
|
} catch (e) {
|
|
45575
45889
|
const code = e.code;
|
|
45576
45890
|
if (code === "EEXIST") {
|
|
45577
|
-
const heldRaw =
|
|
45891
|
+
const heldRaw = existsSync66(lockPath) ? readFileSync43(lockPath, "utf8").trim() : "?";
|
|
45578
45892
|
throw new LockBusyError(Number.parseInt(heldRaw, 10) || -1);
|
|
45579
45893
|
}
|
|
45580
45894
|
throw e;
|
|
@@ -45654,7 +45968,7 @@ function appendIndex(runId, verb, status) {
|
|
|
45654
45968
|
`;
|
|
45655
45969
|
let header2 = "";
|
|
45656
45970
|
let body = "";
|
|
45657
|
-
if (
|
|
45971
|
+
if (existsSync66(path2)) {
|
|
45658
45972
|
body = readFileSync43(path2, "utf8");
|
|
45659
45973
|
} else {
|
|
45660
45974
|
header2 = "# Marketing runs (LIFO)\n\n";
|
|
@@ -45685,7 +45999,7 @@ var init_store3 = __esm({
|
|
|
45685
45999
|
});
|
|
45686
46000
|
|
|
45687
46001
|
// src/lib/marketing/cohort.ts
|
|
45688
|
-
import { existsSync as
|
|
46002
|
+
import { existsSync as existsSync67, readFileSync as readFileSync44, readdirSync as readdirSync14 } from "fs";
|
|
45689
46003
|
import { join as join69 } from "path";
|
|
45690
46004
|
function newCohortId() {
|
|
45691
46005
|
return `coh_${idgen()}`;
|
|
@@ -45699,7 +46013,7 @@ function cohortPaths(id) {
|
|
|
45699
46013
|
}
|
|
45700
46014
|
function loadCohort(id) {
|
|
45701
46015
|
const { json } = cohortPaths(id);
|
|
45702
|
-
if (!
|
|
46016
|
+
if (!existsSync67(json)) return null;
|
|
45703
46017
|
try {
|
|
45704
46018
|
return JSON.parse(readFileSync44(json, "utf8"));
|
|
45705
46019
|
} catch {
|
|
@@ -45708,7 +46022,7 @@ function loadCohort(id) {
|
|
|
45708
46022
|
}
|
|
45709
46023
|
function listCohorts() {
|
|
45710
46024
|
const dir = MARKETING_PATHS.cohortsDir();
|
|
45711
|
-
if (!
|
|
46025
|
+
if (!existsSync67(dir)) return [];
|
|
45712
46026
|
const files = readdirSync14(dir).filter((f) => f.endsWith(".json"));
|
|
45713
46027
|
const cohorts = [];
|
|
45714
46028
|
for (const f of files) {
|
|
@@ -45766,7 +46080,7 @@ var init_cohort = __esm({
|
|
|
45766
46080
|
|
|
45767
46081
|
// src/lib/marketing/learnings.ts
|
|
45768
46082
|
import {
|
|
45769
|
-
existsSync as
|
|
46083
|
+
existsSync as existsSync68,
|
|
45770
46084
|
mkdirSync as mkdirSync38,
|
|
45771
46085
|
readFileSync as readFileSync45,
|
|
45772
46086
|
writeFileSync as writeFileSync45,
|
|
@@ -45788,7 +46102,7 @@ function todayDateString(now = /* @__PURE__ */ new Date()) {
|
|
|
45788
46102
|
}
|
|
45789
46103
|
function loadIndex() {
|
|
45790
46104
|
const path2 = MARKETING_PATHS.learningsIndex();
|
|
45791
|
-
if (!
|
|
46105
|
+
if (!existsSync68(path2)) {
|
|
45792
46106
|
return { version: INDEX_VERSION, entries: [] };
|
|
45793
46107
|
}
|
|
45794
46108
|
try {
|
|
@@ -45806,7 +46120,7 @@ function saveIndex(index) {
|
|
|
45806
46120
|
}
|
|
45807
46121
|
function loadByDate(date) {
|
|
45808
46122
|
const path2 = MARKETING_PATHS.learningsFile(date);
|
|
45809
|
-
if (!
|
|
46123
|
+
if (!existsSync68(path2)) return null;
|
|
45810
46124
|
return readFileSync45(path2, "utf8");
|
|
45811
46125
|
}
|
|
45812
46126
|
function renderEntryBlock(entry, body) {
|
|
@@ -45842,7 +46156,7 @@ function ensureDailyHeader(date, existing) {
|
|
|
45842
46156
|
}
|
|
45843
46157
|
function appendToDayFile(entry, body) {
|
|
45844
46158
|
const path2 = MARKETING_PATHS.learningsFile(entry.date_file);
|
|
45845
|
-
const existing =
|
|
46159
|
+
const existing = existsSync68(path2) ? readFileSync45(path2, "utf8") : null;
|
|
45846
46160
|
const base = ensureDailyHeader(entry.date_file, existing);
|
|
45847
46161
|
const block = renderEntryBlock(entry, body);
|
|
45848
46162
|
const next = existing && existing.startsWith("# Marketing learnings") ? existing.endsWith("\n") ? existing + block : existing + "\n" + block : base + block;
|
|
@@ -45850,7 +46164,7 @@ function appendToDayFile(entry, body) {
|
|
|
45850
46164
|
}
|
|
45851
46165
|
function rewriteDayFileForStatusUpdate(oldEntry, newEntry) {
|
|
45852
46166
|
const path2 = MARKETING_PATHS.learningsFile(oldEntry.date_file);
|
|
45853
|
-
if (!
|
|
46167
|
+
if (!existsSync68(path2)) return;
|
|
45854
46168
|
const text = readFileSync45(path2, "utf8");
|
|
45855
46169
|
const re = new RegExp(
|
|
45856
46170
|
`<!-- entry ([^>]*?id=${escapeRegExp(oldEntry.id)}[^>]*) -->`
|
|
@@ -45959,10 +46273,10 @@ var init_learnings = __esm({
|
|
|
45959
46273
|
});
|
|
45960
46274
|
|
|
45961
46275
|
// src/lib/marketing/snapshot.ts
|
|
45962
|
-
import { existsSync as
|
|
46276
|
+
import { existsSync as existsSync69, readFileSync as readFileSync46 } from "fs";
|
|
45963
46277
|
function buildMarketingSnapshot(opts = {}) {
|
|
45964
46278
|
const root = marketingRootIfExists();
|
|
45965
|
-
if (!root || !
|
|
46279
|
+
if (!root || !existsSync69(root)) return null;
|
|
45966
46280
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
45967
46281
|
const lines = ["## Marketing\n"];
|
|
45968
46282
|
const cohorts = listCohorts();
|
|
@@ -46019,7 +46333,7 @@ function cohortHypothesisLine(c) {
|
|
|
46019
46333
|
}
|
|
46020
46334
|
function readLastInsightsPull() {
|
|
46021
46335
|
const idxPath = MARKETING_PATHS.insightsDir() + "/_index.json";
|
|
46022
|
-
if (!
|
|
46336
|
+
if (!existsSync69(idxPath)) return null;
|
|
46023
46337
|
try {
|
|
46024
46338
|
const raw = JSON.parse(readFileSync46(idxPath, "utf8"));
|
|
46025
46339
|
return raw.updated_at && raw.updated_at !== "1970-01-01T00:00:00Z" ? raw.updated_at : null;
|
|
@@ -46119,7 +46433,7 @@ var init_setup_drift = __esm({
|
|
|
46119
46433
|
});
|
|
46120
46434
|
|
|
46121
46435
|
// src/lib/asset-drift-cache.ts
|
|
46122
|
-
import { existsSync as
|
|
46436
|
+
import { existsSync as existsSync70, readFileSync as readFileSync47, writeFileSync as writeFileSync46, mkdirSync as mkdirSync39 } from "fs";
|
|
46123
46437
|
import { join as join70, dirname as dirname35 } from "path";
|
|
46124
46438
|
function assetDriftCachePath(contextRoot) {
|
|
46125
46439
|
return join70(contextRoot, "state", ".asset-drift.json");
|
|
@@ -46127,7 +46441,7 @@ function assetDriftCachePath(contextRoot) {
|
|
|
46127
46441
|
function readAssetDriftCache(contextRoot) {
|
|
46128
46442
|
try {
|
|
46129
46443
|
const p = assetDriftCachePath(contextRoot);
|
|
46130
|
-
if (!
|
|
46444
|
+
if (!existsSync70(p)) return null;
|
|
46131
46445
|
const parsed = JSON.parse(readFileSync47(p, "utf-8"));
|
|
46132
46446
|
if (!parsed || typeof parsed.cliVersion !== "string" || typeof parsed.setupVersion !== "string" || typeof parsed.usedAssetsChanged !== "boolean") {
|
|
46133
46447
|
return null;
|
|
@@ -46267,14 +46581,14 @@ var init_federation_recall = __esm({
|
|
|
46267
46581
|
});
|
|
46268
46582
|
|
|
46269
46583
|
// src/lib/federation-peer-summary.ts
|
|
46270
|
-
import { existsSync as
|
|
46584
|
+
import { existsSync as existsSync71, mkdirSync as mkdirSync40, readFileSync as readFileSync48, writeFileSync as writeFileSync47 } from "fs";
|
|
46271
46585
|
import { dirname as dirname37, join as join71 } from "path";
|
|
46272
46586
|
function peerSummaryCachePath(contextRoot) {
|
|
46273
46587
|
return join71(contextRoot, CACHE_REL_PATH2);
|
|
46274
46588
|
}
|
|
46275
46589
|
function readPeerSummaryCache(contextRoot) {
|
|
46276
46590
|
const path2 = peerSummaryCachePath(contextRoot);
|
|
46277
|
-
if (!
|
|
46591
|
+
if (!existsSync71(path2)) return null;
|
|
46278
46592
|
try {
|
|
46279
46593
|
const parsed = JSON.parse(readFileSync48(path2, "utf-8"));
|
|
46280
46594
|
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.peers)) return null;
|
|
@@ -46294,7 +46608,8 @@ function sanitizePeer(raw) {
|
|
|
46294
46608
|
whatItIs: typeof raw.whatItIs === "string" ? raw.whatItIs : "",
|
|
46295
46609
|
lastActivity: strArr(raw.lastActivity),
|
|
46296
46610
|
activeTask: typeof raw.activeTask === "string" ? raw.activeTask : "",
|
|
46297
|
-
topTags: strArr(raw.topTags)
|
|
46611
|
+
topTags: strArr(raw.topTags),
|
|
46612
|
+
pinnedKnowledge: strArr(raw.pinnedKnowledge)
|
|
46298
46613
|
};
|
|
46299
46614
|
}
|
|
46300
46615
|
function buildPeerSummary(peerRoot, peerName) {
|
|
@@ -46303,12 +46618,13 @@ function buildPeerSummary(peerRoot, peerName) {
|
|
|
46303
46618
|
whatItIs: readWhatItIs(peerRoot),
|
|
46304
46619
|
lastActivity: readLastActivity(peerRoot),
|
|
46305
46620
|
activeTask: readActiveTask(peerRoot),
|
|
46306
|
-
topTags: readTopTags(peerRoot)
|
|
46621
|
+
topTags: readTopTags(peerRoot),
|
|
46622
|
+
pinnedKnowledge: readPinnedTitles(peerRoot)
|
|
46307
46623
|
};
|
|
46308
46624
|
}
|
|
46309
46625
|
function readWhatItIs(peerRoot) {
|
|
46310
46626
|
const soulPath = join71(peerRoot, "core", "0.soul.md");
|
|
46311
|
-
if (!
|
|
46627
|
+
if (!existsSync71(soulPath)) return "";
|
|
46312
46628
|
try {
|
|
46313
46629
|
const { data, content } = readFrontmatter(soulPath);
|
|
46314
46630
|
const name = typeof data.name === "string" ? data.name : "";
|
|
@@ -46326,7 +46642,7 @@ function readWhatItIs(peerRoot) {
|
|
|
46326
46642
|
}
|
|
46327
46643
|
function readLastActivity(peerRoot) {
|
|
46328
46644
|
const path2 = join71(peerRoot, "core", "CHANGELOG.json");
|
|
46329
|
-
if (!
|
|
46645
|
+
if (!existsSync71(path2)) return [];
|
|
46330
46646
|
try {
|
|
46331
46647
|
const entries = readJsonArray(path2);
|
|
46332
46648
|
const out = [];
|
|
@@ -46345,7 +46661,7 @@ function readLastActivity(peerRoot) {
|
|
|
46345
46661
|
}
|
|
46346
46662
|
function readActiveTask(peerRoot) {
|
|
46347
46663
|
const stateDir = join71(peerRoot, "state");
|
|
46348
|
-
if (!
|
|
46664
|
+
if (!existsSync71(stateDir)) return "";
|
|
46349
46665
|
let files;
|
|
46350
46666
|
try {
|
|
46351
46667
|
files = import_fast_glob17.default.sync("*.md", { cwd: stateDir, absolute: true });
|
|
@@ -46375,7 +46691,7 @@ function readTopTags(peerRoot) {
|
|
|
46375
46691
|
const counts = /* @__PURE__ */ new Map();
|
|
46376
46692
|
const dirs = [join71(peerRoot, "knowledge"), join71(peerRoot, "core", "features")];
|
|
46377
46693
|
for (const dir of dirs) {
|
|
46378
|
-
if (!
|
|
46694
|
+
if (!existsSync71(dir)) continue;
|
|
46379
46695
|
let files;
|
|
46380
46696
|
try {
|
|
46381
46697
|
files = import_fast_glob17.default.sync("*.md", { cwd: dir, absolute: true });
|
|
@@ -46396,6 +46712,32 @@ function readTopTags(peerRoot) {
|
|
|
46396
46712
|
}
|
|
46397
46713
|
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_TAGS).map(([t]) => t);
|
|
46398
46714
|
}
|
|
46715
|
+
function readPinnedTitles(peerRoot) {
|
|
46716
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46717
|
+
const globs = [
|
|
46718
|
+
[join71(peerRoot, "knowledge"), "**/*.md"],
|
|
46719
|
+
[join71(peerRoot, "core", "features"), "*.md"]
|
|
46720
|
+
];
|
|
46721
|
+
for (const [dir, pattern] of globs) {
|
|
46722
|
+
if (!existsSync71(dir)) continue;
|
|
46723
|
+
let files;
|
|
46724
|
+
try {
|
|
46725
|
+
files = import_fast_glob17.default.sync(pattern, { cwd: dir, absolute: true });
|
|
46726
|
+
} catch {
|
|
46727
|
+
continue;
|
|
46728
|
+
}
|
|
46729
|
+
for (const file of files) {
|
|
46730
|
+
try {
|
|
46731
|
+
const { data } = readFrontmatter(file);
|
|
46732
|
+
if (data.pinned !== true) continue;
|
|
46733
|
+
const title = String(data.name ?? data.title ?? "").trim();
|
|
46734
|
+
if (title) seen.add(title);
|
|
46735
|
+
} catch {
|
|
46736
|
+
}
|
|
46737
|
+
}
|
|
46738
|
+
}
|
|
46739
|
+
return Array.from(seen).sort((a, b) => a.localeCompare(b)).slice(0, MAX_PINNED);
|
|
46740
|
+
}
|
|
46399
46741
|
function refreshPeerSummaries(contextRoot, home) {
|
|
46400
46742
|
const { name, target } = currentVaultTarget(dirname37(contextRoot), home);
|
|
46401
46743
|
const targets = resolveConnectedVaults(target, contextRoot, home).filter(
|
|
@@ -46420,7 +46762,7 @@ function writePeerSummaryCache(contextRoot, cache) {
|
|
|
46420
46762
|
mkdirSync40(dirname37(path2), { recursive: true });
|
|
46421
46763
|
writeFileSync47(path2, JSON.stringify(cache, null, 2) + "\n", "utf-8");
|
|
46422
46764
|
}
|
|
46423
|
-
var import_fast_glob17, CACHE_REL_PATH2, MAX_ACTIVITY, MAX_TAGS, WHAT_IT_IS_CHARS;
|
|
46765
|
+
var import_fast_glob17, CACHE_REL_PATH2, MAX_ACTIVITY, MAX_TAGS, MAX_PINNED, WHAT_IT_IS_CHARS;
|
|
46424
46766
|
var init_federation_peer_summary = __esm({
|
|
46425
46767
|
"src/lib/federation-peer-summary.ts"() {
|
|
46426
46768
|
"use strict";
|
|
@@ -46432,6 +46774,7 @@ var init_federation_peer_summary = __esm({
|
|
|
46432
46774
|
CACHE_REL_PATH2 = "state/.peer-summaries.json";
|
|
46433
46775
|
MAX_ACTIVITY = 2;
|
|
46434
46776
|
MAX_TAGS = 5;
|
|
46777
|
+
MAX_PINNED = 5;
|
|
46435
46778
|
WHAT_IT_IS_CHARS = 200;
|
|
46436
46779
|
}
|
|
46437
46780
|
});
|
|
@@ -46541,7 +46884,7 @@ var init_snapshot_budget = __esm({
|
|
|
46541
46884
|
});
|
|
46542
46885
|
|
|
46543
46886
|
// src/cli/commands/snapshot.ts
|
|
46544
|
-
import { readFileSync as readFileSync49, existsSync as
|
|
46887
|
+
import { readFileSync as readFileSync49, existsSync as existsSync72, statSync as statSync10 } from "fs";
|
|
46545
46888
|
import { join as join72, basename as basename20, dirname as dirname38 } from "path";
|
|
46546
46889
|
function extractFirstParagraph(content) {
|
|
46547
46890
|
const lines = content.split("\n");
|
|
@@ -46577,7 +46920,7 @@ function sortTaskEntriesByActivity(entries) {
|
|
|
46577
46920
|
}
|
|
46578
46921
|
function getActiveTaskEntries(root) {
|
|
46579
46922
|
const stateDir = join72(root, "state");
|
|
46580
|
-
if (!
|
|
46923
|
+
if (!existsSync72(stateDir)) return [];
|
|
46581
46924
|
const taskFiles = import_fast_glob18.default.sync("*.md", { cwd: stateDir, absolute: true });
|
|
46582
46925
|
const entries = [];
|
|
46583
46926
|
const declaredFields = loadTaskOverride(root)?.customFields ?? [];
|
|
@@ -46626,14 +46969,14 @@ function getActiveTaskEntries(root) {
|
|
|
46626
46969
|
}
|
|
46627
46970
|
function resolveActiveTaskPath(root) {
|
|
46628
46971
|
const stateDir = join72(root, "state");
|
|
46629
|
-
if (!
|
|
46972
|
+
if (!existsSync72(stateDir)) return null;
|
|
46630
46973
|
const overridePath = join72(stateDir, ".active-task");
|
|
46631
|
-
if (
|
|
46974
|
+
if (existsSync72(overridePath)) {
|
|
46632
46975
|
try {
|
|
46633
46976
|
const slug = readFileSync49(overridePath, "utf-8").trim();
|
|
46634
46977
|
if (slug) {
|
|
46635
46978
|
const taskPath = join72(stateDir, `${slug}.md`);
|
|
46636
|
-
if (
|
|
46979
|
+
if (existsSync72(taskPath)) return taskPath;
|
|
46637
46980
|
}
|
|
46638
46981
|
} catch {
|
|
46639
46982
|
}
|
|
@@ -46677,7 +47020,7 @@ function getActiveProductKnowledge(root) {
|
|
|
46677
47020
|
if (!product) return [];
|
|
46678
47021
|
if (!config.multiProduct.includes(product)) return [];
|
|
46679
47022
|
const productKnowledgePath = join72(root, "knowledge", "products", `${product}.md`);
|
|
46680
|
-
if (!
|
|
47023
|
+
if (!existsSync72(productKnowledgePath)) return [];
|
|
46681
47024
|
let raw;
|
|
46682
47025
|
try {
|
|
46683
47026
|
raw = readFileSync49(productKnowledgePath, "utf-8");
|
|
@@ -46732,7 +47075,7 @@ function getVersionNudge(root) {
|
|
|
46732
47075
|
function getMigrationNote(root) {
|
|
46733
47076
|
try {
|
|
46734
47077
|
const sleepPath = join72(root, "state", ".sleep.json");
|
|
46735
|
-
if (!
|
|
47078
|
+
if (!existsSync72(sleepPath)) return "";
|
|
46736
47079
|
const raw = readFileSync49(sleepPath, "utf-8");
|
|
46737
47080
|
const parsed = JSON.parse(raw);
|
|
46738
47081
|
if (!parsed || !Array.isArray(parsed.pendingMigrationNotices) || parsed.pendingMigrationNotices.length === 0) {
|
|
@@ -46909,14 +47252,14 @@ function generateSnapshot(rootOverride) {
|
|
|
46909
47252
|
}
|
|
46910
47253
|
};
|
|
46911
47254
|
const soulPath = join72(root, "core", "0.soul.md");
|
|
46912
|
-
if (
|
|
47255
|
+
if (existsSync72(soulPath)) {
|
|
46913
47256
|
const content = readFileSync49(soulPath, "utf-8").trim();
|
|
46914
47257
|
parts.push("## Soul (Agent Identity, Principles, Rules)\n");
|
|
46915
47258
|
parts.push(content);
|
|
46916
47259
|
parts.push("");
|
|
46917
47260
|
}
|
|
46918
47261
|
const userPath = join72(root, "core", "1.user.md");
|
|
46919
|
-
if (
|
|
47262
|
+
if (existsSync72(userPath)) {
|
|
46920
47263
|
const content = readFileSync49(userPath, "utf-8").trim();
|
|
46921
47264
|
parts.push("## User (Preferences, Project Details, Rules)\n");
|
|
46922
47265
|
parts.push(content);
|
|
@@ -46931,7 +47274,7 @@ function generateSnapshot(rootOverride) {
|
|
|
46931
47274
|
flush("task-override", { neverEvict: true });
|
|
46932
47275
|
}
|
|
46933
47276
|
const memoryPath = join72(root, "core", "2.memory.md");
|
|
46934
|
-
if (
|
|
47277
|
+
if (existsSync72(memoryPath)) {
|
|
46935
47278
|
const content = readFileSync49(memoryPath, "utf-8").trim();
|
|
46936
47279
|
if (content) {
|
|
46937
47280
|
parts.push("## Memory (Technical Decisions, Known Issues, Session Log)\n");
|
|
@@ -46998,7 +47341,7 @@ function generateSnapshot(rootOverride) {
|
|
|
46998
47341
|
const taskNames = [];
|
|
46999
47342
|
const taskTags = [];
|
|
47000
47343
|
const stateDir = join72(root, "state");
|
|
47001
|
-
if (
|
|
47344
|
+
if (existsSync72(stateDir)) {
|
|
47002
47345
|
const taskFiles = import_fast_glob18.default.sync("*.md", { cwd: stateDir, absolute: true });
|
|
47003
47346
|
for (const file of taskFiles) {
|
|
47004
47347
|
try {
|
|
@@ -47041,7 +47384,7 @@ function generateSnapshot(rootOverride) {
|
|
|
47041
47384
|
return authors.length > 0 ? ` \u2014 by ${authors.join(", ")}` : "";
|
|
47042
47385
|
};
|
|
47043
47386
|
const changelogPath = join72(root, "core", "CHANGELOG.json");
|
|
47044
|
-
if (
|
|
47387
|
+
if (existsSync72(changelogPath)) {
|
|
47045
47388
|
try {
|
|
47046
47389
|
const entries = readJsonArray(changelogPath);
|
|
47047
47390
|
const tier1 = entries.slice(0, CHANGELOG_TIER1);
|
|
@@ -47098,7 +47441,7 @@ function generateSnapshot(rootOverride) {
|
|
|
47098
47441
|
}
|
|
47099
47442
|
}
|
|
47100
47443
|
const releasesPath = join72(root, "core", "RELEASES.json");
|
|
47101
|
-
if (
|
|
47444
|
+
if (existsSync72(releasesPath)) {
|
|
47102
47445
|
try {
|
|
47103
47446
|
const releases = readJsonArray(releasesPath);
|
|
47104
47447
|
if (releases.length > 0) {
|
|
@@ -47151,7 +47494,7 @@ function generateSnapshot(rootOverride) {
|
|
|
47151
47494
|
});
|
|
47152
47495
|
}
|
|
47153
47496
|
const featuresPath = featuresDir(root);
|
|
47154
|
-
if (
|
|
47497
|
+
if (existsSync72(featuresPath)) {
|
|
47155
47498
|
const featureFiles = import_fast_glob18.default.sync("*.md", { cwd: featuresPath, absolute: true });
|
|
47156
47499
|
const features = [];
|
|
47157
47500
|
const featureMeta = [];
|
|
@@ -47240,7 +47583,7 @@ function generateSnapshot(rootOverride) {
|
|
|
47240
47583
|
const warmEntries = [];
|
|
47241
47584
|
const activeTaskTags = [];
|
|
47242
47585
|
const stDir = join72(root, "state");
|
|
47243
|
-
if (
|
|
47586
|
+
if (existsSync72(stDir)) {
|
|
47244
47587
|
const tFiles = import_fast_glob18.default.sync("*.md", { cwd: stDir, absolute: true });
|
|
47245
47588
|
for (const file of tFiles) {
|
|
47246
47589
|
try {
|
|
@@ -47372,6 +47715,7 @@ ${pendingFederation} legacy peer digest entr${pendingFederation === 1 ? "y" : "i
|
|
|
47372
47715
|
for (const act of p.lastActivity) lines.push(` Last: ${act}`);
|
|
47373
47716
|
if (p.activeTask) lines.push(` In progress: ${p.activeTask}`);
|
|
47374
47717
|
if (p.topTags.length > 0) lines.push(` Tags: ${p.topTags.join(", ")}`);
|
|
47718
|
+
if (p.pinnedKnowledge.length > 0) lines.push(` Pinned docs: ${p.pinnedKnowledge.join(", ")}`);
|
|
47375
47719
|
}
|
|
47376
47720
|
lines.push("");
|
|
47377
47721
|
lines.push(
|
|
@@ -47403,7 +47747,7 @@ function generateSubagentBriefing() {
|
|
|
47403
47747
|
parts.push("");
|
|
47404
47748
|
}
|
|
47405
47749
|
const soulPath = join72(root, "core", "0.soul.md");
|
|
47406
|
-
if (
|
|
47750
|
+
if (existsSync72(soulPath)) {
|
|
47407
47751
|
const { data, content } = readFrontmatter(soulPath);
|
|
47408
47752
|
const projectName = typeof data.name === "string" ? data.name : "";
|
|
47409
47753
|
const lines = content.split("\n");
|
|
@@ -47438,7 +47782,7 @@ function generateSubagentBriefing() {
|
|
|
47438
47782
|
} catch {
|
|
47439
47783
|
}
|
|
47440
47784
|
const featuresPath = featuresDir(root);
|
|
47441
|
-
if (
|
|
47785
|
+
if (existsSync72(featuresPath)) {
|
|
47442
47786
|
const featureFiles = import_fast_glob18.default.sync("*.md", { cwd: featuresPath, absolute: true });
|
|
47443
47787
|
const features = [];
|
|
47444
47788
|
for (const file of featureFiles) {
|
|
@@ -47506,7 +47850,7 @@ function generateSubagentBriefing() {
|
|
|
47506
47850
|
parts.push("");
|
|
47507
47851
|
}
|
|
47508
47852
|
const coreDir = join72(root, "core");
|
|
47509
|
-
if (
|
|
47853
|
+
if (existsSync72(coreDir)) {
|
|
47510
47854
|
const allCoreFiles = import_fast_glob18.default.sync(["[0-9]*"], { cwd: coreDir, absolute: true });
|
|
47511
47855
|
allCoreFiles.sort((a, b) => basename20(a).localeCompare(basename20(b), void 0, { numeric: true }));
|
|
47512
47856
|
if (allCoreFiles.length > 0) {
|
|
@@ -47608,7 +47952,7 @@ var init_snapshot2 = __esm({
|
|
|
47608
47952
|
});
|
|
47609
47953
|
|
|
47610
47954
|
// src/cli/commands/transcript.ts
|
|
47611
|
-
import { readFileSync as readFileSync50, existsSync as
|
|
47955
|
+
import { readFileSync as readFileSync50, existsSync as existsSync73, statSync as statSync11 } from "fs";
|
|
47612
47956
|
function isSystemNoiseMessage(text) {
|
|
47613
47957
|
const t = text.trim();
|
|
47614
47958
|
if (!t) return true;
|
|
@@ -47627,7 +47971,7 @@ function distillTranscript(transcriptPath, sinceTimestamp) {
|
|
|
47627
47971
|
errors: [],
|
|
47628
47972
|
bookmarks: []
|
|
47629
47973
|
};
|
|
47630
|
-
if (!
|
|
47974
|
+
if (!existsSync73(transcriptPath)) return result;
|
|
47631
47975
|
try {
|
|
47632
47976
|
const stat = statSync11(transcriptPath);
|
|
47633
47977
|
if (stat.size === 0 || stat.size > MAX_TRANSCRIPT_BYTES) return result;
|
|
@@ -47806,7 +48150,7 @@ function registerTranscriptCommand(program2) {
|
|
|
47806
48150
|
error(`No transcript path for session: ${sessionId}`);
|
|
47807
48151
|
return;
|
|
47808
48152
|
}
|
|
47809
|
-
if (!
|
|
48153
|
+
if (!existsSync73(session.transcript_path)) {
|
|
47810
48154
|
error(`Transcript file not found: ${session.transcript_path}`);
|
|
47811
48155
|
return;
|
|
47812
48156
|
}
|
|
@@ -47900,7 +48244,7 @@ var init_salience = __esm({
|
|
|
47900
48244
|
});
|
|
47901
48245
|
|
|
47902
48246
|
// src/lib/marketing/path-guards.ts
|
|
47903
|
-
import { existsSync as
|
|
48247
|
+
import { existsSync as existsSync74, realpathSync as realpathSync3 } from "fs";
|
|
47904
48248
|
import { basename as basename21, dirname as dirname39, resolve as resolve13, sep as sep9 } from "path";
|
|
47905
48249
|
function isMarketingEnvPath(filePath, from) {
|
|
47906
48250
|
if (!filePath) return false;
|
|
@@ -47915,7 +48259,7 @@ function isMarketingEnvPath(filePath, from) {
|
|
|
47915
48259
|
}
|
|
47916
48260
|
function realpathOrSelf(p) {
|
|
47917
48261
|
try {
|
|
47918
|
-
return
|
|
48262
|
+
return existsSync74(p) ? realpathSync3(p) : p;
|
|
47919
48263
|
} catch {
|
|
47920
48264
|
return p;
|
|
47921
48265
|
}
|
|
@@ -47923,7 +48267,7 @@ function realpathOrSelf(p) {
|
|
|
47923
48267
|
function realpathOfNearestAncestor(p) {
|
|
47924
48268
|
let current = p;
|
|
47925
48269
|
const tail = [];
|
|
47926
|
-
while (current && current !== sep9 && !
|
|
48270
|
+
while (current && current !== sep9 && !existsSync74(current)) {
|
|
47927
48271
|
tail.unshift(basename21(current));
|
|
47928
48272
|
current = dirname39(current);
|
|
47929
48273
|
}
|
|
@@ -47943,6 +48287,9 @@ var init_path_guards = __esm({
|
|
|
47943
48287
|
});
|
|
47944
48288
|
|
|
47945
48289
|
// src/lib/embeddings/hybrid.ts
|
|
48290
|
+
function hybridReady(root, mode) {
|
|
48291
|
+
return mode === "hybrid" && isEmbedModelDownloaded() && embeddingCacheUsable(root);
|
|
48292
|
+
}
|
|
47946
48293
|
function denseRank(queryVec, index, topK = POOL) {
|
|
47947
48294
|
const best = /* @__PURE__ */ new Map();
|
|
47948
48295
|
for (const chunk of index.chunks) {
|
|
@@ -48001,7 +48348,11 @@ function fallbackSnippet(doc) {
|
|
|
48001
48348
|
async function hybridSearch(query, corpus, contextRoot, topK = 10, opts = {}) {
|
|
48002
48349
|
const bm25Hits = bm25Search(query, corpus, POOL, opts);
|
|
48003
48350
|
const [refreshed, queryVec] = await Promise.all([
|
|
48004
|
-
|
|
48351
|
+
// ADD-ONLY: `corpus` may be type-scoped (e.g. the dashboard Knowledge search
|
|
48352
|
+
// asks only for knowledge+feature). Never evict out-of-scope vectors here, or
|
|
48353
|
+
// the next full-corpus query would re-embed the whole corpus inline. Pruning
|
|
48354
|
+
// is the explicit refreshers' job.
|
|
48355
|
+
refreshEmbeddings(contextRoot, corpus, void 0, { additive: true }),
|
|
48005
48356
|
embedQuery(query)
|
|
48006
48357
|
]);
|
|
48007
48358
|
if (refreshed === null || queryVec === null) return bm25Hits.slice(0, topK);
|
|
@@ -48211,7 +48562,7 @@ If pure greeting: {"skip":true}`;
|
|
|
48211
48562
|
});
|
|
48212
48563
|
|
|
48213
48564
|
// src/cli/commands/asset-drift.ts
|
|
48214
|
-
import { mkdtempSync as mkdtempSync2, rmSync as rmSync9, existsSync as
|
|
48565
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync9, existsSync as existsSync75, readFileSync as readFileSync51, readdirSync as readdirSync15 } from "fs";
|
|
48215
48566
|
import { tmpdir as tmpdir3 } from "os";
|
|
48216
48567
|
import { join as join73, dirname as dirname40 } from "path";
|
|
48217
48568
|
function walkFiles(dir, base, out) {
|
|
@@ -48236,7 +48587,7 @@ async function computeUsedAssetsChanged(projectRoot, config) {
|
|
|
48236
48587
|
if (rel.endsWith("settings.json")) continue;
|
|
48237
48588
|
if (rel.startsWith("_dream_context/")) continue;
|
|
48238
48589
|
const onDisk = join73(projectRoot, rel);
|
|
48239
|
-
if (!
|
|
48590
|
+
if (!existsSync75(onDisk)) return true;
|
|
48240
48591
|
if (!readFileSync51(join73(tmp, rel)).equals(readFileSync51(onDisk))) return true;
|
|
48241
48592
|
}
|
|
48242
48593
|
return false;
|
|
@@ -48278,7 +48629,7 @@ var init_asset_drift = __esm({
|
|
|
48278
48629
|
});
|
|
48279
48630
|
|
|
48280
48631
|
// src/lib/initializer-detect.ts
|
|
48281
|
-
import { existsSync as
|
|
48632
|
+
import { existsSync as existsSync76, statSync as statSync12, readdirSync as readdirSync16, readFileSync as readFileSync52 } from "fs";
|
|
48282
48633
|
import { join as join74, dirname as dirname41, basename as basename22, extname as extname2, isAbsolute as isAbsolute2, resolve as resolve14, sep as sep10 } from "path";
|
|
48283
48634
|
import { homedir as homedir5 } from "os";
|
|
48284
48635
|
function isUntouchedTemplateCore(root) {
|
|
@@ -48288,7 +48639,7 @@ function isUntouchedTemplateCore(root) {
|
|
|
48288
48639
|
let templateCount = 0;
|
|
48289
48640
|
for (const f of files) {
|
|
48290
48641
|
const p = join74(root, "core", f);
|
|
48291
|
-
if (!
|
|
48642
|
+
if (!existsSync76(p)) continue;
|
|
48292
48643
|
let content;
|
|
48293
48644
|
try {
|
|
48294
48645
|
content = readFileSync52(p, "utf-8");
|
|
@@ -48308,7 +48659,7 @@ function isUntouchedTemplateCore(root) {
|
|
|
48308
48659
|
function knowledgeIsEmpty(root) {
|
|
48309
48660
|
try {
|
|
48310
48661
|
const kdir = join74(root, "knowledge");
|
|
48311
|
-
if (!
|
|
48662
|
+
if (!existsSync76(kdir)) return true;
|
|
48312
48663
|
const stack = [{ dir: kdir, top: true }];
|
|
48313
48664
|
while (stack.length) {
|
|
48314
48665
|
const { dir, top } = stack.pop();
|
|
@@ -48336,7 +48687,7 @@ function knowledgeIsEmpty(root) {
|
|
|
48336
48687
|
function featuresAreZero(root) {
|
|
48337
48688
|
try {
|
|
48338
48689
|
const fdir = featuresDir(root);
|
|
48339
|
-
if (!
|
|
48690
|
+
if (!existsSync76(fdir)) return true;
|
|
48340
48691
|
const entries = readdirSync16(fdir, { withFileTypes: true });
|
|
48341
48692
|
return !entries.some(
|
|
48342
48693
|
(e) => e.isFile() && !e.name.startsWith(".") && e.name.toLowerCase().endsWith(".md")
|
|
@@ -48358,7 +48709,7 @@ function classifyBrain(root) {
|
|
|
48358
48709
|
function hasProjectSignal(cwd) {
|
|
48359
48710
|
try {
|
|
48360
48711
|
for (const m of PROJECT_MARKERS) {
|
|
48361
|
-
if (
|
|
48712
|
+
if (existsSync76(join74(cwd, m))) return true;
|
|
48362
48713
|
}
|
|
48363
48714
|
for (const d of PROJECT_DIRS) {
|
|
48364
48715
|
try {
|
|
@@ -48650,7 +49001,7 @@ var init_initializer_detect = __esm({
|
|
|
48650
49001
|
});
|
|
48651
49002
|
|
|
48652
49003
|
// src/lib/agent-session-map.ts
|
|
48653
|
-
import { existsSync as
|
|
49004
|
+
import { existsSync as existsSync77, lstatSync as lstatSync3, mkdirSync as mkdirSync41, readFileSync as readFileSync53, writeFileSync as writeFileSync48, renameSync as renameSync16, readdirSync as readdirSync17, unlinkSync as unlinkSync9, statSync as statSync13 } from "fs";
|
|
48654
49005
|
import { join as join75, dirname as dirname42, basename as basename23 } from "path";
|
|
48655
49006
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
48656
49007
|
function mapDir(contextRoot) {
|
|
@@ -48680,10 +49031,10 @@ function listEntryFiles(dir) {
|
|
|
48680
49031
|
}
|
|
48681
49032
|
function ensureMapDir(contextRoot) {
|
|
48682
49033
|
const stateDir = join75(contextRoot, "state");
|
|
48683
|
-
if (
|
|
49034
|
+
if (existsSync77(stateDir) && !lstatSync3(stateDir).isDirectory()) return null;
|
|
48684
49035
|
const dir = mapDir(contextRoot);
|
|
48685
|
-
if (
|
|
48686
|
-
if (!
|
|
49036
|
+
if (existsSync77(dir) && !lstatSync3(dir).isDirectory()) return null;
|
|
49037
|
+
if (!existsSync77(dir)) {
|
|
48687
49038
|
try {
|
|
48688
49039
|
ensureGitignoreEntries(dirname42(contextRoot), ["_dream_context/state/.agent-session-map/"], {
|
|
48689
49040
|
comment: "dreamcontext: machine-local agent tab \u2192 live Claude session map"
|
|
@@ -48705,7 +49056,7 @@ function recordAgentSession(contextRoot, tabId, sessionId) {
|
|
|
48705
49056
|
const dir = ensureMapDir(contextRoot);
|
|
48706
49057
|
if (!dir) return;
|
|
48707
49058
|
const path2 = join75(dir, `${tabId}.json`);
|
|
48708
|
-
if (
|
|
49059
|
+
if (existsSync77(path2) && !lstatSync3(path2).isFile()) return;
|
|
48709
49060
|
const prev = readEntry(path2);
|
|
48710
49061
|
const entry = { current: sessionId, updated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
48711
49062
|
if (prev?.current === sessionId && prev.firstPrompt) entry.firstPrompt = prev.firstPrompt;
|
|
@@ -48773,7 +49124,7 @@ function recordAgentFirstPrompt(contextRoot, tabId, sessionId, prompt) {
|
|
|
48773
49124
|
const dir = ensureMapDir(contextRoot);
|
|
48774
49125
|
if (!dir) return;
|
|
48775
49126
|
const path2 = join75(dir, `${tabId}.json`);
|
|
48776
|
-
if (
|
|
49127
|
+
if (existsSync77(path2) && !lstatSync3(path2).isFile()) return;
|
|
48777
49128
|
const prev = readEntry(path2);
|
|
48778
49129
|
if (prev?.current === sessionId && prev.firstPrompt) return;
|
|
48779
49130
|
writeEntryAtomic(path2, { current: sessionId, updated: (/* @__PURE__ */ new Date()).toISOString(), firstPrompt: clean });
|
|
@@ -48796,7 +49147,7 @@ var init_agent_session_map = __esm({
|
|
|
48796
49147
|
});
|
|
48797
49148
|
|
|
48798
49149
|
// src/cli/commands/hook.ts
|
|
48799
|
-
import { readFileSync as readFileSync54, existsSync as
|
|
49150
|
+
import { readFileSync as readFileSync54, existsSync as existsSync78, statSync as statSync14 } from "fs";
|
|
48800
49151
|
import { execFileSync as execFileSync9, spawn as spawn3 } from "child_process";
|
|
48801
49152
|
import { get as httpGet, request as httpRequest } from "http";
|
|
48802
49153
|
import { dirname as dirname43, resolve as resolve15, join as join76, extname as extname3, basename as basename24, relative as relative5 } from "path";
|
|
@@ -48813,7 +49164,7 @@ function readStdin() {
|
|
|
48813
49164
|
}
|
|
48814
49165
|
}
|
|
48815
49166
|
function analyzeTranscript(transcriptPath) {
|
|
48816
|
-
if (!
|
|
49167
|
+
if (!existsSync78(transcriptPath)) return ZERO_ANALYSIS;
|
|
48817
49168
|
try {
|
|
48818
49169
|
const stat = statSync14(transcriptPath);
|
|
48819
49170
|
if (stat.size === 0 || stat.size > MAX_TRANSCRIPT_BYTES2) return ZERO_ANALYSIS;
|
|
@@ -48919,21 +49270,21 @@ function findProjectConfig(filePath) {
|
|
|
48919
49270
|
for (let i = 0; i <= MAX_WALK_LEVELS; i++) {
|
|
48920
49271
|
if (!formatter) {
|
|
48921
49272
|
for (const name of BIOME_CONFIGS) {
|
|
48922
|
-
if (
|
|
49273
|
+
if (existsSync78(join76(dir, name))) {
|
|
48923
49274
|
formatter = { type: "biome", configPath: join76(dir, name), projectRoot: dir };
|
|
48924
49275
|
break;
|
|
48925
49276
|
}
|
|
48926
49277
|
}
|
|
48927
49278
|
if (!formatter) {
|
|
48928
49279
|
for (const name of PRETTIER_CONFIGS) {
|
|
48929
|
-
if (
|
|
49280
|
+
if (existsSync78(join76(dir, name))) {
|
|
48930
49281
|
formatter = { type: "prettier", configPath: join76(dir, name), projectRoot: dir };
|
|
48931
49282
|
break;
|
|
48932
49283
|
}
|
|
48933
49284
|
}
|
|
48934
49285
|
}
|
|
48935
49286
|
}
|
|
48936
|
-
if (!tsconfig &&
|
|
49287
|
+
if (!tsconfig && existsSync78(join76(dir, "tsconfig.json"))) {
|
|
48937
49288
|
tsconfig = join76(dir, "tsconfig.json");
|
|
48938
49289
|
}
|
|
48939
49290
|
if (formatter && tsconfig) break;
|
|
@@ -48945,7 +49296,7 @@ function findProjectConfig(filePath) {
|
|
|
48945
49296
|
}
|
|
48946
49297
|
function resolveLocalBin(binName, projectRoot) {
|
|
48947
49298
|
const localBin = join76(projectRoot, "node_modules", ".bin", binName);
|
|
48948
|
-
return
|
|
49299
|
+
return existsSync78(localBin) ? localBin : null;
|
|
48949
49300
|
}
|
|
48950
49301
|
function runFormatter(detection, filePath) {
|
|
48951
49302
|
try {
|
|
@@ -49256,7 +49607,7 @@ function registerHookCommand(program2) {
|
|
|
49256
49607
|
recordTabSessionFromHook(root, sessionId);
|
|
49257
49608
|
const state = readSleepState(root);
|
|
49258
49609
|
const stoppedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
49259
|
-
const transcriptOnDisk = !!transcriptPath &&
|
|
49610
|
+
const transcriptOnDisk = !!transcriptPath && existsSync78(transcriptPath);
|
|
49260
49611
|
const analysis = transcriptOnDisk ? analyzeTranscript(transcriptPath) : ZERO_ANALYSIS;
|
|
49261
49612
|
const { changeCount, toolCount } = analysis;
|
|
49262
49613
|
const score = transcriptOnDisk ? Math.max(
|
|
@@ -49353,7 +49704,7 @@ function registerHookCommand(program2) {
|
|
|
49353
49704
|
dirty = true;
|
|
49354
49705
|
continue;
|
|
49355
49706
|
}
|
|
49356
|
-
if (!
|
|
49707
|
+
if (!existsSync78(session.transcript_path)) {
|
|
49357
49708
|
const stoppedMs = Date.parse(session.stopped_at ?? "") || 0;
|
|
49358
49709
|
if (Date.now() - stoppedMs < 7 * 24 * 60 * 60 * 1e3) continue;
|
|
49359
49710
|
session.change_count = 0;
|
|
@@ -49376,7 +49727,7 @@ function registerHookCommand(program2) {
|
|
|
49376
49727
|
}
|
|
49377
49728
|
for (const session of state.sessions) {
|
|
49378
49729
|
if (!session.transcript_path) continue;
|
|
49379
|
-
if (!
|
|
49730
|
+
if (!existsSync78(session.transcript_path)) continue;
|
|
49380
49731
|
if (digestExists(root, session.session_id) && !digestIsPartial(root, session.session_id)) continue;
|
|
49381
49732
|
try {
|
|
49382
49733
|
const distilled = distillTranscript(session.transcript_path);
|
|
@@ -49425,7 +49776,8 @@ function registerHookCommand(program2) {
|
|
|
49425
49776
|
const projectRoot = dirname43(root);
|
|
49426
49777
|
const cfg = readSetupConfig(projectRoot);
|
|
49427
49778
|
const enabledResolution = resolveBrainSyncEnabled(projectRoot, cfg);
|
|
49428
|
-
|
|
49779
|
+
const pullMode = cfg?.brainRepo?.mode;
|
|
49780
|
+
if (enabledResolution.enabled && (pullMode === "separate" || pullMode === "full-repo") && cfg?.brainRepo?.autoSync) {
|
|
49429
49781
|
spawnBrainPull(root);
|
|
49430
49782
|
}
|
|
49431
49783
|
const local = readBrainLocal(projectRoot);
|
|
@@ -49567,7 +49919,7 @@ function registerHookCommand(program2) {
|
|
|
49567
49919
|
try {
|
|
49568
49920
|
const prompt = String(input2.prompt ?? "");
|
|
49569
49921
|
if (prompt.trim().length >= 8) {
|
|
49570
|
-
const recallMode =
|
|
49922
|
+
const recallMode = resolveRecallMode(root);
|
|
49571
49923
|
if (recallMode !== "off") {
|
|
49572
49924
|
let hits = [];
|
|
49573
49925
|
let mode = "BM25";
|
|
@@ -49585,7 +49937,7 @@ function registerHookCommand(program2) {
|
|
|
49585
49937
|
const corpus = buildCorpus(root);
|
|
49586
49938
|
hits = bm25Search(prompt, corpus, 3);
|
|
49587
49939
|
}
|
|
49588
|
-
} else if (recallMode
|
|
49940
|
+
} else if (hybridReady(root, recallMode)) {
|
|
49589
49941
|
const corpus = buildCorpus(root);
|
|
49590
49942
|
hits = await hybridSearch(prompt, corpus, root, 3);
|
|
49591
49943
|
mode = "Hybrid";
|
|
@@ -49723,7 +50075,7 @@ function registerHookCommand(program2) {
|
|
|
49723
50075
|
try {
|
|
49724
50076
|
const sessionId = input2 && typeof input2.session_id === "string" ? input2.session_id : "";
|
|
49725
50077
|
const transcriptPath = input2 && typeof input2.transcript_path === "string" ? input2.transcript_path : "";
|
|
49726
|
-
if (sessionId && transcriptPath &&
|
|
50078
|
+
if (sessionId && transcriptPath && existsSync78(transcriptPath)) {
|
|
49727
50079
|
const distilled = distillTranscript(transcriptPath);
|
|
49728
50080
|
writeDigest(root, sessionId, buildDigest(distilled), { partial: true });
|
|
49729
50081
|
}
|
|
@@ -49839,7 +50191,7 @@ var init_hook = __esm({
|
|
|
49839
50191
|
});
|
|
49840
50192
|
|
|
49841
50193
|
// src/cli/commands/doctor.ts
|
|
49842
|
-
import { existsSync as
|
|
50194
|
+
import { existsSync as existsSync79, readFileSync as readFileSync55, readdirSync as readdirSync18, statSync as statSync15 } from "fs";
|
|
49843
50195
|
import { join as join77 } from "path";
|
|
49844
50196
|
import { dirname as dirname44 } from "path";
|
|
49845
50197
|
function stripDocumentedMentions(content) {
|
|
@@ -49850,7 +50202,7 @@ function stripDocumentedMentions(content) {
|
|
|
49850
50202
|
}
|
|
49851
50203
|
function checkFile(root, relPath, label, required) {
|
|
49852
50204
|
const fullPath = join77(root, relPath);
|
|
49853
|
-
if (!
|
|
50205
|
+
if (!existsSync79(fullPath)) {
|
|
49854
50206
|
return {
|
|
49855
50207
|
name: label,
|
|
49856
50208
|
status: required ? "error" : "warn",
|
|
@@ -49880,7 +50232,7 @@ function checkFile(root, relPath, label, required) {
|
|
|
49880
50232
|
}
|
|
49881
50233
|
function checkJson(root, relPath, label) {
|
|
49882
50234
|
const fullPath = join77(root, relPath);
|
|
49883
|
-
if (!
|
|
50235
|
+
if (!existsSync79(fullPath)) {
|
|
49884
50236
|
return { name: label, status: "error", message: `Missing: ${relPath}` };
|
|
49885
50237
|
}
|
|
49886
50238
|
try {
|
|
@@ -49893,7 +50245,7 @@ function checkJson(root, relPath, label) {
|
|
|
49893
50245
|
}
|
|
49894
50246
|
function checkDirectory(root, relPath, label) {
|
|
49895
50247
|
const fullPath = join77(root, relPath);
|
|
49896
|
-
if (!
|
|
50248
|
+
if (!existsSync79(fullPath)) {
|
|
49897
50249
|
return { name: label, status: "error", message: `Missing directory: ${relPath}` };
|
|
49898
50250
|
}
|
|
49899
50251
|
return { name: label, status: "ok", message: relPath };
|
|
@@ -49904,10 +50256,10 @@ function checkDataStructures(root) {
|
|
|
49904
50256
|
const dirAbs = join77(root, dirRel);
|
|
49905
50257
|
const oldRel = "core/data-structures";
|
|
49906
50258
|
const oldAbs = join77(root, oldRel);
|
|
49907
|
-
const oldExists =
|
|
50259
|
+
const oldExists = existsSync79(oldAbs);
|
|
49908
50260
|
const legacyRel = "core/5.data_structures.sql";
|
|
49909
|
-
const legacyExists =
|
|
49910
|
-
if (!
|
|
50261
|
+
const legacyExists = existsSync79(join77(root, legacyRel));
|
|
50262
|
+
if (!existsSync79(dirAbs)) {
|
|
49911
50263
|
if (oldExists) {
|
|
49912
50264
|
results.push({
|
|
49913
50265
|
name: "Data structures",
|
|
@@ -49980,7 +50332,7 @@ function checkDataStructures(root) {
|
|
|
49980
50332
|
function checkFeaturesMigrated(root) {
|
|
49981
50333
|
const oldRel = "core/features";
|
|
49982
50334
|
const oldAbs = join77(root, oldRel);
|
|
49983
|
-
if (!
|
|
50335
|
+
if (!existsSync79(oldAbs)) {
|
|
49984
50336
|
return { name: "Features (migration)", status: "ok", message: "knowledge/features/" };
|
|
49985
50337
|
}
|
|
49986
50338
|
let mdFiles = [];
|
|
@@ -50075,7 +50427,7 @@ function checkLab(root) {
|
|
|
50075
50427
|
const results = [];
|
|
50076
50428
|
const insights = listInsights(root);
|
|
50077
50429
|
const credentialsPath2 = join77(root, "lab", "credentials.json");
|
|
50078
|
-
if (
|
|
50430
|
+
if (existsSync79(credentialsPath2)) {
|
|
50079
50431
|
const projectRoot = dirname44(root);
|
|
50080
50432
|
const config = readSetupConfig(projectRoot);
|
|
50081
50433
|
const mode = resolveMode2(config);
|
|
@@ -50111,7 +50463,7 @@ function checkLab(root) {
|
|
|
50111
50463
|
}
|
|
50112
50464
|
}
|
|
50113
50465
|
if (m.credentials_used.length > 0) {
|
|
50114
|
-
const creds =
|
|
50466
|
+
const creds = existsSync79(credentialsPath2) ? (() => {
|
|
50115
50467
|
try {
|
|
50116
50468
|
return JSON.parse(readFileSync55(credentialsPath2, "utf-8"));
|
|
50117
50469
|
} catch {
|
|
@@ -50161,7 +50513,7 @@ function checkBrainRepo(root) {
|
|
|
50161
50513
|
if (config?.taskBackend !== "github") return results;
|
|
50162
50514
|
if (resolveMode2(config) !== "separate") return results;
|
|
50163
50515
|
const gitignorePath = join77(root, ".gitignore");
|
|
50164
|
-
if (!
|
|
50516
|
+
if (!existsSync79(gitignorePath)) return results;
|
|
50165
50517
|
if (!gitignoreCovers(root, ["state/*.md"])) {
|
|
50166
50518
|
results.push({
|
|
50167
50519
|
name: "Brain repo",
|
|
@@ -50204,17 +50556,17 @@ function registerDoctorCommand(program2) {
|
|
|
50204
50556
|
...checkBrainRepo(root),
|
|
50205
50557
|
...checkPlatformLayer(root),
|
|
50206
50558
|
// Taxonomy vocabulary (non-fatal: absent means DEFAULT_VOCABULARY used)
|
|
50207
|
-
...!
|
|
50559
|
+
...!existsSync79(join77(root, "core", "taxonomy.json")) ? [{
|
|
50208
50560
|
name: "Taxonomy vocabulary",
|
|
50209
50561
|
status: "warn",
|
|
50210
50562
|
message: "core/taxonomy.json not found \u2014 run `dreamcontext taxonomy init` to scaffold it"
|
|
50211
50563
|
}] : [checkJson(root, "core/taxonomy.json", "Taxonomy vocabulary")],
|
|
50212
50564
|
// Sleep state (optional — created on first Stop hook)
|
|
50213
|
-
...
|
|
50214
|
-
...
|
|
50565
|
+
...existsSync79(join77(root, "state", ".sleep.json")) ? [checkJson(root, "state/.sleep.json", "Sleep state")] : [],
|
|
50566
|
+
...existsSync79(join77(root, "state", ".platforms.json")) ? [checkJson(root, "state/.platforms.json", "Platform defaults")] : []
|
|
50215
50567
|
];
|
|
50216
50568
|
const sleepPath = join77(root, "state", ".sleep.json");
|
|
50217
|
-
if (
|
|
50569
|
+
if (existsSync79(sleepPath)) {
|
|
50218
50570
|
try {
|
|
50219
50571
|
const parsed = JSON.parse(readFileSync55(sleepPath, "utf-8"));
|
|
50220
50572
|
if (typeof parsed.debt !== "number" || parsed.debt < 0) {
|
|
@@ -50388,7 +50740,7 @@ var init_middleware = __esm({
|
|
|
50388
50740
|
});
|
|
50389
50741
|
|
|
50390
50742
|
// src/server/static.ts
|
|
50391
|
-
import { existsSync as
|
|
50743
|
+
import { existsSync as existsSync80, readFileSync as readFileSync56, statSync as statSync16 } from "fs";
|
|
50392
50744
|
import { join as join78, extname as extname4 } from "path";
|
|
50393
50745
|
function serveStatic(req, res, staticDir) {
|
|
50394
50746
|
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
@@ -50398,10 +50750,10 @@ function serveStatic(req, res, staticDir) {
|
|
|
50398
50750
|
res.end("Forbidden");
|
|
50399
50751
|
return;
|
|
50400
50752
|
}
|
|
50401
|
-
if (
|
|
50753
|
+
if (existsSync80(filePath) && statSync16(filePath).isDirectory()) {
|
|
50402
50754
|
filePath = join78(filePath, "index.html");
|
|
50403
50755
|
}
|
|
50404
|
-
if (
|
|
50756
|
+
if (existsSync80(filePath) && statSync16(filePath).isFile()) {
|
|
50405
50757
|
const ext = extname4(filePath);
|
|
50406
50758
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
50407
50759
|
const content = readFileSync56(filePath);
|
|
@@ -50417,7 +50769,7 @@ function serveStatic(req, res, staticDir) {
|
|
|
50417
50769
|
const looksLikeFile = extname4(url.pathname) !== "";
|
|
50418
50770
|
if (acceptsHtml || !looksLikeFile) {
|
|
50419
50771
|
const indexPath2 = join78(staticDir, "index.html");
|
|
50420
|
-
if (
|
|
50772
|
+
if (existsSync80(indexPath2)) {
|
|
50421
50773
|
const content = readFileSync56(indexPath2);
|
|
50422
50774
|
res.writeHead(200, {
|
|
50423
50775
|
"Content-Type": "text/html; charset=utf-8",
|
|
@@ -51180,8 +51532,8 @@ async function handleSleepUpdate(req, res, _params, contextRoot) {
|
|
|
51180
51532
|
sendError(res, 400, "invalid_body", "Request body must be JSON.");
|
|
51181
51533
|
return;
|
|
51182
51534
|
}
|
|
51183
|
-
if (body.recall_mode !== void 0 && !
|
|
51184
|
-
sendError(res, 400, "invalid_value", `recall_mode must be one of: ${
|
|
51535
|
+
if (body.recall_mode !== void 0 && !RECALL_MODES2.includes(body.recall_mode)) {
|
|
51536
|
+
sendError(res, 400, "invalid_value", `recall_mode must be one of: ${RECALL_MODES2.join(", ")}.`);
|
|
51185
51537
|
return;
|
|
51186
51538
|
}
|
|
51187
51539
|
const state = readSleepState(contextRoot);
|
|
@@ -51212,26 +51564,114 @@ async function handleSleepUpdate(req, res, _params, contextRoot) {
|
|
|
51212
51564
|
const updatedState = readSleepState(contextRoot);
|
|
51213
51565
|
sendJson(res, 200, updatedState);
|
|
51214
51566
|
}
|
|
51215
|
-
var
|
|
51567
|
+
var RECALL_MODES2;
|
|
51216
51568
|
var init_sleep2 = __esm({
|
|
51217
51569
|
"src/server/routes/sleep.ts"() {
|
|
51218
51570
|
"use strict";
|
|
51219
51571
|
init_sleep();
|
|
51220
51572
|
init_middleware();
|
|
51221
51573
|
init_change_tracker2();
|
|
51222
|
-
|
|
51574
|
+
RECALL_MODES2 = ["haiku", "raw", "hybrid", "off"];
|
|
51575
|
+
}
|
|
51576
|
+
});
|
|
51577
|
+
|
|
51578
|
+
// src/server/routes/embeddings.ts
|
|
51579
|
+
async function handleEmbeddingModelStatus(_req, res) {
|
|
51580
|
+
sendJson(res, 200, getEmbedModelStatus());
|
|
51581
|
+
}
|
|
51582
|
+
async function handleEmbeddingModelDownload(_req, res) {
|
|
51583
|
+
const status = startEmbedModelDownload();
|
|
51584
|
+
sendJson(res, 200, { ok: true, ...status });
|
|
51585
|
+
}
|
|
51586
|
+
function indexStatusFor(contextRoot) {
|
|
51587
|
+
const run3 = indexRuns.get(contextRoot);
|
|
51588
|
+
const usable = embeddingCacheUsable(contextRoot);
|
|
51589
|
+
let state;
|
|
51590
|
+
if (run3?.state === "building") state = "building";
|
|
51591
|
+
else if (run3?.state === "error" && !usable) state = "error";
|
|
51592
|
+
else if (usable) state = "ready";
|
|
51593
|
+
else state = "not_built";
|
|
51594
|
+
const progress = state === "ready" ? 100 : state === "building" && run3 && run3.total > 0 ? Math.min(99, Math.round(run3.done / run3.total * 100)) : 0;
|
|
51595
|
+
return {
|
|
51596
|
+
state,
|
|
51597
|
+
progress,
|
|
51598
|
+
done: run3?.done ?? 0,
|
|
51599
|
+
total: run3?.total ?? 0,
|
|
51600
|
+
// Prefer the just-built count; else read the real count off the usable cache
|
|
51601
|
+
// (fixes a "0 sections indexed" display when the index was built earlier).
|
|
51602
|
+
chunks: run3?.chunks || (state === "ready" ? embeddingCacheChunkCount(contextRoot) : 0),
|
|
51603
|
+
error: run3?.error ?? null
|
|
51604
|
+
};
|
|
51605
|
+
}
|
|
51606
|
+
async function handleEmbeddingIndexStatus(_req, res, _params, contextRoot) {
|
|
51607
|
+
if (!contextRoot) {
|
|
51608
|
+
sendError(res, 400, "no_vault", "No vault selected.");
|
|
51609
|
+
return;
|
|
51610
|
+
}
|
|
51611
|
+
sendJson(res, 200, indexStatusFor(contextRoot));
|
|
51612
|
+
}
|
|
51613
|
+
async function handleEmbeddingIndexBuild(_req, res, _params, contextRoot) {
|
|
51614
|
+
if (!contextRoot) {
|
|
51615
|
+
sendError(res, 400, "no_vault", "No vault selected.");
|
|
51616
|
+
return;
|
|
51617
|
+
}
|
|
51618
|
+
if (!isEmbedModelDownloaded()) {
|
|
51619
|
+
sendError(res, 409, "model_missing", "Download the embedding model first.");
|
|
51620
|
+
return;
|
|
51621
|
+
}
|
|
51622
|
+
const existing = indexRuns.get(contextRoot);
|
|
51623
|
+
if (existing?.state === "building") {
|
|
51624
|
+
sendJson(res, 200, { ok: true, ...indexStatusFor(contextRoot) });
|
|
51625
|
+
return;
|
|
51626
|
+
}
|
|
51627
|
+
const run3 = { state: "building", done: 0, total: 0, chunks: 0, error: null, startedAt: Date.now() };
|
|
51628
|
+
indexRuns.set(contextRoot, run3);
|
|
51629
|
+
void (async () => {
|
|
51630
|
+
try {
|
|
51631
|
+
const corpus = buildCorpus(contextRoot);
|
|
51632
|
+
const result = await refreshEmbeddings(contextRoot, corpus, void 0, {
|
|
51633
|
+
onProgress: (done, total) => {
|
|
51634
|
+
run3.done = done;
|
|
51635
|
+
run3.total = total;
|
|
51636
|
+
}
|
|
51637
|
+
});
|
|
51638
|
+
if (result === null) {
|
|
51639
|
+
run3.state = "error";
|
|
51640
|
+
run3.error = "Embedding model unavailable \u2014 could not build the index.";
|
|
51641
|
+
} else {
|
|
51642
|
+
run3.state = "ready";
|
|
51643
|
+
run3.chunks = result.index.chunks.length;
|
|
51644
|
+
}
|
|
51645
|
+
} catch (err) {
|
|
51646
|
+
run3.state = "error";
|
|
51647
|
+
run3.error = err instanceof Error ? err.message : "Index build failed.";
|
|
51648
|
+
} finally {
|
|
51649
|
+
run3.endedAt = Date.now();
|
|
51650
|
+
}
|
|
51651
|
+
})();
|
|
51652
|
+
sendJson(res, 200, { ok: true, ...indexStatusFor(contextRoot) });
|
|
51653
|
+
}
|
|
51654
|
+
var indexRuns;
|
|
51655
|
+
var init_embeddings = __esm({
|
|
51656
|
+
"src/server/routes/embeddings.ts"() {
|
|
51657
|
+
"use strict";
|
|
51658
|
+
init_middleware();
|
|
51659
|
+
init_embedder();
|
|
51660
|
+
init_recall();
|
|
51661
|
+
init_store();
|
|
51662
|
+
indexRuns = /* @__PURE__ */ new Map();
|
|
51223
51663
|
}
|
|
51224
51664
|
});
|
|
51225
51665
|
|
|
51226
51666
|
// src/server/routes/core.ts
|
|
51227
|
-
import { existsSync as
|
|
51667
|
+
import { existsSync as existsSync81, readdirSync as readdirSync19 } from "fs";
|
|
51228
51668
|
import { join as join79 } from "path";
|
|
51229
51669
|
function getCoreDir(contextRoot) {
|
|
51230
51670
|
return join79(contextRoot, "core");
|
|
51231
51671
|
}
|
|
51232
51672
|
async function handleCoreList(_req, res, _params, contextRoot) {
|
|
51233
51673
|
const coreDir = getCoreDir(contextRoot);
|
|
51234
|
-
if (!
|
|
51674
|
+
if (!existsSync81(coreDir)) {
|
|
51235
51675
|
sendJson(res, 200, { files: [] });
|
|
51236
51676
|
return;
|
|
51237
51677
|
}
|
|
@@ -51261,7 +51701,7 @@ async function handleCoreGet(_req, res, params, contextRoot) {
|
|
|
51261
51701
|
sendError(res, 400, "invalid_path", "Invalid filename.");
|
|
51262
51702
|
return;
|
|
51263
51703
|
}
|
|
51264
|
-
if (!
|
|
51704
|
+
if (!existsSync81(filePath)) {
|
|
51265
51705
|
sendError(res, 404, "not_found", `Core file not found: ${filename}`);
|
|
51266
51706
|
return;
|
|
51267
51707
|
}
|
|
@@ -51312,7 +51752,7 @@ async function handleCoreUpdate(req, res, params, contextRoot) {
|
|
|
51312
51752
|
sendError(res, 400, "invalid_path", "Invalid filename.");
|
|
51313
51753
|
return;
|
|
51314
51754
|
}
|
|
51315
|
-
if (!
|
|
51755
|
+
if (!existsSync81(filePath)) {
|
|
51316
51756
|
sendError(res, 404, "not_found", `Core file not found: ${filename}`);
|
|
51317
51757
|
return;
|
|
51318
51758
|
}
|
|
@@ -57937,7 +58377,7 @@ var require_lib4 = __commonJS({
|
|
|
57937
58377
|
});
|
|
57938
58378
|
|
|
57939
58379
|
// src/server/routes/knowledge.ts
|
|
57940
|
-
import { existsSync as
|
|
58380
|
+
import { existsSync as existsSync82, readFileSync as readFileSync57, statSync as statSync17 } from "fs";
|
|
57941
58381
|
import { join as join80, dirname as dirname46, basename as basename25, extname as extname5 } from "path";
|
|
57942
58382
|
function getKnowledgeDir2(contextRoot) {
|
|
57943
58383
|
return join80(contextRoot, "knowledge");
|
|
@@ -58021,7 +58461,7 @@ async function handleKnowledgeGet(_req, res, params, contextRoot) {
|
|
|
58021
58461
|
sendError(res, 400, "invalid_path", `Invalid knowledge slug: ${slug}`);
|
|
58022
58462
|
return;
|
|
58023
58463
|
}
|
|
58024
|
-
if (!
|
|
58464
|
+
if (!existsSync82(filePath)) {
|
|
58025
58465
|
sendError(res, 404, "not_found", `Knowledge file not found: ${slug}`);
|
|
58026
58466
|
return;
|
|
58027
58467
|
}
|
|
@@ -58048,7 +58488,7 @@ async function handleKnowledgeAssets(_req, res, params, contextRoot) {
|
|
|
58048
58488
|
sendError(res, 400, "invalid_path", `Invalid knowledge slug: ${slug}`);
|
|
58049
58489
|
return;
|
|
58050
58490
|
}
|
|
58051
|
-
if (!
|
|
58491
|
+
if (!existsSync82(filePath)) {
|
|
58052
58492
|
sendError(res, 404, "not_found", `Knowledge file not found: ${slug}`);
|
|
58053
58493
|
return;
|
|
58054
58494
|
}
|
|
@@ -58073,7 +58513,7 @@ async function handleKnowledgeAssets(_req, res, params, contextRoot) {
|
|
|
58073
58513
|
// co-located self-contained board folder
|
|
58074
58514
|
safeChildPath2(boardDir, join80("Attachments", basename25(path2)))
|
|
58075
58515
|
];
|
|
58076
|
-
const abs = candidates.find((c) => c !== null &&
|
|
58516
|
+
const abs = candidates.find((c) => c !== null && existsSync82(c));
|
|
58077
58517
|
if (!abs) continue;
|
|
58078
58518
|
const loaded = await loadAssetDataURL(abs, maxDim, quality);
|
|
58079
58519
|
if (!loaded) continue;
|
|
@@ -58098,7 +58538,7 @@ async function handleKnowledgeUpdate(req, res, params, contextRoot) {
|
|
|
58098
58538
|
sendError(res, 400, "invalid_path", `Invalid knowledge slug: ${slug}`);
|
|
58099
58539
|
return;
|
|
58100
58540
|
}
|
|
58101
|
-
if (!
|
|
58541
|
+
if (!existsSync82(filePath)) {
|
|
58102
58542
|
sendError(res, 404, "not_found", `Knowledge file not found: ${slug}`);
|
|
58103
58543
|
return;
|
|
58104
58544
|
}
|
|
@@ -58169,11 +58609,11 @@ var init_knowledge2 = __esm({
|
|
|
58169
58609
|
});
|
|
58170
58610
|
|
|
58171
58611
|
// src/server/routes/changelog.ts
|
|
58172
|
-
import { existsSync as
|
|
58612
|
+
import { existsSync as existsSync83 } from "fs";
|
|
58173
58613
|
import { join as join81 } from "path";
|
|
58174
58614
|
async function handleChangelogGet(_req, res, _params, contextRoot) {
|
|
58175
58615
|
const filePath = join81(contextRoot, "core", "CHANGELOG.json");
|
|
58176
|
-
if (!
|
|
58616
|
+
if (!existsSync83(filePath)) {
|
|
58177
58617
|
sendJson(res, 200, { entries: [] });
|
|
58178
58618
|
return;
|
|
58179
58619
|
}
|
|
@@ -58186,7 +58626,7 @@ async function handleChangelogGet(_req, res, _params, contextRoot) {
|
|
|
58186
58626
|
}
|
|
58187
58627
|
async function handleReleasesGet(_req, res, _params, contextRoot) {
|
|
58188
58628
|
const filePath = join81(contextRoot, "core", "RELEASES.json");
|
|
58189
|
-
if (!
|
|
58629
|
+
if (!existsSync83(filePath)) {
|
|
58190
58630
|
sendJson(res, 200, { entries: [] });
|
|
58191
58631
|
return;
|
|
58192
58632
|
}
|
|
@@ -58324,7 +58764,7 @@ async function handleReleasesUpdate(req, res, params, contextRoot) {
|
|
|
58324
58764
|
return;
|
|
58325
58765
|
}
|
|
58326
58766
|
const filePath = join81(contextRoot, "core", "RELEASES.json");
|
|
58327
|
-
if (!
|
|
58767
|
+
if (!existsSync83(filePath)) {
|
|
58328
58768
|
sendError(res, 404, "not_found", `Release not found: ${params.version}`);
|
|
58329
58769
|
return;
|
|
58330
58770
|
}
|
|
@@ -58406,7 +58846,7 @@ async function handleReleasesDelete(_req, res, params, contextRoot) {
|
|
|
58406
58846
|
const filePath = join81(contextRoot, "core", "RELEASES.json");
|
|
58407
58847
|
const wasActive = getActivePlanningVersion(contextRoot) === params.version;
|
|
58408
58848
|
let wasRegistered = false;
|
|
58409
|
-
if (
|
|
58849
|
+
if (existsSync83(filePath)) {
|
|
58410
58850
|
const entries = readJsonArray(filePath);
|
|
58411
58851
|
for (const entry of entries) {
|
|
58412
58852
|
if (!entry.status) entry.status = "released";
|
|
@@ -58447,7 +58887,7 @@ var init_changelog = __esm({
|
|
|
58447
58887
|
});
|
|
58448
58888
|
|
|
58449
58889
|
// src/lib/graph.ts
|
|
58450
|
-
import { existsSync as
|
|
58890
|
+
import { existsSync as existsSync84, readFileSync as readFileSync58 } from "fs";
|
|
58451
58891
|
import { join as join82, basename as basename26 } from "path";
|
|
58452
58892
|
function buildGraph(contextRoot) {
|
|
58453
58893
|
const nodes = [];
|
|
@@ -58469,7 +58909,7 @@ function buildGraph(contextRoot) {
|
|
|
58469
58909
|
{ prefix: "2", group: "memory" }
|
|
58470
58910
|
];
|
|
58471
58911
|
for (const { prefix, group } of foundational) {
|
|
58472
|
-
if (!
|
|
58912
|
+
if (!existsSync84(coreDir)) continue;
|
|
58473
58913
|
const matches = import_fast_glob19.default.sync(`${prefix}.*.md`, { cwd: coreDir, absolute: true });
|
|
58474
58914
|
for (const file of matches) {
|
|
58475
58915
|
try {
|
|
@@ -58489,7 +58929,7 @@ function buildGraph(contextRoot) {
|
|
|
58489
58929
|
}
|
|
58490
58930
|
}
|
|
58491
58931
|
}
|
|
58492
|
-
if (
|
|
58932
|
+
if (existsSync84(coreDir)) {
|
|
58493
58933
|
const others = import_fast_glob19.default.sync("[3-9]*.md", { cwd: coreDir, absolute: true });
|
|
58494
58934
|
for (const file of others) {
|
|
58495
58935
|
const filename = basename26(file);
|
|
@@ -58510,7 +58950,7 @@ function buildGraph(contextRoot) {
|
|
|
58510
58950
|
}
|
|
58511
58951
|
}
|
|
58512
58952
|
const featuresPath = featuresDir(contextRoot);
|
|
58513
|
-
if (
|
|
58953
|
+
if (existsSync84(featuresPath)) {
|
|
58514
58954
|
const files = import_fast_glob19.default.sync("*.md", { cwd: featuresPath, absolute: true });
|
|
58515
58955
|
for (const file of files) {
|
|
58516
58956
|
const fileSlug = basename26(file, ".md");
|
|
@@ -58541,7 +58981,7 @@ function buildGraph(contextRoot) {
|
|
|
58541
58981
|
}
|
|
58542
58982
|
}
|
|
58543
58983
|
const stateDir = join82(contextRoot, "state");
|
|
58544
|
-
if (
|
|
58984
|
+
if (existsSync84(stateDir)) {
|
|
58545
58985
|
const files = import_fast_glob19.default.sync("*.md", { cwd: stateDir, absolute: true });
|
|
58546
58986
|
for (const file of files) {
|
|
58547
58987
|
const fileSlug = basename26(file, ".md");
|
|
@@ -58593,7 +59033,7 @@ function buildGraph(contextRoot) {
|
|
|
58593
59033
|
);
|
|
58594
59034
|
}
|
|
58595
59035
|
const inboxDir2 = join82(contextRoot, "inbox");
|
|
58596
|
-
if (
|
|
59036
|
+
if (existsSync84(inboxDir2)) {
|
|
58597
59037
|
const files = import_fast_glob19.default.sync("*.md", { cwd: inboxDir2, absolute: true });
|
|
58598
59038
|
for (const file of files) {
|
|
58599
59039
|
const slug = basename26(file, ".md");
|
|
@@ -58616,7 +59056,7 @@ function buildGraph(contextRoot) {
|
|
|
58616
59056
|
}
|
|
58617
59057
|
const releasesPath = join82(coreDir, "RELEASES.json");
|
|
58618
59058
|
let releases = [];
|
|
58619
|
-
if (
|
|
59059
|
+
if (existsSync84(releasesPath)) {
|
|
58620
59060
|
try {
|
|
58621
59061
|
const parsed = JSON.parse(readFileSync58(releasesPath, "utf-8"));
|
|
58622
59062
|
if (Array.isArray(parsed)) releases = parsed;
|
|
@@ -58715,7 +59155,7 @@ var init_graph = __esm({
|
|
|
58715
59155
|
});
|
|
58716
59156
|
|
|
58717
59157
|
// src/server/routes/graph.ts
|
|
58718
|
-
import { existsSync as
|
|
59158
|
+
import { existsSync as existsSync85, readFileSync as readFileSync59 } from "fs";
|
|
58719
59159
|
import { normalize, resolve as resolve16, sep as sep11 } from "path";
|
|
58720
59160
|
async function handleGraphGet(_req, res, _params, contextRoot) {
|
|
58721
59161
|
try {
|
|
@@ -58739,7 +59179,7 @@ async function handleGraphContentGet(req, res, _params, contextRoot) {
|
|
|
58739
59179
|
sendError(res, 400, "invalid_path", "Path escapes context root.");
|
|
58740
59180
|
return;
|
|
58741
59181
|
}
|
|
58742
|
-
if (!
|
|
59182
|
+
if (!existsSync85(absTarget)) {
|
|
58743
59183
|
sendError(res, 404, "not_found", `Path not found: ${rawPath}`);
|
|
58744
59184
|
return;
|
|
58745
59185
|
}
|
|
@@ -58790,7 +59230,7 @@ var init_graph2 = __esm({
|
|
|
58790
59230
|
});
|
|
58791
59231
|
|
|
58792
59232
|
// src/lib/council.ts
|
|
58793
|
-
import { existsSync as
|
|
59233
|
+
import { existsSync as existsSync86, mkdirSync as mkdirSync42, readFileSync as readFileSync60 } from "fs";
|
|
58794
59234
|
import { join as join83, resolve as resolve17, sep as sep12 } from "path";
|
|
58795
59235
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
58796
59236
|
function getCouncilDir() {
|
|
@@ -58833,14 +59273,14 @@ function ensureCouncilDir() {
|
|
|
58833
59273
|
const dir = getCouncilDir();
|
|
58834
59274
|
mkdirSync42(dir, { recursive: true });
|
|
58835
59275
|
const indexPath2 = getCouncilIndexPath();
|
|
58836
|
-
if (!
|
|
59276
|
+
if (!existsSync86(indexPath2)) {
|
|
58837
59277
|
writeJsonArray(indexPath2, []);
|
|
58838
59278
|
}
|
|
58839
59279
|
return dir;
|
|
58840
59280
|
}
|
|
58841
59281
|
function ensureDebateExists(debateId) {
|
|
58842
59282
|
const dir = getDebateDir(debateId);
|
|
58843
|
-
if (!
|
|
59283
|
+
if (!existsSync86(dir)) {
|
|
58844
59284
|
throw new Error(`Debate not found: ${debateId}`);
|
|
58845
59285
|
}
|
|
58846
59286
|
return dir;
|
|
@@ -58848,7 +59288,7 @@ function ensureDebateExists(debateId) {
|
|
|
58848
59288
|
function ensurePersonaExists(debateId, personaSlug) {
|
|
58849
59289
|
ensureDebateExists(debateId);
|
|
58850
59290
|
const dir = getPersonaDir(debateId, personaSlug);
|
|
58851
|
-
if (!
|
|
59291
|
+
if (!existsSync86(dir)) {
|
|
58852
59292
|
throw new Error(`Persona not found in ${debateId}: ${personaSlug}`);
|
|
58853
59293
|
}
|
|
58854
59294
|
return dir;
|
|
@@ -58860,7 +59300,7 @@ function readDebateFrontmatter(debateId) {
|
|
|
58860
59300
|
}
|
|
58861
59301
|
function loadCouncilIndex() {
|
|
58862
59302
|
const indexPath2 = getCouncilIndexPath();
|
|
58863
|
-
if (!
|
|
59303
|
+
if (!existsSync86(indexPath2)) return [];
|
|
58864
59304
|
return readJsonArray(indexPath2);
|
|
58865
59305
|
}
|
|
58866
59306
|
function saveCouncilIndex(entries) {
|
|
@@ -58887,7 +59327,7 @@ function loadTemplate(filename) {
|
|
|
58887
59327
|
join83(__dirname6, "..", "..", "src", "templates", filename)
|
|
58888
59328
|
];
|
|
58889
59329
|
for (const path2 of candidates) {
|
|
58890
|
-
if (
|
|
59330
|
+
if (existsSync86(path2)) {
|
|
58891
59331
|
return readFileSync60(path2, "utf-8");
|
|
58892
59332
|
}
|
|
58893
59333
|
}
|
|
@@ -58963,7 +59403,7 @@ function parseReportRounds(reportContent) {
|
|
|
58963
59403
|
}
|
|
58964
59404
|
function getPersonaRoundSummary(debateId, personaSlug, round) {
|
|
58965
59405
|
const reportPath2 = join83(getPersonaDir(debateId, personaSlug), "report.md");
|
|
58966
|
-
if (!
|
|
59406
|
+
if (!existsSync86(reportPath2)) return null;
|
|
58967
59407
|
const { content } = readFrontmatter(reportPath2);
|
|
58968
59408
|
const entries = parseReportRounds(content);
|
|
58969
59409
|
const entry = entries.find((e) => e.round === round);
|
|
@@ -58997,7 +59437,7 @@ var init_council = __esm({
|
|
|
58997
59437
|
});
|
|
58998
59438
|
|
|
58999
59439
|
// src/server/routes/council.ts
|
|
59000
|
-
import { existsSync as
|
|
59440
|
+
import { existsSync as existsSync87 } from "fs";
|
|
59001
59441
|
import { join as join84, resolve as resolve18, sep as sep13 } from "path";
|
|
59002
59442
|
function getCouncilDir2(contextRoot) {
|
|
59003
59443
|
return join84(contextRoot, "council");
|
|
@@ -59054,13 +59494,13 @@ function toParsedRound(entry) {
|
|
|
59054
59494
|
}
|
|
59055
59495
|
function loadPersonaDetail(debateDir, slug) {
|
|
59056
59496
|
const personaDir = join84(debateDir, slug);
|
|
59057
|
-
if (!
|
|
59497
|
+
if (!existsSync87(personaDir)) return null;
|
|
59058
59498
|
const personaFile = join84(personaDir, "context-and-persona.md");
|
|
59059
59499
|
const reportFile = join84(personaDir, "report.md");
|
|
59060
59500
|
let fm = { name: slug, model: "unknown", aspects: [], round_entries: 0 };
|
|
59061
59501
|
let persona = "";
|
|
59062
59502
|
let crossContext = {};
|
|
59063
|
-
if (
|
|
59503
|
+
if (existsSync87(personaFile)) {
|
|
59064
59504
|
const parsed = readFrontmatter(personaFile);
|
|
59065
59505
|
fm = {
|
|
59066
59506
|
name: parsed.data.name ?? slug,
|
|
@@ -59073,13 +59513,13 @@ function loadPersonaDetail(debateDir, slug) {
|
|
|
59073
59513
|
crossContext = split.crossContext;
|
|
59074
59514
|
}
|
|
59075
59515
|
let rounds = [];
|
|
59076
|
-
if (
|
|
59516
|
+
if (existsSync87(reportFile)) {
|
|
59077
59517
|
const { content } = readFrontmatter(reportFile);
|
|
59078
59518
|
rounds = parseReportRounds(content).map(toParsedRound);
|
|
59079
59519
|
}
|
|
59080
59520
|
const researchIndex = join84(personaDir, "researches", "index.json");
|
|
59081
59521
|
let researches = [];
|
|
59082
|
-
if (
|
|
59522
|
+
if (existsSync87(researchIndex)) {
|
|
59083
59523
|
try {
|
|
59084
59524
|
researches = readJsonArray(researchIndex);
|
|
59085
59525
|
} catch {
|
|
@@ -59090,7 +59530,7 @@ function loadPersonaDetail(debateDir, slug) {
|
|
|
59090
59530
|
}
|
|
59091
59531
|
async function handleCouncilList(_req, res, _params, contextRoot) {
|
|
59092
59532
|
const indexPath2 = join84(getCouncilDir2(contextRoot), "index.json");
|
|
59093
|
-
if (!
|
|
59533
|
+
if (!existsSync87(indexPath2)) {
|
|
59094
59534
|
sendJson(res, 200, { debates: [] });
|
|
59095
59535
|
return;
|
|
59096
59536
|
}
|
|
@@ -59099,7 +59539,7 @@ async function handleCouncilList(_req, res, _params, contextRoot) {
|
|
|
59099
59539
|
const enriched = debates.map((d) => {
|
|
59100
59540
|
const debateFile = join84(getCouncilDir2(contextRoot), d.id, "debate.md");
|
|
59101
59541
|
let personaSlugs = [];
|
|
59102
|
-
if (
|
|
59542
|
+
if (existsSync87(debateFile)) {
|
|
59103
59543
|
try {
|
|
59104
59544
|
const fm = readFrontmatter(debateFile).data;
|
|
59105
59545
|
if (Array.isArray(fm.personas)) personaSlugs = fm.personas;
|
|
@@ -59124,12 +59564,12 @@ async function handleCouncilGet(_req, res, params, contextRoot) {
|
|
|
59124
59564
|
const councilDir = getCouncilDir2(contextRoot);
|
|
59125
59565
|
const debateDirUnchecked = join84(councilDir, debateId);
|
|
59126
59566
|
const debateDir = assertWithin(councilDir, debateDirUnchecked);
|
|
59127
|
-
if (!debateDir || !
|
|
59567
|
+
if (!debateDir || !existsSync87(debateDir)) {
|
|
59128
59568
|
sendError(res, 404, "not_found", `Debate not found: ${debateId}`);
|
|
59129
59569
|
return;
|
|
59130
59570
|
}
|
|
59131
59571
|
const debateFile = join84(debateDir, "debate.md");
|
|
59132
|
-
if (!
|
|
59572
|
+
if (!existsSync87(debateFile)) {
|
|
59133
59573
|
sendError(res, 404, "not_found", `Debate metadata missing: ${debateId}`);
|
|
59134
59574
|
return;
|
|
59135
59575
|
}
|
|
@@ -59147,10 +59587,10 @@ async function handleCouncilGet(_req, res, params, contextRoot) {
|
|
|
59147
59587
|
updated_at: String(fmRaw.updated_at ?? "")
|
|
59148
59588
|
};
|
|
59149
59589
|
const roundLogFile = join84(debateDir, "round-log.md");
|
|
59150
|
-
const roundLog =
|
|
59590
|
+
const roundLog = existsSync87(roundLogFile) ? readFrontmatter(roundLogFile).content : null;
|
|
59151
59591
|
const finalReportFile = join84(debateDir, "final-report.md");
|
|
59152
59592
|
let finalReport = null;
|
|
59153
|
-
if (
|
|
59593
|
+
if (existsSync87(finalReportFile)) {
|
|
59154
59594
|
const parsed = readFrontmatter(finalReportFile);
|
|
59155
59595
|
finalReport = { frontmatter: parsed.data, content: parsed.content };
|
|
59156
59596
|
}
|
|
@@ -59180,7 +59620,7 @@ async function handleCouncilResearchGet(_req, res, params, contextRoot) {
|
|
|
59180
59620
|
councilDir,
|
|
59181
59621
|
join84(councilDir, debateId, personaSlug, "researches", `${researchSlug}.md`)
|
|
59182
59622
|
);
|
|
59183
|
-
if (!researchFile || !
|
|
59623
|
+
if (!researchFile || !existsSync87(researchFile)) {
|
|
59184
59624
|
sendError(res, 404, "not_found", `Research not found: ${researchSlug}`);
|
|
59185
59625
|
return;
|
|
59186
59626
|
}
|
|
@@ -59345,9 +59785,9 @@ var init_config = __esm({
|
|
|
59345
59785
|
|
|
59346
59786
|
// src/server/routes/vaults.ts
|
|
59347
59787
|
import { dirname as dirname48, resolve as resolve19 } from "path";
|
|
59348
|
-
import { existsSync as
|
|
59788
|
+
import { existsSync as existsSync88 } from "fs";
|
|
59349
59789
|
async function handleVaultsGet(_req, res, _params, contextRoot) {
|
|
59350
|
-
const vaults = listVaults().map((v) => ({ ...v, exists:
|
|
59790
|
+
const vaults = listVaults().map((v) => ({ ...v, exists: existsSync88(resolve19(v.path)) }));
|
|
59351
59791
|
const current = contextRoot ? vaults.find((v) => resolve19(v.path) === resolve19(dirname48(contextRoot)))?.name ?? null : null;
|
|
59352
59792
|
sendJson(res, 200, { vaults, current });
|
|
59353
59793
|
}
|
|
@@ -59443,7 +59883,7 @@ var init_ensure_cli = __esm({
|
|
|
59443
59883
|
|
|
59444
59884
|
// src/server/routes/launcher.ts
|
|
59445
59885
|
import { basename as basename27, isAbsolute as isAbsolute3, join as join85, resolve as resolve20, sep as sep14 } from "path";
|
|
59446
|
-
import { existsSync as
|
|
59886
|
+
import { existsSync as existsSync89, mkdirSync as mkdirSync43, readdirSync as readdirSync20, statSync as statSync18, createReadStream, readFileSync as readFileSync61, writeFileSync as writeFileSync50 } from "fs";
|
|
59447
59887
|
import { homedir as homedir6 } from "os";
|
|
59448
59888
|
import { execFile as execFile2, spawn as spawn4 } from "child_process";
|
|
59449
59889
|
import { promisify as promisify2 } from "util";
|
|
@@ -59467,7 +59907,7 @@ async function handleLauncherDiscover(req, res, _params, _contextRoot) {
|
|
|
59467
59907
|
return;
|
|
59468
59908
|
}
|
|
59469
59909
|
const resolvedRoot = resolve20(root);
|
|
59470
|
-
if (!
|
|
59910
|
+
if (!existsSync89(resolvedRoot)) {
|
|
59471
59911
|
sendError(res, 400, "invalid_root", `Path does not exist: ${resolvedRoot}`);
|
|
59472
59912
|
return;
|
|
59473
59913
|
}
|
|
@@ -59535,14 +59975,14 @@ async function scaffoldProject(a, runner = defaultCliRunner, home) {
|
|
|
59535
59975
|
throw new ScaffoldError("parentDir must be an absolute path.");
|
|
59536
59976
|
}
|
|
59537
59977
|
const resolvedParent = resolve20(parentDir);
|
|
59538
|
-
if (!
|
|
59978
|
+
if (!existsSync89(resolvedParent) || !statSync18(resolvedParent).isDirectory()) {
|
|
59539
59979
|
throw new ScaffoldError(`Parent directory does not exist: ${resolvedParent}`);
|
|
59540
59980
|
}
|
|
59541
59981
|
target = resolve20(resolvedParent, name);
|
|
59542
59982
|
if (target !== join85(resolvedParent, name) || !target.startsWith(resolvedParent + sep14)) {
|
|
59543
59983
|
throw new ScaffoldError("Resolved project path escapes the parent directory.");
|
|
59544
59984
|
}
|
|
59545
|
-
if (isNonEmptyDir(target) && !
|
|
59985
|
+
if (isNonEmptyDir(target) && !existsSync89(join85(target, "_dream_context"))) {
|
|
59546
59986
|
throw new ScaffoldError(`A non-empty folder already exists at ${target}.`);
|
|
59547
59987
|
}
|
|
59548
59988
|
mkdirSync43(target, { recursive: true });
|
|
@@ -59552,13 +59992,13 @@ async function scaffoldProject(a, runner = defaultCliRunner, home) {
|
|
|
59552
59992
|
throw new ScaffoldError("projectPath must be an absolute path.");
|
|
59553
59993
|
}
|
|
59554
59994
|
target = resolve20(projectPath);
|
|
59555
|
-
if (!
|
|
59995
|
+
if (!existsSync89(target) || !statSync18(target).isDirectory()) {
|
|
59556
59996
|
throw new ScaffoldError(`Folder does not exist: ${target}`);
|
|
59557
59997
|
}
|
|
59558
59998
|
} else {
|
|
59559
59999
|
throw new ScaffoldError("mode must be 'new' or 'existing'.");
|
|
59560
60000
|
}
|
|
59561
|
-
const alreadyProject =
|
|
60001
|
+
const alreadyProject = existsSync89(join85(target, "_dream_context"));
|
|
59562
60002
|
if (!alreadyProject) {
|
|
59563
60003
|
const initArgs = ["init", "--yes", "--platforms", platformArg, "--name", name];
|
|
59564
60004
|
if (a.description?.trim()) initArgs.push("--description", a.description.trim());
|
|
@@ -59613,13 +60053,13 @@ async function handleLauncherDetect(req, res, _params, _contextRoot) {
|
|
|
59613
60053
|
return;
|
|
59614
60054
|
}
|
|
59615
60055
|
const resolved = resolve20(path2);
|
|
59616
|
-
if (!
|
|
60056
|
+
if (!existsSync89(resolved)) {
|
|
59617
60057
|
sendError(res, 400, "invalid_path", `Path does not exist: ${resolved}`);
|
|
59618
60058
|
return;
|
|
59619
60059
|
}
|
|
59620
60060
|
sendJson(res, 200, {
|
|
59621
60061
|
stack: detectTechStack(resolved) ?? "",
|
|
59622
|
-
hasContext:
|
|
60062
|
+
hasContext: existsSync89(join85(resolved, "_dream_context")),
|
|
59623
60063
|
name: basename27(resolved)
|
|
59624
60064
|
});
|
|
59625
60065
|
}
|
|
@@ -59646,7 +60086,7 @@ async function handleSleepyConfigGet(_req, res, _params, _contextRoot) {
|
|
|
59646
60086
|
let hotkey = "Alt+Cmd+S";
|
|
59647
60087
|
try {
|
|
59648
60088
|
const p = sleepyConfigPath();
|
|
59649
|
-
if (
|
|
60089
|
+
if (existsSync89(p)) {
|
|
59650
60090
|
const raw = JSON.parse(readFileSync61(p, "utf-8"));
|
|
59651
60091
|
enabled = raw.enabled === true;
|
|
59652
60092
|
if (typeof raw.hotkey === "string" && raw.hotkey.trim()) hotkey = raw.hotkey;
|
|
@@ -59692,7 +60132,7 @@ async function handleAgentSettingsGet(_req, res, _params, _contextRoot) {
|
|
|
59692
60132
|
let settings = { ...AGENT_UI_DEFAULTS };
|
|
59693
60133
|
try {
|
|
59694
60134
|
const p = agentSettingsPath();
|
|
59695
|
-
if (
|
|
60135
|
+
if (existsSync89(p)) {
|
|
59696
60136
|
settings = coerceAgentSettings(JSON.parse(readFileSync61(p, "utf-8")));
|
|
59697
60137
|
}
|
|
59698
60138
|
} catch {
|
|
@@ -59729,7 +60169,7 @@ async function handleSleepyVideo(req, res, _params, _contextRoot) {
|
|
|
59729
60169
|
return;
|
|
59730
60170
|
}
|
|
59731
60171
|
const file = join85(dir, `${mode}.mp4`);
|
|
59732
|
-
if (!
|
|
60172
|
+
if (!existsSync89(file)) {
|
|
59733
60173
|
res.writeHead(404);
|
|
59734
60174
|
res.end();
|
|
59735
60175
|
return;
|
|
@@ -59761,7 +60201,7 @@ async function handleSleepyAnim(req, res, _params, _contextRoot) {
|
|
|
59761
60201
|
}
|
|
59762
60202
|
const dir = process.env.DREAMCONTEXT_SLEEPY_DIR;
|
|
59763
60203
|
const file = dir ? join85(dir, `${mode}.webp`) : "";
|
|
59764
|
-
if (!file || !
|
|
60204
|
+
if (!file || !existsSync89(file)) {
|
|
59765
60205
|
res.writeHead(404);
|
|
59766
60206
|
res.end();
|
|
59767
60207
|
return;
|
|
@@ -59813,14 +60253,14 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
|
|
|
59813
60253
|
return;
|
|
59814
60254
|
}
|
|
59815
60255
|
const cwd = resolve20(vault.path);
|
|
59816
|
-
if (!
|
|
60256
|
+
if (!existsSync89(cwd)) {
|
|
59817
60257
|
sendError(res, 400, "missing_vault", `Vault path no longer exists: ${cwd}`);
|
|
59818
60258
|
return;
|
|
59819
60259
|
}
|
|
59820
60260
|
if (mode === "learn") {
|
|
59821
60261
|
try {
|
|
59822
60262
|
const changelogPath = join85(cwd, "_dream_context", "core", "CHANGELOG.json");
|
|
59823
|
-
if (!
|
|
60263
|
+
if (!existsSync89(changelogPath)) {
|
|
59824
60264
|
sendError(res, 400, "not_initialized", `"${vaultName}" has no _dream_context \u2014 run init first.`);
|
|
59825
60265
|
return;
|
|
59826
60266
|
}
|
|
@@ -59940,7 +60380,7 @@ async function handleLauncherDefaults(_req, res, _params, _contextRoot) {
|
|
|
59940
60380
|
sendJson(res, 200, { home, defaultParent: join85(home, "projects") });
|
|
59941
60381
|
}
|
|
59942
60382
|
function computeVaultStatus(v, latest) {
|
|
59943
|
-
const exists =
|
|
60383
|
+
const exists = existsSync89(resolve20(v.path));
|
|
59944
60384
|
let setupVersion = "0.0.0";
|
|
59945
60385
|
let shareable = false;
|
|
59946
60386
|
if (exists) {
|
|
@@ -59992,7 +60432,7 @@ async function handleLauncherUpdate(req, res, _params, _contextRoot) {
|
|
|
59992
60432
|
return;
|
|
59993
60433
|
}
|
|
59994
60434
|
const target = resolve20(vault.path);
|
|
59995
|
-
if (!
|
|
60435
|
+
if (!existsSync89(target)) {
|
|
59996
60436
|
sendError(res, 400, "missing_vault", `Vault path no longer exists: ${target}`);
|
|
59997
60437
|
return;
|
|
59998
60438
|
}
|
|
@@ -60071,7 +60511,7 @@ async function handleLauncherUpgradeStatus(_req, res, _params, _contextRoot) {
|
|
|
60071
60511
|
async function handleLauncherRelaunch(_req, res, _params, _contextRoot) {
|
|
60072
60512
|
const manifest = readAppManifest();
|
|
60073
60513
|
const appPath = manifest?.path;
|
|
60074
|
-
if (!appPath || !
|
|
60514
|
+
if (!appPath || !existsSync89(appPath)) {
|
|
60075
60515
|
sendJson(res, 200, { ok: false, reason: "app_not_installed" });
|
|
60076
60516
|
return;
|
|
60077
60517
|
}
|
|
@@ -60098,7 +60538,7 @@ async function handleLauncherFederationGraph(_req, res, _params, _contextRoot) {
|
|
|
60098
60538
|
const connections = [];
|
|
60099
60539
|
const seen = /* @__PURE__ */ new Set();
|
|
60100
60540
|
for (const v of vaults) {
|
|
60101
|
-
if (!
|
|
60541
|
+
if (!existsSync89(resolve20(v.path))) continue;
|
|
60102
60542
|
const conns = listConnections(join85(resolve20(v.path), "_dream_context"));
|
|
60103
60543
|
for (const c of conns) {
|
|
60104
60544
|
if (!known.has(c.vault)) continue;
|
|
@@ -60257,7 +60697,7 @@ async function handleLauncherShareable(req, res, _params, _contextRoot) {
|
|
|
60257
60697
|
return;
|
|
60258
60698
|
}
|
|
60259
60699
|
const root = resolve20(vault.path);
|
|
60260
|
-
if (!
|
|
60700
|
+
if (!existsSync89(root)) {
|
|
60261
60701
|
sendError(res, 400, "missing_vault", `Vault path no longer exists: ${root}`);
|
|
60262
60702
|
return;
|
|
60263
60703
|
}
|
|
@@ -60333,13 +60773,13 @@ var init_launcher = __esm({
|
|
|
60333
60773
|
|
|
60334
60774
|
// src/server/routes/ui-settings.ts
|
|
60335
60775
|
import { dirname as dirname50, join as join86 } from "path";
|
|
60336
|
-
import { existsSync as
|
|
60776
|
+
import { existsSync as existsSync90, mkdirSync as mkdirSync44, readFileSync as readFileSync62, writeFileSync as writeFileSync51 } from "fs";
|
|
60337
60777
|
function settingsPath(contextRoot) {
|
|
60338
60778
|
return join86(contextRoot, BRAIN_SETTINGS_REL_PATH);
|
|
60339
60779
|
}
|
|
60340
60780
|
async function handleBrainSettingsGet(_req, res, _params, contextRoot) {
|
|
60341
60781
|
const path2 = settingsPath(contextRoot);
|
|
60342
|
-
if (!
|
|
60782
|
+
if (!existsSync90(path2)) {
|
|
60343
60783
|
sendJson(res, 200, { settings: {} });
|
|
60344
60784
|
return;
|
|
60345
60785
|
}
|
|
@@ -60381,7 +60821,7 @@ function makeSettingsHandlers(relPath, logTag) {
|
|
|
60381
60821
|
const pathFor = (contextRoot) => join86(contextRoot, relPath);
|
|
60382
60822
|
const get = async (_req, res, _params, contextRoot) => {
|
|
60383
60823
|
const path2 = pathFor(contextRoot);
|
|
60384
|
-
if (!
|
|
60824
|
+
if (!existsSync90(path2)) {
|
|
60385
60825
|
sendJson(res, 200, { settings: {} });
|
|
60386
60826
|
return;
|
|
60387
60827
|
}
|
|
@@ -60870,7 +61310,7 @@ var init_lab2 = __esm({
|
|
|
60870
61310
|
|
|
60871
61311
|
// src/server/routes/board.ts
|
|
60872
61312
|
import { dirname as dirname52, join as join87 } from "path";
|
|
60873
|
-
import { existsSync as
|
|
61313
|
+
import { existsSync as existsSync91, mkdirSync as mkdirSync45, readFileSync as readFileSync63, writeFileSync as writeFileSync52 } from "fs";
|
|
60874
61314
|
function sharedPath(contextRoot) {
|
|
60875
61315
|
return join87(contextRoot, SHARED_REL_PATH);
|
|
60876
61316
|
}
|
|
@@ -60878,7 +61318,7 @@ function localPath(contextRoot) {
|
|
|
60878
61318
|
return join87(contextRoot, LOCAL_REL_PATH);
|
|
60879
61319
|
}
|
|
60880
61320
|
function readBlob(path2) {
|
|
60881
|
-
if (!
|
|
61321
|
+
if (!existsSync91(path2)) return {};
|
|
60882
61322
|
try {
|
|
60883
61323
|
const raw = JSON.parse(readFileSync63(path2, "utf-8"));
|
|
60884
61324
|
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
@@ -60959,7 +61399,7 @@ var init_board = __esm({
|
|
|
60959
61399
|
// src/server/routes/sleepy-chat.ts
|
|
60960
61400
|
import { spawn as spawn5 } from "child_process";
|
|
60961
61401
|
import { dirname as dirname53, join as join88 } from "path";
|
|
60962
|
-
import { existsSync as
|
|
61402
|
+
import { existsSync as existsSync92, mkdirSync as mkdirSync46, readFileSync as readFileSync64, writeFileSync as writeFileSync53 } from "fs";
|
|
60963
61403
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
60964
61404
|
function modelFor(tier) {
|
|
60965
61405
|
return tier === "intelligent" ? "opus" : "sonnet";
|
|
@@ -61003,7 +61443,7 @@ function readStore(contextRoot) {
|
|
|
61003
61443
|
function writeStore(contextRoot, store) {
|
|
61004
61444
|
try {
|
|
61005
61445
|
const dir = join88(contextRoot, "state");
|
|
61006
|
-
if (!
|
|
61446
|
+
if (!existsSync92(dir)) mkdirSync46(dir, { recursive: true });
|
|
61007
61447
|
store.messages = store.messages.slice(-MESSAGES_MAX);
|
|
61008
61448
|
writeFileSync53(storePath(contextRoot), JSON.stringify(store, null, 2), "utf-8");
|
|
61009
61449
|
} catch (err) {
|
|
@@ -65101,21 +65541,21 @@ var init_wrapper = __esm({
|
|
|
65101
65541
|
// src/server/routes/agent-terminal.ts
|
|
65102
65542
|
import { spawn as spawn6 } from "child_process";
|
|
65103
65543
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
65104
|
-
import { createRequire } from "module";
|
|
65544
|
+
import { createRequire as createRequire2 } from "module";
|
|
65105
65545
|
import { basename as basename28, dirname as dirname54, join as join89 } from "path";
|
|
65106
|
-
import { existsSync as
|
|
65546
|
+
import { existsSync as existsSync93, readdirSync as readdirSync21, statSync as statSync19, chmodSync as chmodSync6, readFileSync as readFileSync65 } from "fs";
|
|
65107
65547
|
import { homedir as homedir7 } from "os";
|
|
65108
65548
|
function ensurePtyHelperExecutable() {
|
|
65109
65549
|
try {
|
|
65110
|
-
const require2 =
|
|
65550
|
+
const require2 = createRequire2(import.meta.url);
|
|
65111
65551
|
const root = dirname54(dirname54(require2.resolve("node-pty")));
|
|
65112
65552
|
const candidates = [join89(root, "build", "Release", "spawn-helper")];
|
|
65113
65553
|
const prebuilds = join89(root, "prebuilds");
|
|
65114
|
-
if (
|
|
65554
|
+
if (existsSync93(prebuilds)) {
|
|
65115
65555
|
for (const d of readdirSync21(prebuilds)) candidates.push(join89(prebuilds, d, "spawn-helper"));
|
|
65116
65556
|
}
|
|
65117
65557
|
for (const p of candidates) {
|
|
65118
|
-
if (!
|
|
65558
|
+
if (!existsSync93(p)) continue;
|
|
65119
65559
|
const mode = statSync19(p).mode;
|
|
65120
65560
|
if ((mode & 73) !== 73) chmodSync6(p, mode | 493);
|
|
65121
65561
|
}
|
|
@@ -65170,7 +65610,7 @@ function resolveVaultProjectRoot(name) {
|
|
|
65170
65610
|
if (!name) return null;
|
|
65171
65611
|
if (/[/\\:.\x00]/.test(name)) return null;
|
|
65172
65612
|
const v = listVaults().find((x) => x.name === name);
|
|
65173
|
-
if (!v || !
|
|
65613
|
+
if (!v || !existsSync93(v.path)) return null;
|
|
65174
65614
|
return v.path;
|
|
65175
65615
|
}
|
|
65176
65616
|
async function handleAgentCapabilities(_req, res) {
|
|
@@ -65242,7 +65682,7 @@ function cliPackageRoot() {
|
|
|
65242
65682
|
let dir = process.argv[1] ? dirname54(process.argv[1]) : "";
|
|
65243
65683
|
if (!dir) return null;
|
|
65244
65684
|
for (let i = 0; i < 8; i++) {
|
|
65245
|
-
if (
|
|
65685
|
+
if (existsSync93(join89(dir, "package.json"))) return dir;
|
|
65246
65686
|
const parent = dirname54(dir);
|
|
65247
65687
|
if (parent === dir) break;
|
|
65248
65688
|
dir = parent;
|
|
@@ -65419,12 +65859,12 @@ function findFirstTranscriptPath(ids) {
|
|
|
65419
65859
|
if (wanted.length === 0) return null;
|
|
65420
65860
|
try {
|
|
65421
65861
|
const base = join89(homedir7(), ".claude", "projects");
|
|
65422
|
-
if (!
|
|
65862
|
+
if (!existsSync93(base)) return null;
|
|
65423
65863
|
const dirs = readdirSync21(base);
|
|
65424
65864
|
for (const id of wanted) {
|
|
65425
65865
|
for (const dir of dirs) {
|
|
65426
65866
|
const p = join89(base, dir, `${id}.jsonl`);
|
|
65427
|
-
if (
|
|
65867
|
+
if (existsSync93(p)) return p;
|
|
65428
65868
|
}
|
|
65429
65869
|
}
|
|
65430
65870
|
} catch {
|
|
@@ -65964,7 +66404,7 @@ var init_agent_drop = __esm({
|
|
|
65964
66404
|
|
|
65965
66405
|
// src/server/routes/agent-sessions.ts
|
|
65966
66406
|
import { join as join91, dirname as dirname55 } from "path";
|
|
65967
|
-
import { existsSync as
|
|
66407
|
+
import { existsSync as existsSync94, mkdirSync as mkdirSync48, readFileSync as readFileSync66, writeFileSync as writeFileSync55, renameSync as renameSync17 } from "fs";
|
|
65968
66408
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
65969
66409
|
function storePath2(contextRoot) {
|
|
65970
66410
|
return join91(contextRoot, ROSTER_REL_PATH);
|
|
@@ -66004,7 +66444,7 @@ function writeRoster(contextRoot, sessions) {
|
|
|
66004
66444
|
} catch {
|
|
66005
66445
|
}
|
|
66006
66446
|
const dir = join91(contextRoot, "state");
|
|
66007
|
-
if (!
|
|
66447
|
+
if (!existsSync94(dir)) mkdirSync48(dir, { recursive: true });
|
|
66008
66448
|
const path2 = storePath2(contextRoot);
|
|
66009
66449
|
const tmp = `${path2}.${randomUUID8()}.tmp`;
|
|
66010
66450
|
writeFileSync55(tmp, JSON.stringify({ sessions }, null, 2) + "\n", "utf-8");
|
|
@@ -66142,7 +66582,7 @@ var init_connections2 = __esm({
|
|
|
66142
66582
|
});
|
|
66143
66583
|
|
|
66144
66584
|
// src/lib/federation-digest.ts
|
|
66145
|
-
import { existsSync as
|
|
66585
|
+
import { existsSync as existsSync95 } from "fs";
|
|
66146
66586
|
import { join as join92 } from "path";
|
|
66147
66587
|
function buildInterestProfile(peerRoot, topics) {
|
|
66148
66588
|
if (topics && topics.length > 0) {
|
|
@@ -66163,7 +66603,7 @@ function buildInterestProfile(peerRoot, topics) {
|
|
|
66163
66603
|
}
|
|
66164
66604
|
function activeTaskTerms(peerRoot) {
|
|
66165
66605
|
const stateDir = join92(peerRoot, "state");
|
|
66166
|
-
if (!
|
|
66606
|
+
if (!existsSync95(stateDir)) return [];
|
|
66167
66607
|
let files;
|
|
66168
66608
|
try {
|
|
66169
66609
|
files = import_fast_glob21.default.sync("*.md", { cwd: stateDir, absolute: true });
|
|
@@ -66521,8 +66961,10 @@ function corpusFor(contextRoot, types) {
|
|
|
66521
66961
|
async function handleRecallGet(req, res, _params, contextRoot) {
|
|
66522
66962
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
66523
66963
|
const query = (url.searchParams.get("q") ?? "").trim();
|
|
66964
|
+
const useHybrid = hybridReady(contextRoot, resolveRecallMode(contextRoot));
|
|
66965
|
+
const mode = useHybrid ? "hybrid" : "bm25";
|
|
66524
66966
|
if (!query) {
|
|
66525
|
-
sendJson(res, 200, { query: "", hits: [], tookMs: 0 });
|
|
66967
|
+
sendJson(res, 200, { query: "", mode, hits: [], tookMs: 0 });
|
|
66526
66968
|
return;
|
|
66527
66969
|
}
|
|
66528
66970
|
const types = parseTypes(url.searchParams.get("types")) ?? ALL_TYPES;
|
|
@@ -66531,9 +66973,9 @@ async function handleRecallGet(req, res, _params, contextRoot) {
|
|
|
66531
66973
|
try {
|
|
66532
66974
|
const started = Date.now();
|
|
66533
66975
|
const corpus = corpusFor(contextRoot, types);
|
|
66534
|
-
const hits = bm25Search(query, corpus, topK);
|
|
66976
|
+
const hits = useHybrid ? await hybridSearch(query, corpus, contextRoot, topK) : bm25Search(query, corpus, topK);
|
|
66535
66977
|
const tookMs = Date.now() - started;
|
|
66536
|
-
sendJson(res, 200, { query, tookMs, hits: hits.map(serializeHit) });
|
|
66978
|
+
sendJson(res, 200, { query, mode, tookMs, hits: hits.map(serializeHit) });
|
|
66537
66979
|
} catch (err) {
|
|
66538
66980
|
sendError(res, 500, "recall_failed", err instanceof Error ? err.message : "Recall failed");
|
|
66539
66981
|
}
|
|
@@ -66572,7 +67014,9 @@ var init_recall2 = __esm({
|
|
|
66572
67014
|
"src/server/routes/recall.ts"() {
|
|
66573
67015
|
"use strict";
|
|
66574
67016
|
init_recall();
|
|
67017
|
+
init_hybrid();
|
|
66575
67018
|
init_recall_query_extractor();
|
|
67019
|
+
init_sleep();
|
|
66576
67020
|
init_middleware();
|
|
66577
67021
|
ALL_TYPES = ["knowledge", "feature", "task", "memory", "changelog"];
|
|
66578
67022
|
CORPUS_TTL_MS = 8e3;
|
|
@@ -66890,8 +67334,88 @@ var init_team_fetch = __esm({
|
|
|
66890
67334
|
}
|
|
66891
67335
|
});
|
|
66892
67336
|
|
|
67337
|
+
// src/lib/git-sync/failure.ts
|
|
67338
|
+
function githubSlug(s) {
|
|
67339
|
+
const m = s.match(/github\.com[/:]([^/\s]+\/[^/\s'".]+)/i);
|
|
67340
|
+
return m ? m[1].replace(/\.git$/, "") : void 0;
|
|
67341
|
+
}
|
|
67342
|
+
function extractRepo(message, fallbackRepo) {
|
|
67343
|
+
const perm = message.match(/Permission to ([^\s]+?)(?:\.git)? denied/i);
|
|
67344
|
+
if (perm) return perm[1];
|
|
67345
|
+
const fromMsg = githubSlug(message);
|
|
67346
|
+
if (fromMsg) return fromMsg;
|
|
67347
|
+
if (fallbackRepo) return githubSlug(fallbackRepo) ?? fallbackRepo;
|
|
67348
|
+
return void 0;
|
|
67349
|
+
}
|
|
67350
|
+
function classifySyncError(rawMessage, repoHint) {
|
|
67351
|
+
const m = rawMessage || "";
|
|
67352
|
+
const repo = extractRepo(m, repoHint);
|
|
67353
|
+
const named = repo ? ` on ${repo}` : "";
|
|
67354
|
+
if (/non-fast-forward.*twice|rejected.*non-fast-forward|Push rejected \(non-fast-forward\) twice/i.test(m)) {
|
|
67355
|
+
return {
|
|
67356
|
+
kind: "push-rejected",
|
|
67357
|
+
recovery: "retry",
|
|
67358
|
+
repo,
|
|
67359
|
+
message: "The team pushed while your sync was in flight. Retry \u2014 dreamcontext will merge their changes and push again."
|
|
67360
|
+
};
|
|
67361
|
+
}
|
|
67362
|
+
if (/Contents\b.*write|permission to .* denied|protected branch|not authorized|remote: Permission|must have push access|403\b/i.test(m)) {
|
|
67363
|
+
return {
|
|
67364
|
+
kind: "permission",
|
|
67365
|
+
recovery: "check-permissions",
|
|
67366
|
+
repo,
|
|
67367
|
+
message: `Your GitHub token can't write to${named || " this repo"}. Give it Contents (read & write) access${repo ? ` on ${repo}` : ""}, then retry.`
|
|
67368
|
+
};
|
|
67369
|
+
}
|
|
67370
|
+
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)) {
|
|
67371
|
+
return {
|
|
67372
|
+
kind: "auth",
|
|
67373
|
+
recovery: "reconnect-github",
|
|
67374
|
+
repo,
|
|
67375
|
+
message: "Your GitHub sign-in expired or is invalid. Reconnect GitHub to keep syncing."
|
|
67376
|
+
};
|
|
67377
|
+
}
|
|
67378
|
+
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)) {
|
|
67379
|
+
return {
|
|
67380
|
+
kind: "network",
|
|
67381
|
+
recovery: "wait-online",
|
|
67382
|
+
repo,
|
|
67383
|
+
message: "You're offline \u2014 sync will retry automatically when you're back online. Nothing was lost."
|
|
67384
|
+
};
|
|
67385
|
+
}
|
|
67386
|
+
if (/unrelated histories/i.test(m)) {
|
|
67387
|
+
return {
|
|
67388
|
+
kind: "unknown",
|
|
67389
|
+
recovery: "manual",
|
|
67390
|
+
repo,
|
|
67391
|
+
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."
|
|
67392
|
+
};
|
|
67393
|
+
}
|
|
67394
|
+
return {
|
|
67395
|
+
kind: "unknown",
|
|
67396
|
+
recovery: "retry",
|
|
67397
|
+
repo,
|
|
67398
|
+
message: rawMessage.trim() || "Sync failed. Retry, or check your connection and GitHub access."
|
|
67399
|
+
};
|
|
67400
|
+
}
|
|
67401
|
+
var init_failure = __esm({
|
|
67402
|
+
"src/lib/git-sync/failure.ts"() {
|
|
67403
|
+
"use strict";
|
|
67404
|
+
}
|
|
67405
|
+
});
|
|
67406
|
+
|
|
66893
67407
|
// src/server/routes/brain.ts
|
|
66894
67408
|
import { dirname as dirname61 } from "path";
|
|
67409
|
+
function mergeKindFor(contextRoot, hasMergeHead2, pendingAgentMerge) {
|
|
67410
|
+
if (hasMergeHead2) {
|
|
67411
|
+
const report = readConflictReport(contextRoot);
|
|
67412
|
+
if (!report) return "user";
|
|
67413
|
+
if (report.codeConflicts && report.codeConflicts.length > 0) return "code";
|
|
67414
|
+
return "agent";
|
|
67415
|
+
}
|
|
67416
|
+
if (pendingAgentMerge) return "agent";
|
|
67417
|
+
return null;
|
|
67418
|
+
}
|
|
66895
67419
|
function gate2(res) {
|
|
66896
67420
|
if (!isDesktop()) {
|
|
66897
67421
|
sendError(res, 403, "desktop_only", "Brain cloud-sync is only available in the desktop app.");
|
|
@@ -66921,6 +67445,17 @@ async function handleBrainStatus(_req, res, _params, contextRoot) {
|
|
|
66921
67445
|
} catch {
|
|
66922
67446
|
mergeInProgress = false;
|
|
66923
67447
|
}
|
|
67448
|
+
} else if (mode === "full-repo") {
|
|
67449
|
+
try {
|
|
67450
|
+
remote = isGitRepo(projectRoot) ? getRemoteUrl(projectRoot, "origin") : null;
|
|
67451
|
+
} catch {
|
|
67452
|
+
remote = null;
|
|
67453
|
+
}
|
|
67454
|
+
try {
|
|
67455
|
+
mergeInProgress = hasMergeHead(projectRoot);
|
|
67456
|
+
} catch {
|
|
67457
|
+
mergeInProgress = false;
|
|
67458
|
+
}
|
|
66924
67459
|
}
|
|
66925
67460
|
let codeOrigin = null;
|
|
66926
67461
|
try {
|
|
@@ -66928,6 +67463,15 @@ async function handleBrainStatus(_req, res, _params, contextRoot) {
|
|
|
66928
67463
|
} catch {
|
|
66929
67464
|
codeOrigin = null;
|
|
66930
67465
|
}
|
|
67466
|
+
const mergeKind = mergeKindFor(contextRoot, mergeInProgress, !!local.pendingAgentMerge);
|
|
67467
|
+
let codeConflicts = [];
|
|
67468
|
+
if (mergeKind === "code") {
|
|
67469
|
+
try {
|
|
67470
|
+
codeConflicts = readConflictReport(contextRoot)?.codeConflicts ?? [];
|
|
67471
|
+
} catch {
|
|
67472
|
+
codeConflicts = [];
|
|
67473
|
+
}
|
|
67474
|
+
}
|
|
66931
67475
|
sendJson(res, 200, {
|
|
66932
67476
|
enabled: enabled.enabled,
|
|
66933
67477
|
source: enabled.source,
|
|
@@ -66936,6 +67480,8 @@ async function handleBrainStatus(_req, res, _params, contextRoot) {
|
|
|
66936
67480
|
hasRemote: !!remote,
|
|
66937
67481
|
codeOrigin,
|
|
66938
67482
|
mergeInProgress,
|
|
67483
|
+
mergeKind,
|
|
67484
|
+
codeConflicts,
|
|
66939
67485
|
pendingAgentMerge: !!local.pendingAgentMerge,
|
|
66940
67486
|
pulledUpdates: local.pulledUpdates ?? 0
|
|
66941
67487
|
});
|
|
@@ -67077,18 +67623,48 @@ async function handleBrainDisconnect(_req, res, _params, contextRoot) {
|
|
|
67077
67623
|
}
|
|
67078
67624
|
async function handleBrainSync(req, res, _params, contextRoot) {
|
|
67079
67625
|
if (!gate2(res)) return;
|
|
67626
|
+
const projectRoot = dirname61(contextRoot);
|
|
67080
67627
|
const body = await parseJsonBody(req);
|
|
67081
67628
|
const mode = body?.mode === "auto" ? "auto" : "pull-only";
|
|
67629
|
+
const foreground = body?.foreground !== false;
|
|
67630
|
+
const noCheckpoint = body?.noCheckpoint === true;
|
|
67082
67631
|
try {
|
|
67083
|
-
const result = await runBrainSync({ cwd: contextRoot, mode });
|
|
67632
|
+
const result = await runBrainSync({ cwd: contextRoot, mode, foreground, noCheckpoint });
|
|
67633
|
+
let failure;
|
|
67634
|
+
if (result.action === "no-remote" && /token/i.test(result.note ?? "")) {
|
|
67635
|
+
failure = classifySyncError(result.note ?? "no github token found", syncRepoHint(projectRoot, result));
|
|
67636
|
+
}
|
|
67084
67637
|
sendJson(res, 200, {
|
|
67085
67638
|
action: result.action,
|
|
67086
67639
|
pulledUpdates: result.pulledUpdates ?? 0,
|
|
67087
67640
|
scrub: { blocks: result.scrub.blocks, warns: result.scrub.warns },
|
|
67088
|
-
note: result.note
|
|
67641
|
+
note: result.note,
|
|
67642
|
+
checkpointed: !!result.checkpointed,
|
|
67643
|
+
checkpointSha: result.checkpointSha,
|
|
67644
|
+
codeConflicts: result.codeConflicts,
|
|
67645
|
+
failure
|
|
67089
67646
|
});
|
|
67090
67647
|
} catch (err) {
|
|
67091
|
-
|
|
67648
|
+
const failure = classifySyncError(err.message, syncRepoHint(projectRoot));
|
|
67649
|
+
sendJson(res, 200, {
|
|
67650
|
+
action: "error",
|
|
67651
|
+
pulledUpdates: 0,
|
|
67652
|
+
scrub: { blocks: [], warns: [] },
|
|
67653
|
+
note: failure.message,
|
|
67654
|
+
failure
|
|
67655
|
+
});
|
|
67656
|
+
}
|
|
67657
|
+
}
|
|
67658
|
+
function syncRepoHint(projectRoot, _result) {
|
|
67659
|
+
const config = readSetupConfig(projectRoot);
|
|
67660
|
+
const mode = resolveMode2(config);
|
|
67661
|
+
try {
|
|
67662
|
+
if (mode === "full-repo" || mode === "in-tree") {
|
|
67663
|
+
return (isGitRepo(projectRoot) ? getRemoteUrl(projectRoot, "origin") : null) ?? void 0;
|
|
67664
|
+
}
|
|
67665
|
+
return config?.brainRepo?.remote ?? void 0;
|
|
67666
|
+
} catch {
|
|
67667
|
+
return config?.brainRepo?.remote ?? void 0;
|
|
67092
67668
|
}
|
|
67093
67669
|
}
|
|
67094
67670
|
async function handleBrainSettingsGet2(_req, res, _params, contextRoot) {
|
|
@@ -67127,6 +67703,82 @@ async function handleBrainSettingsPost(req, res, _params, contextRoot) {
|
|
|
67127
67703
|
remote: next?.brainRepo?.remote ?? null
|
|
67128
67704
|
});
|
|
67129
67705
|
}
|
|
67706
|
+
async function handleBrainScope(req, res, _params, contextRoot) {
|
|
67707
|
+
if (!gate2(res)) return;
|
|
67708
|
+
const projectRoot = dirname61(contextRoot);
|
|
67709
|
+
const body = await parseJsonBody(req);
|
|
67710
|
+
const scope = body?.scope === "full-repo" ? "full-repo" : body?.scope === "brain" ? "brain" : null;
|
|
67711
|
+
if (!scope) {
|
|
67712
|
+
sendError(res, 400, "invalid_body", "scope must be 'full-repo' or 'brain'.");
|
|
67713
|
+
return;
|
|
67714
|
+
}
|
|
67715
|
+
const config = readSetupConfig(projectRoot);
|
|
67716
|
+
const existing = config?.brainRepo ?? { mode: "in-tree" };
|
|
67717
|
+
if (scope === "full-repo") {
|
|
67718
|
+
let origin = null;
|
|
67719
|
+
try {
|
|
67720
|
+
origin = isGitRepo(projectRoot) ? getRemoteUrl(projectRoot, "origin") : null;
|
|
67721
|
+
} catch {
|
|
67722
|
+
origin = null;
|
|
67723
|
+
}
|
|
67724
|
+
if (!origin) {
|
|
67725
|
+
sendError(res, 400, "no_origin", "Whole-project sync needs a GitHub `origin` on this project. Add one (git remote add origin \u2026) and try again.");
|
|
67726
|
+
return;
|
|
67727
|
+
}
|
|
67728
|
+
updateSetupConfig(projectRoot, {
|
|
67729
|
+
brainRepo: { ...existing, mode: "full-repo", enabled: true, autoSync: true }
|
|
67730
|
+
});
|
|
67731
|
+
ensureFullRepoGitignore(projectRoot, config?.taskBackend);
|
|
67732
|
+
} else {
|
|
67733
|
+
const nextMode = existing.remote ? "separate" : "in-tree";
|
|
67734
|
+
updateSetupConfig(projectRoot, { brainRepo: { ...existing, mode: nextMode } });
|
|
67735
|
+
}
|
|
67736
|
+
const next = readSetupConfig(projectRoot);
|
|
67737
|
+
const resolved = resolveBrainSyncEnabled(projectRoot, next);
|
|
67738
|
+
sendJson(res, 200, {
|
|
67739
|
+
enabled: resolved.enabled,
|
|
67740
|
+
source: resolved.source,
|
|
67741
|
+
mode: resolveMode2(next),
|
|
67742
|
+
autoSync: next?.brainRepo?.autoSync ?? false,
|
|
67743
|
+
remote: next?.brainRepo?.remote ?? null
|
|
67744
|
+
});
|
|
67745
|
+
}
|
|
67746
|
+
function isSafeToGitignore(relPath) {
|
|
67747
|
+
const p = relPath.replace(/\\/g, "/").trim();
|
|
67748
|
+
if (!p) return false;
|
|
67749
|
+
if (/[!#*?[\]\r\n\0]/.test(p)) return false;
|
|
67750
|
+
if (p.startsWith("/") || p.split("/").includes("..")) return false;
|
|
67751
|
+
return SAFE_TO_GITIGNORE.test(p);
|
|
67752
|
+
}
|
|
67753
|
+
async function handleBrainScrubIgnore(req, res, _params, contextRoot) {
|
|
67754
|
+
if (!gate2(res)) return;
|
|
67755
|
+
const projectRoot = dirname61(contextRoot);
|
|
67756
|
+
const body = await parseJsonBody(req);
|
|
67757
|
+
const rawPath = typeof body?.path === "string" ? body.path.trim() : "";
|
|
67758
|
+
if (!rawPath) {
|
|
67759
|
+
sendError(res, 400, "invalid_body", "path is required.");
|
|
67760
|
+
return;
|
|
67761
|
+
}
|
|
67762
|
+
const relPath = rawPath.replace(/\\/g, "/");
|
|
67763
|
+
if (relPath.startsWith("/") || relPath.split("/").includes("..")) {
|
|
67764
|
+
sendError(res, 400, "invalid_path", "That path is not allowed.");
|
|
67765
|
+
return;
|
|
67766
|
+
}
|
|
67767
|
+
if (!isSafeToGitignore(relPath)) {
|
|
67768
|
+
sendError(res, 400, "unsafe_path", "That looks like a real source file \u2014 remove the secret from it instead of un-tracking it.");
|
|
67769
|
+
return;
|
|
67770
|
+
}
|
|
67771
|
+
const mode = resolveMode2(readSetupConfig(projectRoot));
|
|
67772
|
+
const root = mode === "separate" ? contextRoot : projectRoot;
|
|
67773
|
+
try {
|
|
67774
|
+
const added = ensureGitignoreEntries(root, [relPath], {
|
|
67775
|
+
comment: "dreamcontext: excluded a scrub-blocked local secret file (added from the dashboard)"
|
|
67776
|
+
});
|
|
67777
|
+
sendJson(res, 200, { ok: true, added, path: relPath });
|
|
67778
|
+
} catch (err) {
|
|
67779
|
+
sendError(res, 502, "gitignore_failed", err.message);
|
|
67780
|
+
}
|
|
67781
|
+
}
|
|
67130
67782
|
async function handleBrainTeamUpdates(_req, res) {
|
|
67131
67783
|
if (!gate2(res)) return;
|
|
67132
67784
|
const vaults = listVaults().map((v) => {
|
|
@@ -67155,6 +67807,7 @@ async function handleBrainTeamFetch(req, res) {
|
|
|
67155
67807
|
sendError(res, 502, "team_fetch_failed", err.message);
|
|
67156
67808
|
}
|
|
67157
67809
|
}
|
|
67810
|
+
var SAFE_TO_GITIGNORE;
|
|
67158
67811
|
var init_brain2 = __esm({
|
|
67159
67812
|
"src/server/routes/brain.ts"() {
|
|
67160
67813
|
"use strict";
|
|
@@ -67169,7 +67822,11 @@ var init_brain2 = __esm({
|
|
|
67169
67822
|
init_sync_engine();
|
|
67170
67823
|
init_auth_store();
|
|
67171
67824
|
init_team_fetch();
|
|
67825
|
+
init_conflict_report();
|
|
67826
|
+
init_failure();
|
|
67827
|
+
init_gitignore();
|
|
67172
67828
|
init_vaults();
|
|
67829
|
+
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;
|
|
67173
67830
|
}
|
|
67174
67831
|
});
|
|
67175
67832
|
|
|
@@ -67221,6 +67878,10 @@ function buildRouter() {
|
|
|
67221
67878
|
router.post("/api/tasks/:slug/insert", handleTasksInsert);
|
|
67222
67879
|
router.get("/api/sleep", handleSleepGet);
|
|
67223
67880
|
router.patch("/api/sleep", handleSleepUpdate);
|
|
67881
|
+
router.get("/api/embeddings/status", handleEmbeddingModelStatus);
|
|
67882
|
+
router.post("/api/embeddings/download", handleEmbeddingModelDownload);
|
|
67883
|
+
router.get("/api/embeddings/index/status", handleEmbeddingIndexStatus);
|
|
67884
|
+
router.post("/api/embeddings/index", handleEmbeddingIndexBuild);
|
|
67224
67885
|
router.get("/api/core", handleCoreList);
|
|
67225
67886
|
router.get("/api/core/:filename", handleCoreGet);
|
|
67226
67887
|
router.put("/api/core/:filename", handleCoreUpdate);
|
|
@@ -67246,6 +67907,8 @@ function buildRouter() {
|
|
|
67246
67907
|
router.post("/api/brain/sync", handleBrainSync);
|
|
67247
67908
|
router.get("/api/brain/settings", handleBrainSettingsGet2);
|
|
67248
67909
|
router.post("/api/brain/settings", handleBrainSettingsPost);
|
|
67910
|
+
router.post("/api/brain/scope", handleBrainScope);
|
|
67911
|
+
router.post("/api/brain/scrub/ignore", handleBrainScrubIgnore);
|
|
67249
67912
|
router.get("/api/graph", handleGraphGet);
|
|
67250
67913
|
router.get("/api/graph/content", handleGraphContentGet);
|
|
67251
67914
|
router.get("/api/council", handleCouncilList);
|
|
@@ -67453,6 +68116,7 @@ var init_server = __esm({
|
|
|
67453
68116
|
init_health();
|
|
67454
68117
|
init_tasks2();
|
|
67455
68118
|
init_sleep2();
|
|
68119
|
+
init_embeddings();
|
|
67456
68120
|
init_core2();
|
|
67457
68121
|
init_knowledge2();
|
|
67458
68122
|
init_changelog();
|
|
@@ -67482,7 +68146,7 @@ var init_server = __esm({
|
|
|
67482
68146
|
init_lifecycle();
|
|
67483
68147
|
init_admin();
|
|
67484
68148
|
init_manifest();
|
|
67485
|
-
VAULT_AGNOSTIC_PREFIXES = ["/api/health", "/api/admin/shutdown", "/api/vaults", "/api/launcher", "/api/sleepy", "/api/agent/capabilities", "/api/agent/install", "/api/agent/model-config", "/api/agent/session-model", "/api/agent/session-stats", "/api/brain/auth", "/api/brain/team"];
|
|
68149
|
+
VAULT_AGNOSTIC_PREFIXES = ["/api/health", "/api/admin/shutdown", "/api/vaults", "/api/launcher", "/api/sleepy", "/api/embeddings", "/api/agent/capabilities", "/api/agent/install", "/api/agent/model-config", "/api/agent/session-model", "/api/agent/session-stats", "/api/brain/auth", "/api/brain/team"];
|
|
67486
68150
|
}
|
|
67487
68151
|
});
|
|
67488
68152
|
|
|
@@ -67666,7 +68330,7 @@ var init_trigger = __esm({
|
|
|
67666
68330
|
});
|
|
67667
68331
|
|
|
67668
68332
|
// src/lib/reflection.ts
|
|
67669
|
-
import { existsSync as
|
|
68333
|
+
import { existsSync as existsSync96, mkdirSync as mkdirSync49, writeFileSync as writeFileSync56 } from "fs";
|
|
67670
68334
|
import { join as join95, dirname as dirname62 } from "path";
|
|
67671
68335
|
function buildExclusionSet(corpus, excludedExtra) {
|
|
67672
68336
|
const excluded = new Set(excludedExtra);
|
|
@@ -67848,7 +68512,7 @@ function reflectionPath(root) {
|
|
|
67848
68512
|
function writeReflection(root, md) {
|
|
67849
68513
|
const outPath = reflectionPath(root);
|
|
67850
68514
|
const dir = dirname62(outPath);
|
|
67851
|
-
if (!
|
|
68515
|
+
if (!existsSync96(dir)) {
|
|
67852
68516
|
mkdirSync49(dir, { recursive: true });
|
|
67853
68517
|
}
|
|
67854
68518
|
const tsMatch = md.match(/Generated: ([^\n]+)/);
|
|
@@ -68036,12 +68700,12 @@ var init_reflection = __esm({
|
|
|
68036
68700
|
});
|
|
68037
68701
|
|
|
68038
68702
|
// src/cli/commands/reflect.ts
|
|
68039
|
-
import { existsSync as
|
|
68703
|
+
import { existsSync as existsSync97, readFileSync as readFileSync69 } from "fs";
|
|
68040
68704
|
import { join as join96 } from "path";
|
|
68041
68705
|
function buildBookmarkSessions(root) {
|
|
68042
68706
|
const sleepPath = join96(root, "state", ".sleep.json");
|
|
68043
68707
|
const result = /* @__PURE__ */ new Map();
|
|
68044
|
-
if (!
|
|
68708
|
+
if (!existsSync97(sleepPath)) return result;
|
|
68045
68709
|
try {
|
|
68046
68710
|
const parsed = JSON.parse(readFileSync69(sleepPath, "utf-8"));
|
|
68047
68711
|
const bookmarks = parsed.bookmarks ?? [];
|
|
@@ -68061,7 +68725,7 @@ function buildExcludedExtra(root) {
|
|
|
68061
68725
|
join96(root, "core", "1.user.md")
|
|
68062
68726
|
];
|
|
68063
68727
|
for (const filePath of coreFiles) {
|
|
68064
|
-
if (!
|
|
68728
|
+
if (!existsSync97(filePath)) continue;
|
|
68065
68729
|
try {
|
|
68066
68730
|
const content = readFileSync69(filePath, "utf-8");
|
|
68067
68731
|
for (const tok of tokenize(content)) {
|
|
@@ -68114,7 +68778,7 @@ var init_reflect = __esm({
|
|
|
68114
68778
|
});
|
|
68115
68779
|
|
|
68116
68780
|
// src/cli/commands/council.ts
|
|
68117
|
-
import { existsSync as
|
|
68781
|
+
import { existsSync as existsSync98, mkdirSync as mkdirSync50, readFileSync as readFileSync70, writeFileSync as writeFileSync57 } from "fs";
|
|
68118
68782
|
import { join as join97 } from "path";
|
|
68119
68783
|
function roundRunningStatus(n) {
|
|
68120
68784
|
return `round_${n}_running`;
|
|
@@ -68205,7 +68869,7 @@ function registerAgent(council) {
|
|
|
68205
68869
|
}
|
|
68206
68870
|
const personaDir = getPersonaDir(debateId, slug);
|
|
68207
68871
|
const personaFile = join97(personaDir, "context-and-persona.md");
|
|
68208
|
-
if (
|
|
68872
|
+
if (existsSync98(personaFile) && !opts.force) {
|
|
68209
68873
|
error(`Persona already exists: ${slug}`, "Use --force to overwrite.");
|
|
68210
68874
|
process.exit(1);
|
|
68211
68875
|
}
|
|
@@ -68261,7 +68925,7 @@ function registerRound(council) {
|
|
|
68261
68925
|
if (n >= 2) {
|
|
68262
68926
|
for (const persona of personas) {
|
|
68263
68927
|
const personaFile = join97(getPersonaDir(debateId, persona), "context-and-persona.md");
|
|
68264
|
-
if (!
|
|
68928
|
+
if (!existsSync98(personaFile)) continue;
|
|
68265
68929
|
const existing = readFileSync70(personaFile, "utf-8");
|
|
68266
68930
|
if (existing.includes(crossContextHeader)) {
|
|
68267
68931
|
continue;
|
|
@@ -68293,7 +68957,7 @@ ${peerLines.join("\n\n")}`;
|
|
|
68293
68957
|
updated_at: today()
|
|
68294
68958
|
});
|
|
68295
68959
|
const logFile = join97(getDebateDir(debateId), "round-log.md");
|
|
68296
|
-
const logExisting =
|
|
68960
|
+
const logExisting = existsSync98(logFile) ? readFileSync70(logFile, "utf-8") : "";
|
|
68297
68961
|
const logEntry = `
|
|
68298
68962
|
## Round ${n} started \u2014 ${today()}
|
|
68299
68963
|
- Personas: ${formatPersonaList(personas)}
|
|
@@ -68338,7 +69002,7 @@ ${peerLines.join("\n\n")}`;
|
|
|
68338
69002
|
updated_at: today()
|
|
68339
69003
|
});
|
|
68340
69004
|
const logFile = join97(getDebateDir(debateId), "round-log.md");
|
|
68341
|
-
const logExisting =
|
|
69005
|
+
const logExisting = existsSync98(logFile) ? readFileSync70(logFile, "utf-8") : "";
|
|
68342
69006
|
const logEntry = `
|
|
68343
69007
|
## Round ${n} complete \u2014 ${today()}
|
|
68344
69008
|
- All ${personas.length} personas submitted reports.
|
|
@@ -68488,10 +69152,10 @@ function registerResearch(council) {
|
|
|
68488
69152
|
const researchesDir = join97(getPersonaDir(debateId, personaSlug), "researches");
|
|
68489
69153
|
mkdirSync50(researchesDir, { recursive: true });
|
|
68490
69154
|
const indexPath2 = join97(researchesDir, "index.json");
|
|
68491
|
-
if (!
|
|
69155
|
+
if (!existsSync98(indexPath2)) writeJsonArray(indexPath2, []);
|
|
68492
69156
|
const slug = slugify(topic);
|
|
68493
69157
|
const file = join97(researchesDir, `${slug}.md`);
|
|
68494
|
-
if (
|
|
69158
|
+
if (existsSync98(file)) {
|
|
68495
69159
|
error(`Research note already exists: ${slug}.md`);
|
|
68496
69160
|
process.exit(1);
|
|
68497
69161
|
}
|
|
@@ -68523,7 +69187,7 @@ ${body.trim()}
|
|
|
68523
69187
|
ensurePersonaExists(debateId, personaSlug);
|
|
68524
69188
|
const researchesDir = join97(getPersonaDir(debateId, personaSlug), "researches");
|
|
68525
69189
|
const indexPath2 = join97(researchesDir, "index.json");
|
|
68526
|
-
if (!
|
|
69190
|
+
if (!existsSync98(indexPath2)) {
|
|
68527
69191
|
console.log(source_default.dim("(no researches)"));
|
|
68528
69192
|
return;
|
|
68529
69193
|
}
|
|
@@ -68568,7 +69232,7 @@ function registerSynthesize(council) {
|
|
|
68568
69232
|
manifest.push(`_dream_context/council/${debateId}/${persona}/context-and-persona.md`);
|
|
68569
69233
|
manifest.push(`_dream_context/council/${debateId}/${persona}/report.md`);
|
|
68570
69234
|
const researchesIndex = join97(personaDir, "researches", "index.json");
|
|
68571
|
-
if (
|
|
69235
|
+
if (existsSync98(researchesIndex)) {
|
|
68572
69236
|
manifest.push(`_dream_context/council/${debateId}/${persona}/researches/`);
|
|
68573
69237
|
}
|
|
68574
69238
|
}
|
|
@@ -68587,7 +69251,7 @@ function registerComplete(council) {
|
|
|
68587
69251
|
try {
|
|
68588
69252
|
const data = readDebateFrontmatter(debateId);
|
|
68589
69253
|
const finalReport = join97(getDebateDir(debateId), "final-report.md");
|
|
68590
|
-
if (!
|
|
69254
|
+
if (!existsSync98(finalReport)) {
|
|
68591
69255
|
error("final-report.md not found.", "Synthesizer must write it before calling `council complete`.");
|
|
68592
69256
|
process.exit(1);
|
|
68593
69257
|
}
|
|
@@ -68624,7 +69288,7 @@ function registerPromote(council) {
|
|
|
68624
69288
|
process.exit(1);
|
|
68625
69289
|
}
|
|
68626
69290
|
const finalReport = join97(getDebateDir(debateId), "final-report.md");
|
|
68627
|
-
if (!
|
|
69291
|
+
if (!existsSync98(finalReport)) {
|
|
68628
69292
|
error("final-report.md not found.");
|
|
68629
69293
|
process.exit(1);
|
|
68630
69294
|
}
|
|
@@ -68642,7 +69306,7 @@ ${sec.body.trim()}` : null;
|
|
|
68642
69306
|
const slug = slugify(data.topic).slice(0, 80) || debateId;
|
|
68643
69307
|
const filename = `decision-${slug}.md`;
|
|
68644
69308
|
const target = join97(knowledgeDir, filename);
|
|
68645
|
-
if (
|
|
69309
|
+
if (existsSync98(target) && !opts.force) {
|
|
68646
69310
|
error(`Knowledge file exists: ${filename}`, "Use --force to overwrite.");
|
|
68647
69311
|
process.exit(1);
|
|
68648
69312
|
}
|
|
@@ -68729,7 +69393,7 @@ function registerShow(council) {
|
|
|
68729
69393
|
console.log(` created: ${data.created_at}`);
|
|
68730
69394
|
console.log(` updated: ${data.updated_at}`);
|
|
68731
69395
|
const logFile = join97(getDebateDir(debateId), "round-log.md");
|
|
68732
|
-
if (
|
|
69396
|
+
if (existsSync98(logFile)) {
|
|
68733
69397
|
console.log("\n" + source_default.dim("\u2500\u2500\u2500 Round log \u2500\u2500\u2500"));
|
|
68734
69398
|
console.log(readFileSync70(logFile, "utf-8"));
|
|
68735
69399
|
}
|
|
@@ -68923,11 +69587,11 @@ var init_env_loader = __esm({
|
|
|
68923
69587
|
});
|
|
68924
69588
|
|
|
68925
69589
|
// src/lib/marketing/config.ts
|
|
68926
|
-
import { existsSync as
|
|
69590
|
+
import { existsSync as existsSync99, readFileSync as readFileSync71, writeFileSync as writeFileSync58, mkdirSync as mkdirSync51 } from "fs";
|
|
68927
69591
|
import { dirname as dirname63 } from "path";
|
|
68928
69592
|
function readEnvFile() {
|
|
68929
69593
|
const path2 = MARKETING_PATHS.envFile();
|
|
68930
|
-
if (!
|
|
69594
|
+
if (!existsSync99(path2)) return {};
|
|
68931
69595
|
const raw = readFileSync71(path2, "utf8");
|
|
68932
69596
|
const parsed = parseEnv(raw);
|
|
68933
69597
|
if (parsed.errors.length > 0) {
|
|
@@ -68972,7 +69636,7 @@ function requireEnv(keys = REQUIRED_KEYS) {
|
|
|
68972
69636
|
}
|
|
68973
69637
|
function loadConfig() {
|
|
68974
69638
|
const path2 = MARKETING_PATHS.configFile();
|
|
68975
|
-
if (!
|
|
69639
|
+
if (!existsSync99(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
|
|
68976
69640
|
try {
|
|
68977
69641
|
const raw = readFileSync71(path2, "utf8");
|
|
68978
69642
|
const parsed = JSON.parse(raw);
|
|
@@ -68994,14 +69658,14 @@ function writeConfig(cfg) {
|
|
|
68994
69658
|
}
|
|
68995
69659
|
function ensureConfigFile() {
|
|
68996
69660
|
const path2 = MARKETING_PATHS.configFile();
|
|
68997
|
-
if (
|
|
69661
|
+
if (existsSync99(path2)) return loadConfig();
|
|
68998
69662
|
const cfg = { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
|
|
68999
69663
|
writeConfig(cfg);
|
|
69000
69664
|
return cfg;
|
|
69001
69665
|
}
|
|
69002
69666
|
function ensureEnvFile() {
|
|
69003
69667
|
const path2 = MARKETING_PATHS.envFile();
|
|
69004
|
-
if (
|
|
69668
|
+
if (existsSync99(path2)) return;
|
|
69005
69669
|
mkdirSync51(marketingRoot(), { recursive: true });
|
|
69006
69670
|
writeFileSync58(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
|
|
69007
69671
|
}
|
|
@@ -69044,7 +69708,7 @@ REINFLUENCE_BIN= # optional override; default uses .venv
|
|
|
69044
69708
|
|
|
69045
69709
|
// src/lib/marketing/bootstrap.ts
|
|
69046
69710
|
import { spawn as spawn7, spawnSync as spawnSync2 } from "child_process";
|
|
69047
|
-
import { existsSync as
|
|
69711
|
+
import { existsSync as existsSync100, mkdirSync as mkdirSync52, cpSync as cpSync3 } from "fs";
|
|
69048
69712
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
69049
69713
|
import { dirname as dirname64, resolve as resolve22, join as join98 } from "path";
|
|
69050
69714
|
function findBundledReinfluence() {
|
|
@@ -69056,7 +69720,7 @@ function findBundledReinfluence() {
|
|
|
69056
69720
|
resolve22(__dirname7, "..", "..", "..", "tools", "reinfluence")
|
|
69057
69721
|
];
|
|
69058
69722
|
for (const c of candidates) {
|
|
69059
|
-
if (
|
|
69723
|
+
if (existsSync100(join98(c, "__main__.py"))) return c;
|
|
69060
69724
|
}
|
|
69061
69725
|
throw new Error(
|
|
69062
69726
|
"Bundled reinfluence not found. Reinstall dreamcontext or set REINFLUENCE_BIN."
|
|
@@ -69098,7 +69762,7 @@ async function bootstrapMarketing(opts = {}) {
|
|
|
69098
69762
|
throw new Error("python3 not found on PATH. Install Python 3.10+ and retry.");
|
|
69099
69763
|
}
|
|
69100
69764
|
const venv = MARKETING_PATHS.venvDir();
|
|
69101
|
-
if (!
|
|
69765
|
+
if (!existsSync100(MARKETING_PATHS.venvPython())) {
|
|
69102
69766
|
log(`creating venv \u2192 ${venv}`);
|
|
69103
69767
|
const r2 = runBlocking(py, ["-m", "venv", venv]);
|
|
69104
69768
|
if (r2.code !== 0) {
|
|
@@ -69169,7 +69833,7 @@ function subprocessEnv() {
|
|
|
69169
69833
|
};
|
|
69170
69834
|
}
|
|
69171
69835
|
function isBootstrapped() {
|
|
69172
|
-
return
|
|
69836
|
+
return existsSync100(MARKETING_PATHS.venvPython()) && existsSync100(join98(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
|
|
69173
69837
|
}
|
|
69174
69838
|
var __filename, __dirname7;
|
|
69175
69839
|
var init_bootstrap = __esm({
|
|
@@ -69246,7 +69910,7 @@ var init_init2 = __esm({
|
|
|
69246
69910
|
});
|
|
69247
69911
|
|
|
69248
69912
|
// src/lib/marketing/vision.ts
|
|
69249
|
-
import { existsSync as
|
|
69913
|
+
import { existsSync as existsSync101, readFileSync as readFileSync72, writeFileSync as writeFileSync59 } from "fs";
|
|
69250
69914
|
import { dirname as dirname65, join as join99 } from "path";
|
|
69251
69915
|
function pickVisionProvider(env2 = process.env) {
|
|
69252
69916
|
const oai = env2.OPENAI_VISION_API_KEY;
|
|
@@ -69290,7 +69954,7 @@ async function readImageAsBase64(framePath) {
|
|
|
69290
69954
|
return buf.toString("base64");
|
|
69291
69955
|
}
|
|
69292
69956
|
async function labelHookFrame(framePath, opts) {
|
|
69293
|
-
if (!
|
|
69957
|
+
if (!existsSync101(framePath)) return [];
|
|
69294
69958
|
const fetcher = opts.fetcher ?? defaultFetcher;
|
|
69295
69959
|
const prompt = opts.promptOverride ?? PROMPT;
|
|
69296
69960
|
const b64 = await readImageAsBase64(framePath);
|
|
@@ -69383,7 +70047,7 @@ async function runVisionPassOnPost(postJsonPath, opts = {}) {
|
|
|
69383
70047
|
const fs = await import("fs");
|
|
69384
70048
|
fs.renameSync(tmp, postJsonPath);
|
|
69385
70049
|
const mdPath = join99(dirname65(postJsonPath), `${shortcode}.md`);
|
|
69386
|
-
if (
|
|
70050
|
+
if (existsSync101(mdPath)) {
|
|
69387
70051
|
try {
|
|
69388
70052
|
const md = readFileSync72(mdPath, "utf-8");
|
|
69389
70053
|
const refreshed = updatePatternTagsInBridge(md, post.pattern_tags);
|
|
@@ -69462,7 +70126,7 @@ Example output: ["talking-head","prop-driven"]`;
|
|
|
69462
70126
|
// src/lib/marketing/competitors.ts
|
|
69463
70127
|
import { spawn as spawn8 } from "child_process";
|
|
69464
70128
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
69465
|
-
import { existsSync as
|
|
70129
|
+
import { existsSync as existsSync102, mkdirSync as mkdirSync54, statfsSync } from "fs";
|
|
69466
70130
|
import { dirname as dirname66, join as join100, basename as basename30, extname as extname6 } from "path";
|
|
69467
70131
|
function which(cmd) {
|
|
69468
70132
|
const r = spawnSync3(process.platform === "win32" ? "where" : "which", [cmd], { encoding: "utf8" });
|
|
@@ -69673,7 +70337,7 @@ function persistPost(evt) {
|
|
|
69673
70337
|
const bridgePath = join100(postsDir, `${evt.shortcode}.md`);
|
|
69674
70338
|
writeJsonWithBridge(jsonPath, bridgePath, json, renderPostBridge(json));
|
|
69675
70339
|
const metaPath = join100(handleDir, "meta.json");
|
|
69676
|
-
if (!
|
|
70340
|
+
if (!existsSync102(metaPath)) {
|
|
69677
70341
|
writeJsonWithBridge(
|
|
69678
70342
|
metaPath,
|
|
69679
70343
|
join100(handleDir, "meta.md"),
|
|
@@ -69693,7 +70357,7 @@ First seen: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
|
69693
70357
|
return jsonPath;
|
|
69694
70358
|
}
|
|
69695
70359
|
function moveAsset(src, dest) {
|
|
69696
|
-
if (!
|
|
70360
|
+
if (!existsSync102(src)) return dest;
|
|
69697
70361
|
mkdirSync54(dirname66(dest), { recursive: true });
|
|
69698
70362
|
const fs = __require("fs");
|
|
69699
70363
|
try {
|
|
@@ -69755,7 +70419,7 @@ var init_competitors = __esm({
|
|
|
69755
70419
|
});
|
|
69756
70420
|
|
|
69757
70421
|
// src/cli/commands/marketing/competitor.ts
|
|
69758
|
-
import { existsSync as
|
|
70422
|
+
import { existsSync as existsSync103, readdirSync as readdirSync23, statSync as statSync21 } from "fs";
|
|
69759
70423
|
import { join as join101 } from "path";
|
|
69760
70424
|
function registerMarketingCompetitor(parent) {
|
|
69761
70425
|
const cmd = parent.command("competitor").description("Ingest competitor IG / YouTube content (Reinfluence pipeline).");
|
|
@@ -69806,7 +70470,7 @@ function registerMarketingCompetitor(parent) {
|
|
|
69806
70470
|
});
|
|
69807
70471
|
cmd.command("list").description("List ingested competitor handles.").action(() => {
|
|
69808
70472
|
const dir = MARKETING_PATHS.competitorsDir();
|
|
69809
|
-
if (!
|
|
70473
|
+
if (!existsSync103(dir)) {
|
|
69810
70474
|
info("No competitors ingested yet.");
|
|
69811
70475
|
return;
|
|
69812
70476
|
}
|
|
@@ -69826,7 +70490,7 @@ function registerMarketingCompetitor(parent) {
|
|
|
69826
70490
|
console.log(header("Competitors"));
|
|
69827
70491
|
for (const handle of handles) {
|
|
69828
70492
|
const postsDir = join101(dir, handle, "posts");
|
|
69829
|
-
const postCount =
|
|
70493
|
+
const postCount = existsSync103(postsDir) ? readdirSync23(postsDir).filter((f) => f.endsWith(".json")).length : 0;
|
|
69830
70494
|
console.log(` ${source_default.cyan("@" + handle)} ${source_default.dim(`${postCount} post(s)`)}`);
|
|
69831
70495
|
}
|
|
69832
70496
|
});
|
|
@@ -69839,11 +70503,11 @@ function registerMarketingCompetitor(parent) {
|
|
|
69839
70503
|
}
|
|
69840
70504
|
info(`Provider: ${provider.provider}`);
|
|
69841
70505
|
const competitorsDir = MARKETING_PATHS.competitorsDir();
|
|
69842
|
-
const handles = opts.handle ? [opts.handle] :
|
|
70506
|
+
const handles = opts.handle ? [opts.handle] : existsSync103(competitorsDir) ? readdirSync23(competitorsDir).filter((h) => !h.startsWith("_") && statSync21(join101(competitorsDir, h)).isDirectory()) : [];
|
|
69843
70507
|
const matches = [];
|
|
69844
70508
|
for (const h of handles) {
|
|
69845
70509
|
const candidate = join101(competitorsDir, h, "posts", `${shortcode}.json`);
|
|
69846
|
-
if (
|
|
70510
|
+
if (existsSync103(candidate)) matches.push(candidate);
|
|
69847
70511
|
}
|
|
69848
70512
|
if (matches.length === 0) {
|
|
69849
70513
|
error(`No post JSON found for shortcode "${shortcode}".`);
|
|
@@ -69878,7 +70542,7 @@ function registerMarketingCompetitor(parent) {
|
|
|
69878
70542
|
process.exit(1);
|
|
69879
70543
|
}
|
|
69880
70544
|
const competitorsDir = MARKETING_PATHS.competitorsDir();
|
|
69881
|
-
if (!
|
|
70545
|
+
if (!existsSync103(competitorsDir)) {
|
|
69882
70546
|
warn("No competitors directory yet \u2014 nothing to relabel.");
|
|
69883
70547
|
return;
|
|
69884
70548
|
}
|
|
@@ -69887,7 +70551,7 @@ function registerMarketingCompetitor(parent) {
|
|
|
69887
70551
|
let skipped = 0;
|
|
69888
70552
|
for (const h of handles) {
|
|
69889
70553
|
const postsDir = join101(competitorsDir, h, "posts");
|
|
69890
|
-
if (!
|
|
70554
|
+
if (!existsSync103(postsDir)) continue;
|
|
69891
70555
|
for (const f of readdirSync23(postsDir).filter((n) => n.endsWith(".json"))) {
|
|
69892
70556
|
const path2 = join101(postsDir, f);
|
|
69893
70557
|
if (opts.dryRun) {
|
|
@@ -69936,7 +70600,7 @@ var init_competitor = __esm({
|
|
|
69936
70600
|
});
|
|
69937
70601
|
|
|
69938
70602
|
// src/lib/marketing/meta-fetch.ts
|
|
69939
|
-
import { existsSync as
|
|
70603
|
+
import { existsSync as existsSync104, mkdirSync as mkdirSync55, readFileSync as readFileSync73, writeFileSync as writeFileSync60, statSync as statSync22, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
|
|
69940
70604
|
import { dirname as dirname67, basename as basename31 } from "path";
|
|
69941
70605
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
69942
70606
|
function getQueue(accountId) {
|
|
@@ -69987,7 +70651,7 @@ function idemCachePath(key2) {
|
|
|
69987
70651
|
}
|
|
69988
70652
|
function readIdem(key2) {
|
|
69989
70653
|
const p = idemCachePath(key2);
|
|
69990
|
-
if (!
|
|
70654
|
+
if (!existsSync104(p)) return null;
|
|
69991
70655
|
try {
|
|
69992
70656
|
return JSON.parse(readFileSync73(p, "utf8"));
|
|
69993
70657
|
} catch {
|
|
@@ -70733,7 +71397,7 @@ var init_account = __esm({
|
|
|
70733
71397
|
});
|
|
70734
71398
|
|
|
70735
71399
|
// src/lib/marketing/hypothesis.ts
|
|
70736
|
-
import { existsSync as
|
|
71400
|
+
import { existsSync as existsSync105, readFileSync as readFileSync74 } from "fs";
|
|
70737
71401
|
function validateHypothesis(raw, options2 = {}) {
|
|
70738
71402
|
const errors = [];
|
|
70739
71403
|
const fieldErrors = {};
|
|
@@ -70800,7 +71464,7 @@ function validateHypothesis(raw, options2 = {}) {
|
|
|
70800
71464
|
};
|
|
70801
71465
|
}
|
|
70802
71466
|
function loadHypothesisFile(path2, options2 = {}) {
|
|
70803
|
-
if (!
|
|
71467
|
+
if (!existsSync105(path2)) {
|
|
70804
71468
|
return { ok: false, errors: [`Hypothesis file not found: ${path2}`] };
|
|
70805
71469
|
}
|
|
70806
71470
|
let parsed;
|
|
@@ -70993,7 +71657,7 @@ var init_cohort2 = __esm({
|
|
|
70993
71657
|
});
|
|
70994
71658
|
|
|
70995
71659
|
// src/lib/marketing/insights-cache.ts
|
|
70996
|
-
import { existsSync as
|
|
71660
|
+
import { existsSync as existsSync106, readFileSync as readFileSync75, mkdirSync as mkdirSync56, writeFileSync as writeFileSync61, readdirSync as readdirSync24, statSync as statSync23 } from "fs";
|
|
70997
71661
|
import { join as join102 } from "path";
|
|
70998
71662
|
import { randomBytes as randomBytes4 } from "crypto";
|
|
70999
71663
|
function snapshotFilename(entityId, pulledAt) {
|
|
@@ -71009,7 +71673,7 @@ function indexPath() {
|
|
|
71009
71673
|
}
|
|
71010
71674
|
function readIndex() {
|
|
71011
71675
|
const p = indexPath();
|
|
71012
|
-
if (!
|
|
71676
|
+
if (!existsSync106(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
|
|
71013
71677
|
try {
|
|
71014
71678
|
return JSON.parse(readFileSync75(p, "utf8"));
|
|
71015
71679
|
} catch {
|
|
@@ -71041,7 +71705,7 @@ function getCachedInsights(entityId) {
|
|
|
71041
71705
|
const filename = idx.latest[entityId];
|
|
71042
71706
|
if (!filename) return null;
|
|
71043
71707
|
const fullPath = join102(MARKETING_PATHS.insightsDir(), filename);
|
|
71044
|
-
if (!
|
|
71708
|
+
if (!existsSync106(fullPath)) return null;
|
|
71045
71709
|
try {
|
|
71046
71710
|
const snap = JSON.parse(readFileSync75(fullPath, "utf8"));
|
|
71047
71711
|
const ageMs = Date.now() - new Date(snap.pulled_at).getTime();
|
|
@@ -71056,7 +71720,7 @@ function getLatestSnapshot(entityId) {
|
|
|
71056
71720
|
const filename = idx.latest[entityId];
|
|
71057
71721
|
if (!filename) return null;
|
|
71058
71722
|
const fullPath = join102(MARKETING_PATHS.insightsDir(), filename);
|
|
71059
|
-
if (!
|
|
71723
|
+
if (!existsSync106(fullPath)) return null;
|
|
71060
71724
|
try {
|
|
71061
71725
|
return JSON.parse(readFileSync75(fullPath, "utf8"));
|
|
71062
71726
|
} catch {
|
|
@@ -71065,7 +71729,7 @@ function getLatestSnapshot(entityId) {
|
|
|
71065
71729
|
}
|
|
71066
71730
|
function getPriorSnapshot(entityId, beforeMs) {
|
|
71067
71731
|
const dir = MARKETING_PATHS.insightsDir();
|
|
71068
|
-
if (!
|
|
71732
|
+
if (!existsSync106(dir)) return null;
|
|
71069
71733
|
const safe = entityId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
71070
71734
|
const candidates = readdirSync24(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
|
|
71071
71735
|
const p = join102(dir, f);
|
|
@@ -71859,7 +72523,7 @@ var init_doctor2 = __esm({
|
|
|
71859
72523
|
});
|
|
71860
72524
|
|
|
71861
72525
|
// src/lib/marketing/entity-store.ts
|
|
71862
|
-
import { existsSync as
|
|
72526
|
+
import { existsSync as existsSync108, readFileSync as readFileSync77, readdirSync as readdirSync26 } from "fs";
|
|
71863
72527
|
import { join as join104 } from "path";
|
|
71864
72528
|
function dirFor(kind) {
|
|
71865
72529
|
switch (kind) {
|
|
@@ -71883,7 +72547,7 @@ function entityPaths(kind, id) {
|
|
|
71883
72547
|
}
|
|
71884
72548
|
function loadEntity(kind, id) {
|
|
71885
72549
|
const { json } = entityPaths(kind, id);
|
|
71886
|
-
if (!
|
|
72550
|
+
if (!existsSync108(json)) return null;
|
|
71887
72551
|
try {
|
|
71888
72552
|
return JSON.parse(readFileSync77(json, "utf8"));
|
|
71889
72553
|
} catch {
|
|
@@ -71892,7 +72556,7 @@ function loadEntity(kind, id) {
|
|
|
71892
72556
|
}
|
|
71893
72557
|
function listEntities(kind) {
|
|
71894
72558
|
const d = dirFor(kind);
|
|
71895
|
-
if (!
|
|
72559
|
+
if (!existsSync108(d)) return [];
|
|
71896
72560
|
const out = [];
|
|
71897
72561
|
for (const f of readdirSync26(d).filter((x) => x.endsWith(".json"))) {
|
|
71898
72562
|
try {
|
|
@@ -72090,7 +72754,7 @@ var init_campaign = __esm({
|
|
|
72090
72754
|
});
|
|
72091
72755
|
|
|
72092
72756
|
// src/cli/commands/marketing/adset.ts
|
|
72093
|
-
import { existsSync as
|
|
72757
|
+
import { existsSync as existsSync109, readFileSync as readFileSync78 } from "fs";
|
|
72094
72758
|
function registerMarketingAdSet(parent) {
|
|
72095
72759
|
const cmd = parent.command("adset").description("Manage adsets.");
|
|
72096
72760
|
cmd.command("create").description("Create an adset (PAUSED). --daily-budget required (no fallback).").requiredOption("--campaign <id>", "parent campaign local id").requiredOption("--name <name>", "adset name").requiredOption("--daily-budget <amount>", "daily budget (major-currency units)").requiredOption("--targeting <file>", "JSON file with Meta targeting spec").option("--currency <code>", "currency code", "TRY").option("--optimization-goal <goal>", "OFFSITE_CONVERSIONS|LINK_CLICKS|...", "OFFSITE_CONVERSIONS").option("--billing-event <event>", "IMPRESSIONS|LINK_CLICKS|THRUPLAY", "IMPRESSIONS").option("--custom-event-type <evt>", "e.g. PURCHASE, COMPLETE_REGISTRATION (for OFFSITE_CONVERSIONS)").option("--no-dry-run", "Actually create on Meta").action(async (opts) => {
|
|
@@ -72110,7 +72774,7 @@ function registerMarketingAdSet(parent) {
|
|
|
72110
72774
|
}
|
|
72111
72775
|
throw e;
|
|
72112
72776
|
}
|
|
72113
|
-
if (!
|
|
72777
|
+
if (!existsSync109(opts.targeting)) {
|
|
72114
72778
|
error(`Targeting file not found: ${opts.targeting}`);
|
|
72115
72779
|
process.exit(1);
|
|
72116
72780
|
}
|
|
@@ -72373,12 +73037,12 @@ var init_creative = __esm({
|
|
|
72373
73037
|
});
|
|
72374
73038
|
|
|
72375
73039
|
// src/cli/commands/marketing/asset.ts
|
|
72376
|
-
import { existsSync as
|
|
73040
|
+
import { existsSync as existsSync110, statSync as statSync25 } from "fs";
|
|
72377
73041
|
import { extname as extname7 } from "path";
|
|
72378
73042
|
function registerMarketingAsset(parent) {
|
|
72379
73043
|
const cmd = parent.command("asset").description("Upload creative assets to Meta.");
|
|
72380
73044
|
cmd.command("upload <path>").description("Upload a video (>50MB \u2192 chunked) or image to Meta. Returns id/hash.").option("--type <type>", "override auto-detection (video|image)").option("--name <name>", "asset name (videos)").option("--no-dry-run", "Actually upload to Meta").action(async (path2, opts) => {
|
|
72381
|
-
if (!
|
|
73045
|
+
if (!existsSync110(path2)) {
|
|
72382
73046
|
error(`File not found: ${path2}`);
|
|
72383
73047
|
process.exit(1);
|
|
72384
73048
|
}
|
|
@@ -72546,7 +73210,7 @@ var init_ad = __esm({
|
|
|
72546
73210
|
});
|
|
72547
73211
|
|
|
72548
73212
|
// src/lib/marketing/launch.ts
|
|
72549
|
-
import { existsSync as
|
|
73213
|
+
import { existsSync as existsSync111, readFileSync as readFileSync79, writeFileSync as writeFileSync62, mkdirSync as mkdirSync57, renameSync as renameSync18, readdirSync as readdirSync27 } from "fs";
|
|
72550
73214
|
import { dirname as dirname68, join as join105, basename as basename32 } from "path";
|
|
72551
73215
|
import { randomBytes as randomBytes5 } from "crypto";
|
|
72552
73216
|
function buildLaunchSummary(cohortId) {
|
|
@@ -72597,7 +73261,7 @@ function atomicWriteFile3(path2, data) {
|
|
|
72597
73261
|
renameSync18(tmp, path2);
|
|
72598
73262
|
}
|
|
72599
73263
|
function readWal(path2) {
|
|
72600
|
-
if (!
|
|
73264
|
+
if (!existsSync111(path2)) return null;
|
|
72601
73265
|
try {
|
|
72602
73266
|
return JSON.parse(readFileSync79(path2, "utf8"));
|
|
72603
73267
|
} catch {
|
|
@@ -72609,7 +73273,7 @@ function writeWal(path2, wal) {
|
|
|
72609
73273
|
}
|
|
72610
73274
|
function findWalByRunId(runId) {
|
|
72611
73275
|
const dir = MARKETING_PATHS.runsDir();
|
|
72612
|
-
if (!
|
|
73276
|
+
if (!existsSync111(dir)) return null;
|
|
72613
73277
|
for (const f of readdirSync27(dir)) {
|
|
72614
73278
|
if (!f.endsWith(".json")) continue;
|
|
72615
73279
|
if (f.startsWith("by-idem")) continue;
|
|
@@ -72886,7 +73550,7 @@ var init_launch2 = __esm({
|
|
|
72886
73550
|
});
|
|
72887
73551
|
|
|
72888
73552
|
// src/cli/commands/marketing/learnings.ts
|
|
72889
|
-
import { existsSync as
|
|
73553
|
+
import { existsSync as existsSync112, readFileSync as readFileSync80 } from "fs";
|
|
72890
73554
|
function registerMarketingLearnings(parent) {
|
|
72891
73555
|
const cmd = parent.command("learnings").description("Performance Monitor learnings ledger (per-day .md + index).");
|
|
72892
73556
|
cmd.command("show").description("Show today's (or specified day's) learnings file.").option("--date <YYYY-MM-DD>", "Day to show (default: today UTC)").option("--id <id>", "Show a single entry by id").action((opts) => {
|
|
@@ -73029,7 +73693,7 @@ async function resolveBody(body, bodyFile) {
|
|
|
73029
73693
|
if (body) return body;
|
|
73030
73694
|
if (bodyFile === "-") return readStdin3();
|
|
73031
73695
|
if (bodyFile) {
|
|
73032
|
-
if (!
|
|
73696
|
+
if (!existsSync112(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
|
|
73033
73697
|
return readFileSync80(bodyFile, "utf8");
|
|
73034
73698
|
}
|
|
73035
73699
|
return null;
|
|
@@ -73060,7 +73724,7 @@ var init_learnings2 = __esm({
|
|
|
73060
73724
|
|
|
73061
73725
|
// src/lib/marketing/rem-sleep.ts
|
|
73062
73726
|
import {
|
|
73063
|
-
existsSync as
|
|
73727
|
+
existsSync as existsSync113,
|
|
73064
73728
|
mkdirSync as mkdirSync58,
|
|
73065
73729
|
readFileSync as readFileSync81,
|
|
73066
73730
|
writeFileSync as writeFileSync63,
|
|
@@ -73080,7 +73744,7 @@ function atomicWriteFile4(path2, data) {
|
|
|
73080
73744
|
function pruneRuns2(opts = {}) {
|
|
73081
73745
|
const keepLast = opts.keepLast ?? 100;
|
|
73082
73746
|
const dir = MARKETING_PATHS.runsDir();
|
|
73083
|
-
if (!
|
|
73747
|
+
if (!existsSync113(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
|
|
73084
73748
|
const files = readdirSync28(dir).filter((f) => f.endsWith(".json")).map((f) => {
|
|
73085
73749
|
const p = join106(dir, f);
|
|
73086
73750
|
try {
|
|
@@ -73116,7 +73780,7 @@ function compactInsights(opts = {}) {
|
|
|
73116
73780
|
const weeklyAfterDays = opts.weeklyAfterDays ?? 14;
|
|
73117
73781
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
73118
73782
|
const dir = MARKETING_PATHS.insightsDir();
|
|
73119
|
-
if (!
|
|
73783
|
+
if (!existsSync113(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
|
|
73120
73784
|
const files = [];
|
|
73121
73785
|
for (const f of readdirSync28(dir)) {
|
|
73122
73786
|
if (!f.endsWith(".json") || f.startsWith("_")) continue;
|
|
@@ -73188,7 +73852,7 @@ function mergeDailyLearnings(opts = {}) {
|
|
|
73188
73852
|
const retainDays = opts.retainDays ?? 7;
|
|
73189
73853
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
73190
73854
|
const dir = MARKETING_PATHS.learningsDir();
|
|
73191
|
-
if (!
|
|
73855
|
+
if (!existsSync113(dir)) {
|
|
73192
73856
|
return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
|
|
73193
73857
|
}
|
|
73194
73858
|
const dayMs = 24 * 60 * 60 * 1e3;
|
|
@@ -73216,7 +73880,7 @@ function mergeDailyLearnings(opts = {}) {
|
|
|
73216
73880
|
const archivePath = join106(dir, `_archive-${q}.md`);
|
|
73217
73881
|
list.sort((a, b) => a.date.localeCompare(b.date));
|
|
73218
73882
|
for (const c of list) {
|
|
73219
|
-
const existingArchive =
|
|
73883
|
+
const existingArchive = existsSync113(archivePath) ? readFileSync81(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
|
|
73220
73884
|
`;
|
|
73221
73885
|
const dateMarker = `# Marketing learnings \u2014 ${c.date}`;
|
|
73222
73886
|
const alreadyMerged = existingArchive.includes(dateMarker);
|
|
@@ -73268,7 +73932,7 @@ function quarterKey(yyyymmdd) {
|
|
|
73268
73932
|
}
|
|
73269
73933
|
function redactRunsSweep(opts = {}) {
|
|
73270
73934
|
const dir = MARKETING_PATHS.runsDir();
|
|
73271
|
-
if (!
|
|
73935
|
+
if (!existsSync113(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
|
|
73272
73936
|
const files = readdirSync28(dir).filter((f) => f.endsWith(".json"));
|
|
73273
73937
|
const rewrittenFiles = [];
|
|
73274
73938
|
for (const f of files) {
|
|
@@ -73297,7 +73961,7 @@ function redactRunsSweep(opts = {}) {
|
|
|
73297
73961
|
function runRemSleep(opts = {}) {
|
|
73298
73962
|
const ranAt = (opts.now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
73299
73963
|
const root = marketingRootIfExists();
|
|
73300
|
-
if (!root || !
|
|
73964
|
+
if (!root || !existsSync113(root)) {
|
|
73301
73965
|
return {
|
|
73302
73966
|
ranAt,
|
|
73303
73967
|
marketingPresent: false,
|
|
@@ -73378,7 +74042,7 @@ var init_rem_sleep2 = __esm({
|
|
|
73378
74042
|
});
|
|
73379
74043
|
|
|
73380
74044
|
// src/cli/commands/marketing/hooks.ts
|
|
73381
|
-
import { existsSync as
|
|
74045
|
+
import { existsSync as existsSync114, readFileSync as readFileSync82, writeFileSync as writeFileSync64, chmodSync as chmodSync7, mkdirSync as mkdirSync59, statSync as statSync27 } from "fs";
|
|
73382
74046
|
import { execFileSync as execFileSync10 } from "child_process";
|
|
73383
74047
|
import { join as join107 } from "path";
|
|
73384
74048
|
function findGitDir(cwd = process.cwd()) {
|
|
@@ -73423,7 +74087,7 @@ function registerMarketingHooks(parent) {
|
|
|
73423
74087
|
const hooksDir = join107(gitDir, "hooks");
|
|
73424
74088
|
mkdirSync59(hooksDir, { recursive: true });
|
|
73425
74089
|
const target = join107(hooksDir, "pre-commit");
|
|
73426
|
-
if (
|
|
74090
|
+
if (existsSync114(target)) {
|
|
73427
74091
|
const existing = readFileSync82(target, "utf-8");
|
|
73428
74092
|
if (existing.includes(MANAGED_MARKER)) {
|
|
73429
74093
|
info("pre-commit hook already managed by dreamcontext \u2014 refreshing.");
|
|
@@ -73475,7 +74139,7 @@ exec dreamcontext mk hooks check-staged
|
|
|
73475
74139
|
});
|
|
73476
74140
|
|
|
73477
74141
|
// src/lib/marketing/council-personas.ts
|
|
73478
|
-
import { existsSync as
|
|
74142
|
+
import { existsSync as existsSync115, readFileSync as readFileSync83, readdirSync as readdirSync29 } from "fs";
|
|
73479
74143
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
73480
74144
|
import { join as join108, dirname as dirname70 } from "path";
|
|
73481
74145
|
function findPersonasDir() {
|
|
@@ -73489,7 +74153,7 @@ function findPersonasDir() {
|
|
|
73489
74153
|
join108(__dirname_local, "..", "..", PERSONA_SUBPATH)
|
|
73490
74154
|
];
|
|
73491
74155
|
for (const candidate of candidates) {
|
|
73492
|
-
if (
|
|
74156
|
+
if (existsSync115(candidate)) return candidate;
|
|
73493
74157
|
}
|
|
73494
74158
|
return null;
|
|
73495
74159
|
}
|
|
@@ -73514,7 +74178,7 @@ function parsePersonaFile(filePath) {
|
|
|
73514
74178
|
}
|
|
73515
74179
|
function loadAllPersonas(personasDir) {
|
|
73516
74180
|
const dir = personasDir ?? findPersonasDir();
|
|
73517
|
-
if (!dir || !
|
|
74181
|
+
if (!dir || !existsSync115(dir)) return [];
|
|
73518
74182
|
const files = readdirSync29(dir).filter((n) => n.endsWith(".md")).sort();
|
|
73519
74183
|
return files.map((name) => parsePersonaFile(join108(dir, name)));
|
|
73520
74184
|
}
|
|
@@ -73547,11 +74211,11 @@ var init_council_personas = __esm({
|
|
|
73547
74211
|
|
|
73548
74212
|
// src/cli/commands/marketing/council.ts
|
|
73549
74213
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
73550
|
-
import { existsSync as
|
|
74214
|
+
import { existsSync as existsSync116 } from "fs";
|
|
73551
74215
|
function resolveDreamcontextEntry() {
|
|
73552
74216
|
const node = process.argv[0];
|
|
73553
74217
|
const script = process.argv[1];
|
|
73554
|
-
if (script &&
|
|
74218
|
+
if (script && existsSync116(script)) {
|
|
73555
74219
|
return { node, script };
|
|
73556
74220
|
}
|
|
73557
74221
|
return { node, script: null };
|
|
@@ -73723,7 +74387,7 @@ var init_marketing = __esm({
|
|
|
73723
74387
|
});
|
|
73724
74388
|
|
|
73725
74389
|
// src/cli/commands/memory.ts
|
|
73726
|
-
import { existsSync as
|
|
74390
|
+
import { existsSync as existsSync117, unlinkSync as unlinkSync12 } from "fs";
|
|
73727
74391
|
import { join as join109, dirname as dirname71 } from "path";
|
|
73728
74392
|
function collectVault(value, previous) {
|
|
73729
74393
|
return [...previous, value];
|
|
@@ -73834,7 +74498,12 @@ function registerMemoryCommand(program2) {
|
|
|
73834
74498
|
}
|
|
73835
74499
|
const corpus = buildCorpus(root, types ? { types } : {});
|
|
73836
74500
|
const vocab = loadProjectVocabulary(root);
|
|
73837
|
-
const
|
|
74501
|
+
const mode = resolveRecallMode(root);
|
|
74502
|
+
const useHybrid = hybridReady(root, mode);
|
|
74503
|
+
if (mode === "hybrid" && !useHybrid) {
|
|
74504
|
+
console.error(source_default.dim(" (hybrid recall selected but not warmed \u2014 using BM25. Run `dreamcontext embed refresh` to enable it.)"));
|
|
74505
|
+
}
|
|
74506
|
+
const hits = useHybrid ? await hybridSearch(query, corpus, root, topK, { aliasGroups: aliasGroups(vocab) }) : bm25Search(query, corpus, topK, { aliasGroups: aliasGroups(vocab) });
|
|
73838
74507
|
if (opts.json) {
|
|
73839
74508
|
const payload = hits.map((h) => ({
|
|
73840
74509
|
type: h.doc.type,
|
|
@@ -73915,7 +74584,7 @@ function registerMemoryCommand(program2) {
|
|
|
73915
74584
|
async (slug, opts) => {
|
|
73916
74585
|
const root = ensureContextRoot();
|
|
73917
74586
|
const filePath = join109(root, "knowledge", `${slug}.md`);
|
|
73918
|
-
if (!
|
|
74587
|
+
if (!existsSync117(filePath)) {
|
|
73919
74588
|
error(`Knowledge file not found: ${slug}.md`);
|
|
73920
74589
|
return;
|
|
73921
74590
|
}
|
|
@@ -73963,7 +74632,7 @@ ${opts.append}
|
|
|
73963
74632
|
memory.command("delete").argument("<slug>", "Knowledge file slug to delete (without .md)").option("-f, --force", "Skip confirmation prompt").description("Delete a knowledge file (irreversible; use git to recover)").action(async (slug, opts) => {
|
|
73964
74633
|
const root = ensureContextRoot();
|
|
73965
74634
|
const filePath = join109(root, "knowledge", `${slug}.md`);
|
|
73966
|
-
if (!
|
|
74635
|
+
if (!existsSync117(filePath)) {
|
|
73967
74636
|
error(`Knowledge file not found: ${slug}.md`);
|
|
73968
74637
|
return;
|
|
73969
74638
|
}
|
|
@@ -74060,6 +74729,7 @@ var init_memory = __esm({
|
|
|
74060
74729
|
init_format();
|
|
74061
74730
|
init_recall();
|
|
74062
74731
|
init_hybrid();
|
|
74732
|
+
init_sleep();
|
|
74063
74733
|
init_federation_recall();
|
|
74064
74734
|
init_taxonomy();
|
|
74065
74735
|
init_frontmatter();
|
|
@@ -74079,7 +74749,7 @@ var init_memory = __esm({
|
|
|
74079
74749
|
});
|
|
74080
74750
|
|
|
74081
74751
|
// src/cli/commands/embed.ts
|
|
74082
|
-
import { existsSync as
|
|
74752
|
+
import { existsSync as existsSync118, statSync as statSync28, readFileSync as readFileSync85 } from "fs";
|
|
74083
74753
|
import { join as join110 } from "path";
|
|
74084
74754
|
function registerEmbedCommand(program2) {
|
|
74085
74755
|
const embed = program2.command("embed").description("EXPERIMENTAL: manage the local embedding index used by hybrid recall");
|
|
@@ -74111,7 +74781,7 @@ function registerEmbedCommand(program2) {
|
|
|
74111
74781
|
const root = ensureContextRoot();
|
|
74112
74782
|
console.log(header("Embedding Index"));
|
|
74113
74783
|
const path2 = join110(root, ".embeddings", "cache.json");
|
|
74114
|
-
if (!
|
|
74784
|
+
if (!existsSync118(path2)) {
|
|
74115
74785
|
info("No embedding cache \u2014 hybrid recall has not been used in this vault.");
|
|
74116
74786
|
info(`Enable: ${source_default.cyan("dreamcontext recall hybrid")} (or DREAMCONTEXT_RECALL_MODE=hybrid), then run ${source_default.cyan("dreamcontext embed refresh")} to prewarm.`);
|
|
74117
74787
|
return;
|
|
@@ -74144,12 +74814,12 @@ var init_embed = __esm({
|
|
|
74144
74814
|
// src/cli/commands/upgrade.ts
|
|
74145
74815
|
import { execFileSync as execFileSync12 } from "child_process";
|
|
74146
74816
|
import { dirname as dirname72 } from "path";
|
|
74147
|
-
import { existsSync as
|
|
74817
|
+
import { existsSync as existsSync119 } from "fs";
|
|
74148
74818
|
function defaultInstaller(args) {
|
|
74149
74819
|
execFileSync12("npm", args, { stdio: "inherit" });
|
|
74150
74820
|
}
|
|
74151
74821
|
function defaultProjectUpdater(vault) {
|
|
74152
|
-
if (!
|
|
74822
|
+
if (!existsSync119(vault.path)) {
|
|
74153
74823
|
return { vault, ok: false, error: "project folder no longer exists" };
|
|
74154
74824
|
}
|
|
74155
74825
|
try {
|
|
@@ -74944,7 +75614,7 @@ var init_people = __esm({
|
|
|
74944
75614
|
|
|
74945
75615
|
// src/cli/commands/config.ts
|
|
74946
75616
|
import { dirname as dirname74 } from "path";
|
|
74947
|
-
import { existsSync as
|
|
75617
|
+
import { existsSync as existsSync120, readFileSync as readFileSync86, writeFileSync as writeFileSync66 } from "fs";
|
|
74948
75618
|
import { join as join112 } from "path";
|
|
74949
75619
|
function resolveProjectRoot() {
|
|
74950
75620
|
const contextRoot = resolveContextRoot();
|
|
@@ -75300,7 +75970,7 @@ function registerConfigCommand(program2) {
|
|
|
75300
75970
|
let userMdSynced = false;
|
|
75301
75971
|
if (contextRoot) {
|
|
75302
75972
|
const userMdPath = join112(contextRoot, "core", "1.user.md");
|
|
75303
|
-
if (
|
|
75973
|
+
if (existsSync120(userMdPath)) {
|
|
75304
75974
|
try {
|
|
75305
75975
|
const before = readFileSync86(userMdPath, "utf-8");
|
|
75306
75976
|
const after = ensurePeopleSection(before, roster);
|