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