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