dreamcontext 0.8.2 → 0.8.3
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 +97 -3
- package/agents/sleep-product.md +22 -0
- package/agents/sleep-state.md +3 -1
- package/agents/sleep-tasks.md +3 -1
- package/dist/agents/sleep-product.md +22 -0
- package/dist/agents/sleep-state.md +3 -1
- package/dist/agents/sleep-tasks.md +3 -1
- package/dist/dashboard/assets/{BrainCanvas3D-CNDjMlun.js → BrainCanvas3D-CoTzHqzT.js} +1 -1
- package/dist/dashboard/assets/{_baseUniq-DtoPVYjz.js → _baseUniq-BlQ6XWxs.js} +1 -1
- package/dist/dashboard/assets/{ar-SA-G6X2FPQ2-D_dXe_8i.js → ar-SA-G6X2FPQ2-C4qyHe9L.js} +1 -1
- package/dist/dashboard/assets/{arc-8LFYH4lG.js → arc-uGukQNxI.js} +1 -1
- package/dist/dashboard/assets/{architectureDiagram-Q4EWVU46-BIgEpM4v.js → architectureDiagram-Q4EWVU46-BhtWTFvf.js} +1 -1
- package/dist/dashboard/assets/{az-AZ-76LH7QW2-C30ZBwgT.js → az-AZ-76LH7QW2-HfK2pIVQ.js} +1 -1
- package/dist/dashboard/assets/{bg-BG-XCXSNQG7-D0R9pSdG.js → bg-BG-XCXSNQG7-L7TlhXli.js} +1 -1
- package/dist/dashboard/assets/{blockDiagram-DXYQGD6D-DRTa0DpJ.js → blockDiagram-DXYQGD6D-BmPhQEp6.js} +1 -1
- package/dist/dashboard/assets/{bn-BD-2XOGV67Q-vkWxteG3.js → bn-BD-2XOGV67Q-DE0uNoU6.js} +1 -1
- package/dist/dashboard/assets/{c4Diagram-AHTNJAMY-Do_gB8Cs.js → c4Diagram-AHTNJAMY-DtQKYrmP.js} +1 -1
- package/dist/dashboard/assets/{ca-ES-6MX7JW3Y-CTyxGdzW.js → ca-ES-6MX7JW3Y-7JHCTA6b.js} +1 -1
- package/dist/dashboard/assets/channel-3OfE-PZ3.js +1 -0
- package/dist/dashboard/assets/{chunk-4BX2VUAB-DJlttKoY.js → chunk-4BX2VUAB-BvnLY9qE.js} +1 -1
- package/dist/dashboard/assets/{chunk-4TB4RGXK-BdixZX4J.js → chunk-4TB4RGXK--piiFXgS.js} +1 -1
- package/dist/dashboard/assets/{chunk-55IACEB6-CPhKaTLr.js → chunk-55IACEB6-C7uvmawY.js} +1 -1
- package/dist/dashboard/assets/{chunk-EDXVE4YY-Bv0bQVvi.js → chunk-EDXVE4YY-BuWBKOPY.js} +1 -1
- package/dist/dashboard/assets/{chunk-FMBD7UC4-DGjRdLDd.js → chunk-FMBD7UC4-C1Le6hxh.js} +1 -1
- package/dist/dashboard/assets/{chunk-OYMX7WX6-B-wzkRri.js → chunk-OYMX7WX6-B8JE8Wz4.js} +1 -1
- package/dist/dashboard/assets/{chunk-QZHKN3VN-BwK1NqpV.js → chunk-QZHKN3VN-U9FJi59p.js} +1 -1
- package/dist/dashboard/assets/{chunk-YZCP3GAM-DjEwJGlh.js → chunk-YZCP3GAM-BNc94uy1.js} +1 -1
- package/dist/dashboard/assets/classDiagram-6PBFFD2Q-Dpt9qwZI.js +1 -0
- package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-Dpt9qwZI.js +1 -0
- package/dist/dashboard/assets/clone-CZ-InUnR.js +1 -0
- package/dist/dashboard/assets/{cose-bilkent-S5V4N54A-BJXUn11L.js → cose-bilkent-S5V4N54A-D0hUzBCj.js} +1 -1
- package/dist/dashboard/assets/{cs-CZ-2BRQDIVT-BjRikaNe.js → cs-CZ-2BRQDIVT-B0rWHDIi.js} +1 -1
- package/dist/dashboard/assets/{da-DK-5WZEPLOC-Cn3GTxbV.js → da-DK-5WZEPLOC-D_PQO_T0.js} +1 -1
- package/dist/dashboard/assets/{dagre-KV5264BT-BHn2c24z.js → dagre-KV5264BT-B_bjkEDQ.js} +1 -1
- package/dist/dashboard/assets/{de-DE-XR44H4JA-IvGsdpTt.js → de-DE-XR44H4JA-D1G4J6Mz.js} +1 -1
- package/dist/dashboard/assets/{diagram-5BDNPKRD-YrlF3B5a.js → diagram-5BDNPKRD-B63uEoiS.js} +1 -1
- package/dist/dashboard/assets/{diagram-G4DWMVQ6-DHONF1OD.js → diagram-G4DWMVQ6-DShdwm3D.js} +1 -1
- package/dist/dashboard/assets/{diagram-MMDJMWI5-B1vJLt5b.js → diagram-MMDJMWI5-DdVsHQ-l.js} +1 -1
- package/dist/dashboard/assets/{diagram-TYMM5635-C8P5-4A3.js → diagram-TYMM5635-BdHifyqU.js} +1 -1
- package/dist/dashboard/assets/{el-GR-BZB4AONW-B9GA8_lO.js → el-GR-BZB4AONW-a0CO4RfB.js} +1 -1
- package/dist/dashboard/assets/{erDiagram-SMLLAGMA-CjWWTCWe.js → erDiagram-SMLLAGMA-CYxdxNcb.js} +1 -1
- package/dist/dashboard/assets/{es-ES-U4NZUMDT-Ct1wP_9r.js → es-ES-U4NZUMDT-ejRYVYRf.js} +1 -1
- package/dist/dashboard/assets/{eu-ES-A7QVB2H4-C-49gWlR.js → eu-ES-A7QVB2H4-B-4OXJLd.js} +1 -1
- package/dist/dashboard/assets/{fa-IR-HGAKTJCU-DUo8t-xv.js → fa-IR-HGAKTJCU-DhOcLy7v.js} +1 -1
- package/dist/dashboard/assets/{fi-FI-Z5N7JZ37-DCObnr3i.js → fi-FI-Z5N7JZ37-CKQF9xKf.js} +1 -1
- package/dist/dashboard/assets/{flowDiagram-DWJPFMVM-OQ_IRMqG.js → flowDiagram-DWJPFMVM-azQUtREP.js} +1 -1
- package/dist/dashboard/assets/{fr-FR-RHASNOE6-0EGg3zhN.js → fr-FR-RHASNOE6-CsGekBXq.js} +1 -1
- package/dist/dashboard/assets/{ganttDiagram-T4ZO3ILL-DPTSBcnu.js → ganttDiagram-T4ZO3ILL-DjXmGcb4.js} +2 -2
- package/dist/dashboard/assets/{gitGraphDiagram-UUTBAWPF-BxfeiCqm.js → gitGraphDiagram-UUTBAWPF-Dz87wo6e.js} +1 -1
- package/dist/dashboard/assets/{gl-ES-HMX3MZ6V-WtVwXY6x.js → gl-ES-HMX3MZ6V-NRfsjlmW.js} +1 -1
- package/dist/dashboard/assets/{graph-Du_3_o8q.js → graph-BMW3t-Jz.js} +1 -1
- package/dist/dashboard/assets/{he-IL-6SHJWFNN-CfgspIku.js → he-IL-6SHJWFNN-CK4gfEss.js} +1 -1
- package/dist/dashboard/assets/{hi-IN-IWLTKZ5I-CS9l2g3B.js → hi-IN-IWLTKZ5I-CqyBl1jA.js} +1 -1
- package/dist/dashboard/assets/{hu-HU-A5ZG7DT2-BQ46AerM.js → hu-HU-A5ZG7DT2-BO0SthvO.js} +1 -1
- package/dist/dashboard/assets/{id-ID-SAP4L64H-BeShJyKQ.js → id-ID-SAP4L64H-CrHxJe1s.js} +1 -1
- package/dist/dashboard/assets/{index-D7dWmypK.js → index-B0pCDfL8.js} +1 -1
- package/dist/dashboard/assets/index-rIZLhbl7.js +480 -0
- package/dist/dashboard/assets/index-sax--nf3.css +1 -0
- package/dist/dashboard/assets/{infoDiagram-42DDH7IO-CcFhyaQp.js → infoDiagram-42DDH7IO-zG-8q9HR.js} +1 -1
- package/dist/dashboard/assets/{ishikawaDiagram-UXIWVN3A-9QJeD00p.js → ishikawaDiagram-UXIWVN3A-5OzPmL1c.js} +1 -1
- package/dist/dashboard/assets/{it-IT-JPQ66NNP-csyvfk0t.js → it-IT-JPQ66NNP-CW6fpZrT.js} +1 -1
- package/dist/dashboard/assets/{ja-JP-DBVTYXUO-DctpJ2yz.js → ja-JP-DBVTYXUO-DMJRiMhd.js} +1 -1
- package/dist/dashboard/assets/{journeyDiagram-VCZTEJTY-CU4EYedt.js → journeyDiagram-VCZTEJTY-f8lbDQ22.js} +1 -1
- package/dist/dashboard/assets/{kaa-6HZHGXH3-D0tWzHt3.js → kaa-6HZHGXH3-C4yr2X6j.js} +1 -1
- package/dist/dashboard/assets/{kab-KAB-ZGHBKWFO-BC-g4xJU.js → kab-KAB-ZGHBKWFO-BtwhZ5Ak.js} +1 -1
- package/dist/dashboard/assets/{kanban-definition-6JOO6SKY-BxXqVmz1.js → kanban-definition-6JOO6SKY-BJtF1llZ.js} +1 -1
- package/dist/dashboard/assets/{kk-KZ-P5N5QNE5-TLB3Lxri.js → kk-KZ-P5N5QNE5-BiS5ISFw.js} +1 -1
- package/dist/dashboard/assets/{km-KH-HSX4SM5Z-DCh7cRAS.js → km-KH-HSX4SM5Z-CJcAjj0D.js} +1 -1
- package/dist/dashboard/assets/{ko-KR-MTYHY66A-BPIl5ido.js → ko-KR-MTYHY66A-yw6XRj7m.js} +1 -1
- package/dist/dashboard/assets/{ku-TR-6OUDTVRD-TUpeN1Tm.js → ku-TR-6OUDTVRD-nAwdHGyN.js} +1 -1
- package/dist/dashboard/assets/{layout-CyrgfqIp.js → layout-guqP2e-e.js} +1 -1
- package/dist/dashboard/assets/linear-W2_Ct9N6.js +1 -0
- package/dist/dashboard/assets/{lt-LT-XHIRWOB4-BRKyR_Xw.js → lt-LT-XHIRWOB4-D7h1NJrv.js} +1 -1
- package/dist/dashboard/assets/{lv-LV-5QDEKY6T-BANbTe4s.js → lv-LV-5QDEKY6T-DJfUJgRc.js} +1 -1
- package/dist/dashboard/assets/{min-lcwVZhZ7.js → min-BlLHklQU.js} +1 -1
- package/dist/dashboard/assets/{mindmap-definition-QFDTVHPH-fVIbdlXp.js → mindmap-definition-QFDTVHPH-Ch2AO4mc.js} +1 -1
- package/dist/dashboard/assets/{mr-IN-CRQNXWMA-DLFutdXk.js → mr-IN-CRQNXWMA-BV3znx0p.js} +1 -1
- package/dist/dashboard/assets/{my-MM-5M5IBNSE-CGWrcNBC.js → my-MM-5M5IBNSE-IjUN-e5U.js} +1 -1
- package/dist/dashboard/assets/{nb-NO-T6EIAALU-CGRDupuc.js → nb-NO-T6EIAALU-MMsvbc2a.js} +1 -1
- package/dist/dashboard/assets/{nl-NL-IS3SIHDZ-BKwBfrzp.js → nl-NL-IS3SIHDZ-ByYTJGOK.js} +1 -1
- package/dist/dashboard/assets/{nn-NO-6E72VCQL-DDQkGe44.js → nn-NO-6E72VCQL-Bgbgzvhm.js} +1 -1
- package/dist/dashboard/assets/{oc-FR-POXYY2M6-DufeHCWh.js → oc-FR-POXYY2M6-BMBbvfQp.js} +1 -1
- package/dist/dashboard/assets/{pa-IN-N4M65BXN-BUzelJDX.js → pa-IN-N4M65BXN-CgcUC9Zd.js} +1 -1
- package/dist/dashboard/assets/{percentages-BXMCSKIN-FxAvjywS.js → percentages-BXMCSKIN-AuedyVVS.js} +7 -7
- package/dist/dashboard/assets/{pica-Cek5bFnr.js → pica-DxO5y0j_.js} +1 -1
- package/dist/dashboard/assets/{pieDiagram-DEJITSTG-PgIrKPnB.js → pieDiagram-DEJITSTG-q-J8tI3B.js} +1 -1
- package/dist/dashboard/assets/{pl-PL-T2D74RX3-Bd-rxZs3.js → pl-PL-T2D74RX3-BaZSYTKJ.js} +1 -1
- package/dist/dashboard/assets/{pt-BR-5N22H2LF-D0QJGoo5.js → pt-BR-5N22H2LF-DSPF7aLm.js} +1 -1
- package/dist/dashboard/assets/{pt-PT-UZXXM6DQ-DjumltMq.js → pt-PT-UZXXM6DQ-aoPTHC3m.js} +1 -1
- package/dist/dashboard/assets/{quadrantDiagram-34T5L4WZ-C30tZOBh.js → quadrantDiagram-34T5L4WZ-CGbfFson.js} +1 -1
- package/dist/dashboard/assets/{requirementDiagram-MS252O5E-D3vhi-ZB.js → requirementDiagram-MS252O5E-ThxVmoCe.js} +1 -1
- package/dist/dashboard/assets/{ro-RO-JPDTUUEW-DmEo8cEd.js → ro-RO-JPDTUUEW-YfCwiIS2.js} +1 -1
- package/dist/dashboard/assets/{ru-RU-B4JR7IUQ-ZHCu1nBu.js → ru-RU-B4JR7IUQ-zIVsVhsz.js} +1 -1
- package/dist/dashboard/assets/{sankeyDiagram-XADWPNL6-Cmbs-PxO.js → sankeyDiagram-XADWPNL6-BvEv917s.js} +1 -1
- package/dist/dashboard/assets/{sequenceDiagram-FGHM5R23-DlBqk4uQ.js → sequenceDiagram-FGHM5R23-JrhjN3MG.js} +1 -1
- package/dist/dashboard/assets/{si-LK-N5RQ5JYF-iuqtpRqI.js → si-LK-N5RQ5JYF-CegSAwip.js} +1 -1
- package/dist/dashboard/assets/{sk-SK-C5VTKIMK-BWFUWdaQ.js → sk-SK-C5VTKIMK-C_K-Uoai.js} +1 -1
- package/dist/dashboard/assets/{sl-SI-NN7IZMDC-irYTfiq_.js → sl-SI-NN7IZMDC-DHGXOoZl.js} +1 -1
- package/dist/dashboard/assets/{stateDiagram-FHFEXIEX-B6T9ib8G.js → stateDiagram-FHFEXIEX-BzOtZESp.js} +1 -1
- package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-CjcHIbj7.js +1 -0
- package/dist/dashboard/assets/{subset-shared.chunk-LTgWgeng.js → subset-shared.chunk-BWfXaC19.js} +1 -1
- package/dist/dashboard/assets/{subset-worker.chunk-CT_2iDuG.js → subset-worker.chunk-DHcqLDUZ.js} +1 -1
- package/dist/dashboard/assets/{sv-SE-XGPEYMSR-BvDzjArd.js → sv-SE-XGPEYMSR-BoNob2y3.js} +1 -1
- package/dist/dashboard/assets/{ta-IN-2NMHFXQM-DdsS_3Yq.js → ta-IN-2NMHFXQM-C8UHJYct.js} +1 -1
- package/dist/dashboard/assets/{th-TH-HPSO5L25-Duadkok3.js → th-TH-HPSO5L25-D7wP1iSi.js} +1 -1
- package/dist/dashboard/assets/{timeline-definition-GMOUNBTQ-CHTQqVpC.js → timeline-definition-GMOUNBTQ-Gwb0w7bX.js} +1 -1
- package/dist/dashboard/assets/{tr-TR-DEFEU3FU-CTnPpl_3.js → tr-TR-DEFEU3FU-He51QB-L.js} +1 -1
- package/dist/dashboard/assets/{uk-UA-QMV73CPH-CAqmQ01_.js → uk-UA-QMV73CPH-Blg5n9CR.js} +1 -1
- package/dist/dashboard/assets/{vennDiagram-DHZGUBPP-tWl34rwo.js → vennDiagram-DHZGUBPP-y2S0dZjp.js} +1 -1
- package/dist/dashboard/assets/{vi-VN-M7AON7JQ-Cz7FDG8R.js → vi-VN-M7AON7JQ-2z-4xcM3.js} +1 -1
- package/dist/dashboard/assets/{wardley-RL74JXVD-UjdnBcpJ.js → wardley-RL74JXVD-BNThyuCt.js} +1 -1
- package/dist/dashboard/assets/{wardleyDiagram-NUSXRM2D-KhVWSzPf.js → wardleyDiagram-NUSXRM2D-Sljri5hz.js} +1 -1
- package/dist/dashboard/assets/{xychartDiagram-5P7HB3ND-SwtVQYTW.js → xychartDiagram-5P7HB3ND-BIFYd4_d.js} +1 -1
- package/dist/dashboard/assets/{zh-CN-LNUGB5OW-B7cbFS35.js → zh-CN-LNUGB5OW-DZ8sfmlq.js} +1 -1
- package/dist/dashboard/assets/{zh-HK-E62DVLB3-CLi9BFmp.js → zh-HK-E62DVLB3-Zvqwoloz.js} +1 -1
- package/dist/dashboard/assets/{zh-TW-RAJ6MFWO-XAcgJHay.js → zh-TW-RAJ6MFWO-Ck_uDtMQ.js} +1 -1
- package/dist/dashboard/index.html +2 -2
- package/dist/index.js +930 -471
- package/package.json +1 -1
- package/dist/dashboard/assets/channel-C5p1t-nJ.js +0 -1
- package/dist/dashboard/assets/classDiagram-6PBFFD2Q-sTJpbWV4.js +0 -1
- package/dist/dashboard/assets/classDiagram-v2-HSJHXN6E-sTJpbWV4.js +0 -1
- package/dist/dashboard/assets/clone-DTslXBzp.js +0 -1
- package/dist/dashboard/assets/index-C9VT2u9E.js +0 -480
- package/dist/dashboard/assets/index-DoFaQKCx.css +0 -1
- package/dist/dashboard/assets/linear-B6cMUkoc.js +0 -1
- package/dist/dashboard/assets/stateDiagram-v2-QKLJ7IA2-CN0hAOp7.js +0 -1
package/dist/index.js
CHANGED
|
@@ -18458,11 +18458,11 @@ var init_install_claude_md = __esm({
|
|
|
18458
18458
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
|
|
18459
18459
|
import { dirname as dirname4, join as join6 } from "path";
|
|
18460
18460
|
function applyClaudeAutoMemory(projectRoot, disable) {
|
|
18461
|
-
const
|
|
18461
|
+
const settingsPath2 = join6(projectRoot, ".claude", "settings.json");
|
|
18462
18462
|
let settings = {};
|
|
18463
|
-
if (existsSync6(
|
|
18463
|
+
if (existsSync6(settingsPath2)) {
|
|
18464
18464
|
try {
|
|
18465
|
-
const parsed = JSON.parse(readFileSync7(
|
|
18465
|
+
const parsed = JSON.parse(readFileSync7(settingsPath2, "utf-8"));
|
|
18466
18466
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
18467
18467
|
settings = parsed;
|
|
18468
18468
|
}
|
|
@@ -18473,8 +18473,8 @@ function applyClaudeAutoMemory(projectRoot, disable) {
|
|
|
18473
18473
|
const desired = !disable;
|
|
18474
18474
|
if (settings.autoMemoryEnabled === desired) return false;
|
|
18475
18475
|
settings.autoMemoryEnabled = desired;
|
|
18476
|
-
mkdirSync4(dirname4(
|
|
18477
|
-
writeFileSync7(
|
|
18476
|
+
mkdirSync4(dirname4(settingsPath2), { recursive: true });
|
|
18477
|
+
writeFileSync7(settingsPath2, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
18478
18478
|
return true;
|
|
18479
18479
|
}
|
|
18480
18480
|
var init_claude_settings = __esm({
|
|
@@ -22458,12 +22458,12 @@ async function resolvePlatforms(projectRoot, raw) {
|
|
|
22458
22458
|
return platforms;
|
|
22459
22459
|
}
|
|
22460
22460
|
function ensureClaudeHooks(projectRoot) {
|
|
22461
|
-
const
|
|
22461
|
+
const settingsPath2 = join9(projectRoot, ".claude", "settings.json");
|
|
22462
22462
|
const result = { added: [], migrated: false };
|
|
22463
22463
|
let settings = {};
|
|
22464
|
-
if (existsSync9(
|
|
22464
|
+
if (existsSync9(settingsPath2)) {
|
|
22465
22465
|
try {
|
|
22466
|
-
settings = JSON.parse(readFileSync10(
|
|
22466
|
+
settings = JSON.parse(readFileSync10(settingsPath2, "utf-8"));
|
|
22467
22467
|
} catch {
|
|
22468
22468
|
settings = {};
|
|
22469
22469
|
}
|
|
@@ -22497,7 +22497,7 @@ function ensureClaudeHooks(projectRoot) {
|
|
|
22497
22497
|
}
|
|
22498
22498
|
}
|
|
22499
22499
|
mkdirSync6(join9(projectRoot, ".claude"), { recursive: true });
|
|
22500
|
-
writeFileSync9(
|
|
22500
|
+
writeFileSync9(settingsPath2, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
22501
22501
|
return result;
|
|
22502
22502
|
}
|
|
22503
22503
|
function findPackageFile(subdir, filename) {
|
|
@@ -34672,6 +34672,170 @@ var init_migration_runner = __esm({
|
|
|
34672
34672
|
}
|
|
34673
34673
|
});
|
|
34674
34674
|
|
|
34675
|
+
// src/lib/sleep-consolidation.ts
|
|
34676
|
+
function sleepinessLevel(debt) {
|
|
34677
|
+
if (debt <= 3) return "Alert";
|
|
34678
|
+
if (debt <= 6) return "Drowsy";
|
|
34679
|
+
if (debt <= 9) return "Sleepy";
|
|
34680
|
+
return "Must Sleep";
|
|
34681
|
+
}
|
|
34682
|
+
function sleepinessRange(debt) {
|
|
34683
|
+
if (debt <= 3) return "0-3";
|
|
34684
|
+
if (debt <= 6) return "4-6";
|
|
34685
|
+
if (debt <= 9) return "7-9";
|
|
34686
|
+
return "10+";
|
|
34687
|
+
}
|
|
34688
|
+
function recomputeDebt(sessions) {
|
|
34689
|
+
return sessions.reduce((sum, s) => sum + (s.score ?? 0), 0);
|
|
34690
|
+
}
|
|
34691
|
+
function depthFromDebt(debt) {
|
|
34692
|
+
if (debt <= 3) return "light";
|
|
34693
|
+
if (debt <= 9) return "standard";
|
|
34694
|
+
return "deep";
|
|
34695
|
+
}
|
|
34696
|
+
function consolidationDepth(debt, opts = {}) {
|
|
34697
|
+
const base = depthFromDebt(debt);
|
|
34698
|
+
if (opts.userRequestedDeep) {
|
|
34699
|
+
return { depth: "deep", reason: "user requested deep consolidation", source: "user" };
|
|
34700
|
+
}
|
|
34701
|
+
const bump = Math.max(0, Math.min(2, opts.agentBump ?? 0));
|
|
34702
|
+
if (bump > 0) {
|
|
34703
|
+
const baseIdx = DEPTH_ORDER.indexOf(base);
|
|
34704
|
+
const idx = Math.min(DEPTH_ORDER.length - 1, baseIdx + bump);
|
|
34705
|
+
return {
|
|
34706
|
+
depth: DEPTH_ORDER[idx],
|
|
34707
|
+
reason: `agent bumped depth by ${bump} tier(s) from ${base}`,
|
|
34708
|
+
source: "agent"
|
|
34709
|
+
};
|
|
34710
|
+
}
|
|
34711
|
+
return { depth: base, reason: `debt ${debt} \u2192 ${base}`, source: "debt" };
|
|
34712
|
+
}
|
|
34713
|
+
function isDestructiveAllowed(depth) {
|
|
34714
|
+
return depth === "deep";
|
|
34715
|
+
}
|
|
34716
|
+
function applyConsolidation(state, epoch) {
|
|
34717
|
+
const next = cloneState(state);
|
|
34718
|
+
let sessionsProcessed = 0;
|
|
34719
|
+
let bookmarksProcessed = 0;
|
|
34720
|
+
let processedSessionIds = [];
|
|
34721
|
+
if (epoch) {
|
|
34722
|
+
const processedSessions = next.sessions.filter((s) => !s.stopped_at || s.stopped_at <= epoch);
|
|
34723
|
+
sessionsProcessed = processedSessions.length;
|
|
34724
|
+
processedSessionIds = processedSessions.map((s) => s.session_id);
|
|
34725
|
+
bookmarksProcessed = next.bookmarks.filter((b) => b.created_at <= epoch).length;
|
|
34726
|
+
next.sessions = next.sessions.filter((s) => {
|
|
34727
|
+
if (!s.stopped_at) return false;
|
|
34728
|
+
return s.stopped_at > epoch;
|
|
34729
|
+
});
|
|
34730
|
+
next.bookmarks = next.bookmarks.filter((b) => b.created_at > epoch);
|
|
34731
|
+
next.dashboard_changes = next.dashboard_changes.filter((c) => c.timestamp > epoch);
|
|
34732
|
+
next.debt = recomputeDebt(next.sessions);
|
|
34733
|
+
} else {
|
|
34734
|
+
sessionsProcessed = next.sessions.length;
|
|
34735
|
+
processedSessionIds = next.sessions.map((s) => s.session_id);
|
|
34736
|
+
bookmarksProcessed = next.bookmarks.length;
|
|
34737
|
+
next.sessions = [];
|
|
34738
|
+
next.bookmarks = [];
|
|
34739
|
+
next.dashboard_changes = [];
|
|
34740
|
+
next.debt = 0;
|
|
34741
|
+
}
|
|
34742
|
+
next.triggers = next.triggers.filter((t) => t.fired_count < t.max_fires);
|
|
34743
|
+
return { state: next, sessionsProcessed, bookmarksProcessed, processedSessionIds };
|
|
34744
|
+
}
|
|
34745
|
+
function upsertSessionOnStop(state, input2) {
|
|
34746
|
+
const next = cloneState(state);
|
|
34747
|
+
const existing = next.sessions.findIndex((s) => s.session_id === input2.session_id);
|
|
34748
|
+
if (existing >= 0) {
|
|
34749
|
+
const oldScore = next.sessions[existing].score ?? 0;
|
|
34750
|
+
next.debt = Math.max(0, next.debt - oldScore);
|
|
34751
|
+
const existingSlugs = next.sessions[existing].task_slugs ?? [];
|
|
34752
|
+
next.sessions[existing] = {
|
|
34753
|
+
...next.sessions[existing],
|
|
34754
|
+
transcript_path: input2.transcript_path,
|
|
34755
|
+
stopped_at: input2.stopped_at,
|
|
34756
|
+
last_assistant_message: input2.last_assistant_message,
|
|
34757
|
+
change_count: input2.change_count,
|
|
34758
|
+
tool_count: input2.tool_count,
|
|
34759
|
+
score: input2.score,
|
|
34760
|
+
task_slugs: [.../* @__PURE__ */ new Set([...existingSlugs, ...input2.task_slugs])]
|
|
34761
|
+
};
|
|
34762
|
+
next.debt += input2.score;
|
|
34763
|
+
} else {
|
|
34764
|
+
next.sessions.unshift({
|
|
34765
|
+
session_id: input2.session_id,
|
|
34766
|
+
transcript_path: input2.transcript_path,
|
|
34767
|
+
stopped_at: input2.stopped_at,
|
|
34768
|
+
last_assistant_message: input2.last_assistant_message,
|
|
34769
|
+
change_count: input2.change_count,
|
|
34770
|
+
tool_count: input2.tool_count,
|
|
34771
|
+
score: input2.score,
|
|
34772
|
+
task_slugs: input2.task_slugs
|
|
34773
|
+
});
|
|
34774
|
+
next.debt += input2.score;
|
|
34775
|
+
next.sessions_since_last_sleep = (next.sessions_since_last_sleep || 0) + 1;
|
|
34776
|
+
}
|
|
34777
|
+
return next;
|
|
34778
|
+
}
|
|
34779
|
+
function appendCompactionRecord(state, record) {
|
|
34780
|
+
const next = cloneState(state);
|
|
34781
|
+
next.compaction_log.unshift(record);
|
|
34782
|
+
if (next.compaction_log.length > COMPACTION_LOG_CAP) {
|
|
34783
|
+
next.compaction_log = next.compaction_log.slice(0, COMPACTION_LOG_CAP);
|
|
34784
|
+
}
|
|
34785
|
+
return next;
|
|
34786
|
+
}
|
|
34787
|
+
function validateSleepAdd(scoreStr, desc) {
|
|
34788
|
+
const score = parseInt(scoreStr, 10);
|
|
34789
|
+
if (isNaN(score) || score < 1 || score > 3) {
|
|
34790
|
+
return { ok: false, error: "Score must be 1, 2, or 3." };
|
|
34791
|
+
}
|
|
34792
|
+
if (!desc.trim()) {
|
|
34793
|
+
return { ok: false, error: "Description is required." };
|
|
34794
|
+
}
|
|
34795
|
+
return { ok: true };
|
|
34796
|
+
}
|
|
34797
|
+
function buildHistoryEntry(prevDebt, result, summary, today2) {
|
|
34798
|
+
return {
|
|
34799
|
+
date: today2,
|
|
34800
|
+
consolidated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34801
|
+
summary: summary.trim(),
|
|
34802
|
+
debt_before: prevDebt,
|
|
34803
|
+
debt_after: result.state.debt,
|
|
34804
|
+
sessions_processed: result.sessionsProcessed,
|
|
34805
|
+
bookmarks_processed: result.bookmarksProcessed,
|
|
34806
|
+
session_ids: result.processedSessionIds
|
|
34807
|
+
};
|
|
34808
|
+
}
|
|
34809
|
+
function finalizeSleepState(state, summary, today2) {
|
|
34810
|
+
const next = cloneState(state);
|
|
34811
|
+
next.last_sleep = today2;
|
|
34812
|
+
next.last_sleep_summary = summary.trim();
|
|
34813
|
+
next.sleep_started_at = null;
|
|
34814
|
+
next.sessions_since_last_sleep = 0;
|
|
34815
|
+
next.consolidation_depth = null;
|
|
34816
|
+
return next;
|
|
34817
|
+
}
|
|
34818
|
+
function cloneState(state) {
|
|
34819
|
+
return {
|
|
34820
|
+
...state,
|
|
34821
|
+
sessions: state.sessions.map((s) => ({ ...s, task_slugs: [...s.task_slugs ?? []] })),
|
|
34822
|
+
bookmarks: state.bookmarks.map((b) => ({ ...b })),
|
|
34823
|
+
triggers: state.triggers.map((t) => ({ ...t })),
|
|
34824
|
+
knowledge_access: { ...state.knowledge_access },
|
|
34825
|
+
dashboard_changes: state.dashboard_changes.map((c) => ({ ...c })),
|
|
34826
|
+
compaction_log: state.compaction_log.map((c) => ({ ...c })),
|
|
34827
|
+
pendingMigrationNotices: [...state.pendingMigrationNotices]
|
|
34828
|
+
};
|
|
34829
|
+
}
|
|
34830
|
+
var DEPTH_ORDER, COMPACTION_LOG_CAP;
|
|
34831
|
+
var init_sleep_consolidation = __esm({
|
|
34832
|
+
"src/lib/sleep-consolidation.ts"() {
|
|
34833
|
+
"use strict";
|
|
34834
|
+
DEPTH_ORDER = ["light", "standard", "deep"];
|
|
34835
|
+
COMPACTION_LOG_CAP = 20;
|
|
34836
|
+
}
|
|
34837
|
+
});
|
|
34838
|
+
|
|
34675
34839
|
// src/cli/commands/sleep.ts
|
|
34676
34840
|
import { existsSync as existsSync37 } from "fs";
|
|
34677
34841
|
import { join as join37, dirname as dirname18 } from "path";
|
|
@@ -34763,8 +34927,8 @@ function registerSleepCommand(program2) {
|
|
|
34763
34927
|
sleep2.command("status").description("Show current sleep debt level and history").action(() => {
|
|
34764
34928
|
const root = ensureContextRoot();
|
|
34765
34929
|
const state = readSleepState(root);
|
|
34766
|
-
const level =
|
|
34767
|
-
const range =
|
|
34930
|
+
const level = sleepinessLevel(state.debt);
|
|
34931
|
+
const range = sleepinessRange(state.debt);
|
|
34768
34932
|
console.log(header("Sleep State"));
|
|
34769
34933
|
console.log(` Debt: ${source_default.bold(String(state.debt))} ${source_default.dim(`(${range})`)} ${source_default.magentaBright(level)}`);
|
|
34770
34934
|
console.log(` Last sleep: ${state.last_sleep ? source_default.white(state.last_sleep) : source_default.dim("never")}`);
|
|
@@ -34792,16 +34956,13 @@ function registerSleepCommand(program2) {
|
|
|
34792
34956
|
}
|
|
34793
34957
|
});
|
|
34794
34958
|
sleep2.command("add").argument("<score>", "Debt score to add (1-3)").argument("<description...>", "Description of what happened").description("Record a debt-accumulating action").action((scoreStr, descParts) => {
|
|
34795
|
-
const score = parseInt(scoreStr, 10);
|
|
34796
|
-
if (isNaN(score) || score < 1 || score > 3) {
|
|
34797
|
-
error("Score must be 1, 2, or 3.");
|
|
34798
|
-
return;
|
|
34799
|
-
}
|
|
34800
34959
|
const description = descParts.join(" ");
|
|
34801
|
-
|
|
34802
|
-
|
|
34960
|
+
const valid = validateSleepAdd(scoreStr, description);
|
|
34961
|
+
if (!valid.ok) {
|
|
34962
|
+
error(valid.error);
|
|
34803
34963
|
return;
|
|
34804
34964
|
}
|
|
34965
|
+
const score = parseInt(scoreStr, 10);
|
|
34805
34966
|
const root = ensureContextRoot();
|
|
34806
34967
|
const state = readSleepState(root);
|
|
34807
34968
|
state.sessions.unshift({
|
|
@@ -34816,7 +34977,7 @@ function registerSleepCommand(program2) {
|
|
|
34816
34977
|
});
|
|
34817
34978
|
state.debt += score;
|
|
34818
34979
|
writeSleepState(root, state);
|
|
34819
|
-
const level =
|
|
34980
|
+
const level = sleepinessLevel(state.debt);
|
|
34820
34981
|
success(`Sleep debt: ${state.debt} (${level})`);
|
|
34821
34982
|
if (state.debt >= 10) {
|
|
34822
34983
|
warn("Must sleep! Debt is 10+. Consolidation needed.");
|
|
@@ -34824,12 +34985,14 @@ function registerSleepCommand(program2) {
|
|
|
34824
34985
|
info("Getting sleepy. Consider consolidating soon.");
|
|
34825
34986
|
}
|
|
34826
34987
|
});
|
|
34827
|
-
sleep2.command("start").description("Mark beginning of consolidation (sets epoch for safe clearing)").action(() => {
|
|
34988
|
+
sleep2.command("start").description("Mark beginning of consolidation (sets epoch for safe clearing)").option("--deep", "Force a deep consolidation (authorizes destructive knowledge ops)").action((opts) => {
|
|
34828
34989
|
const root = ensureContextRoot();
|
|
34829
34990
|
const state = readSleepState(root);
|
|
34830
34991
|
if (state.sleep_started_at) {
|
|
34831
34992
|
warn(`Consolidation already in progress (started ${state.sleep_started_at}). Overwriting epoch.`);
|
|
34832
34993
|
}
|
|
34994
|
+
const decision = consolidationDepth(state.debt, { userRequestedDeep: !!opts.deep });
|
|
34995
|
+
state.consolidation_depth = decision.depth;
|
|
34833
34996
|
state.pendingMigrationNotices = [];
|
|
34834
34997
|
const projectRoot = dirname18(root);
|
|
34835
34998
|
const config = readSetupConfig(projectRoot);
|
|
@@ -34853,6 +35016,10 @@ function registerSleepCommand(program2) {
|
|
|
34853
35016
|
state.sleep_started_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
34854
35017
|
writeSleepState(root, state);
|
|
34855
35018
|
success(`Consolidation epoch set: ${state.sleep_started_at}`);
|
|
35019
|
+
info(`Consolidation depth: ${decision.depth} (source: ${decision.source}) \u2014 ${decision.reason}`);
|
|
35020
|
+
if (decision.depth !== "deep") {
|
|
35021
|
+
info("Light/standard consolidation: do NOT merge/summarize-replace/delete knowledge \u2014 flag candidates in the report instead.");
|
|
35022
|
+
}
|
|
34856
35023
|
});
|
|
34857
35024
|
sleep2.command("done").argument("<summary...>", "Summary of what was consolidated").description("Mark consolidation complete, reset debt").action(async (summaryParts) => {
|
|
34858
35025
|
const summary = summaryParts.join(" ");
|
|
@@ -34864,52 +35031,17 @@ function registerSleepCommand(program2) {
|
|
|
34864
35031
|
const state = readSleepState(root);
|
|
34865
35032
|
const previousDebt = state.debt;
|
|
34866
35033
|
const epoch = state.sleep_started_at;
|
|
34867
|
-
|
|
34868
|
-
|
|
34869
|
-
let processedSessionIds = [];
|
|
34870
|
-
if (epoch) {
|
|
34871
|
-
const processedSessions = state.sessions.filter((s) => !s.stopped_at || s.stopped_at <= epoch);
|
|
34872
|
-
sessionsProcessed = processedSessions.length;
|
|
34873
|
-
processedSessionIds = processedSessions.map((s) => s.session_id);
|
|
34874
|
-
bookmarksProcessed = state.bookmarks.filter((b) => b.created_at <= epoch).length;
|
|
34875
|
-
state.sessions = state.sessions.filter((s) => {
|
|
34876
|
-
if (!s.stopped_at) return false;
|
|
34877
|
-
return s.stopped_at > epoch;
|
|
34878
|
-
});
|
|
34879
|
-
state.bookmarks = state.bookmarks.filter((b) => b.created_at > epoch);
|
|
34880
|
-
state.dashboard_changes = state.dashboard_changes.filter((c) => c.timestamp > epoch);
|
|
34881
|
-
state.debt = state.sessions.reduce((sum, s) => sum + (s.score ?? 0), 0);
|
|
34882
|
-
} else {
|
|
34883
|
-
sessionsProcessed = state.sessions.length;
|
|
34884
|
-
processedSessionIds = state.sessions.map((s) => s.session_id);
|
|
34885
|
-
bookmarksProcessed = state.bookmarks.length;
|
|
34886
|
-
state.sessions = [];
|
|
34887
|
-
state.bookmarks = [];
|
|
34888
|
-
state.dashboard_changes = [];
|
|
34889
|
-
state.debt = 0;
|
|
34890
|
-
}
|
|
34891
|
-
state.triggers = state.triggers.filter((t) => t.fired_count < t.max_fires);
|
|
35034
|
+
const result = applyConsolidation(state, epoch);
|
|
35035
|
+
const today_ = today();
|
|
34892
35036
|
const history = readSleepHistory(root);
|
|
34893
|
-
history.unshift(
|
|
34894
|
-
date: today(),
|
|
34895
|
-
consolidated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34896
|
-
summary: summary.trim(),
|
|
34897
|
-
debt_before: previousDebt,
|
|
34898
|
-
debt_after: state.debt,
|
|
34899
|
-
sessions_processed: sessionsProcessed,
|
|
34900
|
-
bookmarks_processed: bookmarksProcessed,
|
|
34901
|
-
session_ids: processedSessionIds
|
|
34902
|
-
});
|
|
35037
|
+
history.unshift(buildHistoryEntry(previousDebt, result, summary, today_));
|
|
34903
35038
|
writeSleepHistory(root, history);
|
|
34904
|
-
|
|
34905
|
-
|
|
34906
|
-
|
|
34907
|
-
|
|
34908
|
-
writeSleepState(root, state);
|
|
34909
|
-
if (epoch && state.sessions.length > 0) {
|
|
34910
|
-
success(`Consolidation complete. Debt reduced from ${previousDebt} to ${state.debt}. ${state.sessions.length} post-epoch session(s) preserved.`);
|
|
35039
|
+
const finalState = finalizeSleepState(result.state, summary, today_);
|
|
35040
|
+
writeSleepState(root, finalState);
|
|
35041
|
+
if (epoch && finalState.sessions.length > 0) {
|
|
35042
|
+
success(`Consolidation complete. Debt reduced from ${previousDebt} to ${finalState.debt}. ${finalState.sessions.length} post-epoch session(s) preserved.`);
|
|
34911
35043
|
} else {
|
|
34912
|
-
success(`Consolidation complete. Debt reset from ${previousDebt} to ${
|
|
35044
|
+
success(`Consolidation complete. Debt reset from ${previousDebt} to ${finalState.debt}.`);
|
|
34913
35045
|
}
|
|
34914
35046
|
try {
|
|
34915
35047
|
const backend = getTaskBackend(root);
|
|
@@ -35001,6 +35133,7 @@ var init_sleep = __esm({
|
|
|
35001
35133
|
init_migration_runner();
|
|
35002
35134
|
init_setup_config();
|
|
35003
35135
|
init_manifest();
|
|
35136
|
+
init_sleep_consolidation();
|
|
35004
35137
|
}
|
|
35005
35138
|
});
|
|
35006
35139
|
|
|
@@ -37684,6 +37817,53 @@ var init_snapshot2 = __esm({
|
|
|
37684
37817
|
}
|
|
37685
37818
|
});
|
|
37686
37819
|
|
|
37820
|
+
// src/lib/salience.ts
|
|
37821
|
+
function clamp(text) {
|
|
37822
|
+
const oneLine = text.replace(/\s+/g, " ").trim();
|
|
37823
|
+
return oneLine.length <= MAX_MESSAGE_CHARS ? oneLine : oneLine.slice(0, MAX_MESSAGE_CHARS - 1) + "\u2026";
|
|
37824
|
+
}
|
|
37825
|
+
function detectSalience(distilled) {
|
|
37826
|
+
const moments = [];
|
|
37827
|
+
const seen = /* @__PURE__ */ new Set();
|
|
37828
|
+
const push = (message, salience) => {
|
|
37829
|
+
const clamped = clamp(message);
|
|
37830
|
+
if (!clamped) return;
|
|
37831
|
+
const key = `${salience}::${clamped.toLowerCase()}`;
|
|
37832
|
+
if (seen.has(key)) return;
|
|
37833
|
+
seen.add(key);
|
|
37834
|
+
moments.push({ message: clamped, salience });
|
|
37835
|
+
};
|
|
37836
|
+
for (const msg of distilled.userMessages) {
|
|
37837
|
+
if (CORRECTION_RE.test(msg)) {
|
|
37838
|
+
push(`User correction: ${msg}`, 2);
|
|
37839
|
+
}
|
|
37840
|
+
}
|
|
37841
|
+
if (distilled.errors.length > 0 && distilled.codeChanges.length > 0) {
|
|
37842
|
+
const firstError = distilled.errors[0];
|
|
37843
|
+
push(`Error resolved by code change: ${firstError}`, 1);
|
|
37844
|
+
}
|
|
37845
|
+
const decisionSources = [
|
|
37846
|
+
...distilled.agentDecisions.filter((d) => !d.startsWith("[thinking]")),
|
|
37847
|
+
...distilled.userMessages
|
|
37848
|
+
];
|
|
37849
|
+
for (const src of decisionSources) {
|
|
37850
|
+
if (DECISION_RE.test(src)) {
|
|
37851
|
+
push(`Decision: ${src}`, 2);
|
|
37852
|
+
}
|
|
37853
|
+
}
|
|
37854
|
+
return moments.slice(0, MAX_MOMENTS);
|
|
37855
|
+
}
|
|
37856
|
+
var CORRECTION_RE, DECISION_RE, MAX_MOMENTS, MAX_MESSAGE_CHARS;
|
|
37857
|
+
var init_salience = __esm({
|
|
37858
|
+
"src/lib/salience.ts"() {
|
|
37859
|
+
"use strict";
|
|
37860
|
+
CORRECTION_RE = /\b(no|actually|wrong|instead|hayır|yanlış|değil)\b/i;
|
|
37861
|
+
DECISION_RE = /\b(decided|chose|switched to|will use|karar|seçtik)\b/i;
|
|
37862
|
+
MAX_MOMENTS = 5;
|
|
37863
|
+
MAX_MESSAGE_CHARS = 200;
|
|
37864
|
+
}
|
|
37865
|
+
});
|
|
37866
|
+
|
|
37687
37867
|
// src/cli/commands/transcript.ts
|
|
37688
37868
|
import { readFileSync as readFileSync35, existsSync as existsSync46, statSync as statSync6 } from "fs";
|
|
37689
37869
|
function distillTranscript(transcriptPath, sinceTimestamp) {
|
|
@@ -38878,53 +39058,6 @@ var init_session_digest = __esm({
|
|
|
38878
39058
|
}
|
|
38879
39059
|
});
|
|
38880
39060
|
|
|
38881
|
-
// src/lib/salience.ts
|
|
38882
|
-
function clamp(text) {
|
|
38883
|
-
const oneLine = text.replace(/\s+/g, " ").trim();
|
|
38884
|
-
return oneLine.length <= MAX_MESSAGE_CHARS ? oneLine : oneLine.slice(0, MAX_MESSAGE_CHARS - 1) + "\u2026";
|
|
38885
|
-
}
|
|
38886
|
-
function detectSalience(distilled) {
|
|
38887
|
-
const moments = [];
|
|
38888
|
-
const seen = /* @__PURE__ */ new Set();
|
|
38889
|
-
const push = (message, salience) => {
|
|
38890
|
-
const clamped = clamp(message);
|
|
38891
|
-
if (!clamped) return;
|
|
38892
|
-
const key = `${salience}::${clamped.toLowerCase()}`;
|
|
38893
|
-
if (seen.has(key)) return;
|
|
38894
|
-
seen.add(key);
|
|
38895
|
-
moments.push({ message: clamped, salience });
|
|
38896
|
-
};
|
|
38897
|
-
for (const msg of distilled.userMessages) {
|
|
38898
|
-
if (CORRECTION_RE.test(msg)) {
|
|
38899
|
-
push(`User correction: ${msg}`, 2);
|
|
38900
|
-
}
|
|
38901
|
-
}
|
|
38902
|
-
if (distilled.errors.length > 0 && distilled.codeChanges.length > 0) {
|
|
38903
|
-
const firstError = distilled.errors[0];
|
|
38904
|
-
push(`Error resolved by code change: ${firstError}`, 1);
|
|
38905
|
-
}
|
|
38906
|
-
const decisionSources = [
|
|
38907
|
-
...distilled.agentDecisions.filter((d) => !d.startsWith("[thinking]")),
|
|
38908
|
-
...distilled.userMessages
|
|
38909
|
-
];
|
|
38910
|
-
for (const src of decisionSources) {
|
|
38911
|
-
if (DECISION_RE.test(src)) {
|
|
38912
|
-
push(`Decision: ${src}`, 2);
|
|
38913
|
-
}
|
|
38914
|
-
}
|
|
38915
|
-
return moments.slice(0, MAX_MOMENTS);
|
|
38916
|
-
}
|
|
38917
|
-
var CORRECTION_RE, DECISION_RE, MAX_MOMENTS, MAX_MESSAGE_CHARS;
|
|
38918
|
-
var init_salience = __esm({
|
|
38919
|
-
"src/lib/salience.ts"() {
|
|
38920
|
-
"use strict";
|
|
38921
|
-
CORRECTION_RE = /\b(no|actually|wrong|instead|hayır|yanlış|değil)\b/i;
|
|
38922
|
-
DECISION_RE = /\b(decided|chose|switched to|will use|karar|seçtik)\b/i;
|
|
38923
|
-
MAX_MOMENTS = 5;
|
|
38924
|
-
MAX_MESSAGE_CHARS = 200;
|
|
38925
|
-
}
|
|
38926
|
-
});
|
|
38927
|
-
|
|
38928
39061
|
// src/lib/marketing/path-guards.ts
|
|
38929
39062
|
import { existsSync as existsSync49, realpathSync } from "fs";
|
|
38930
39063
|
import { basename as basename14, dirname as dirname24, resolve as resolve8, sep as sep5 } from "path";
|
|
@@ -39487,15 +39620,76 @@ function analyzeTranscript(transcriptPath) {
|
|
|
39487
39620
|
for (const m of content.matchAll(/"file_path"\s*:\s*"[^"]*_dream_context\/state\/([a-z0-9][a-z0-9-]*)\.md"/g)) {
|
|
39488
39621
|
slugs.add(m[1]);
|
|
39489
39622
|
}
|
|
39623
|
+
let userTurns = 0;
|
|
39624
|
+
let assistantChars = 0;
|
|
39625
|
+
let decisionMarkers = 0;
|
|
39626
|
+
for (const line of content.split("\n")) {
|
|
39627
|
+
const trimmed = line.trim();
|
|
39628
|
+
if (!trimmed) continue;
|
|
39629
|
+
if (DECISION_RE.test(trimmed) || CORRECTION_RE.test(trimmed)) {
|
|
39630
|
+
decisionMarkers++;
|
|
39631
|
+
}
|
|
39632
|
+
let rec;
|
|
39633
|
+
try {
|
|
39634
|
+
rec = JSON.parse(trimmed);
|
|
39635
|
+
} catch {
|
|
39636
|
+
continue;
|
|
39637
|
+
}
|
|
39638
|
+
if (!rec || typeof rec !== "object") continue;
|
|
39639
|
+
const role = recordRole(rec);
|
|
39640
|
+
if (role === "user") {
|
|
39641
|
+
userTurns++;
|
|
39642
|
+
} else if (role === "assistant") {
|
|
39643
|
+
assistantChars += sumAssistantTextChars(rec);
|
|
39644
|
+
}
|
|
39645
|
+
}
|
|
39490
39646
|
return {
|
|
39491
39647
|
changeCount: changeMatches ? changeMatches.length : 0,
|
|
39492
39648
|
toolCount: toolMatches ? toolMatches.length : 0,
|
|
39493
|
-
taskSlugs: [...slugs]
|
|
39649
|
+
taskSlugs: [...slugs],
|
|
39650
|
+
userTurns,
|
|
39651
|
+
assistantChars,
|
|
39652
|
+
decisionMarkers
|
|
39494
39653
|
};
|
|
39495
39654
|
} catch {
|
|
39496
39655
|
return ZERO_ANALYSIS;
|
|
39497
39656
|
}
|
|
39498
39657
|
}
|
|
39658
|
+
function recordRole(rec) {
|
|
39659
|
+
const r = rec;
|
|
39660
|
+
if (typeof r.role === "string") return r.role;
|
|
39661
|
+
if (r.message && typeof r.message === "object" && typeof r.message.role === "string") {
|
|
39662
|
+
return r.message.role;
|
|
39663
|
+
}
|
|
39664
|
+
return null;
|
|
39665
|
+
}
|
|
39666
|
+
function sumAssistantTextChars(rec) {
|
|
39667
|
+
const r = rec;
|
|
39668
|
+
const content = (r.message && typeof r.message === "object" ? r.message.content : void 0) ?? r.content;
|
|
39669
|
+
let total = 0;
|
|
39670
|
+
if (typeof content === "string") {
|
|
39671
|
+
return Math.min(MAX_TEXT_BLOCK_CHARS, content.length);
|
|
39672
|
+
}
|
|
39673
|
+
if (Array.isArray(content)) {
|
|
39674
|
+
for (const block of content) {
|
|
39675
|
+
if (block && typeof block === "object") {
|
|
39676
|
+
const b = block;
|
|
39677
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
39678
|
+
total += Math.min(MAX_TEXT_BLOCK_CHARS, b.text.length);
|
|
39679
|
+
}
|
|
39680
|
+
}
|
|
39681
|
+
}
|
|
39682
|
+
}
|
|
39683
|
+
return total;
|
|
39684
|
+
}
|
|
39685
|
+
function scoreFromSubstance(signals2) {
|
|
39686
|
+
let pts = 0;
|
|
39687
|
+
if (signals2.userTurns >= 6) pts++;
|
|
39688
|
+
if (signals2.assistantChars >= 6e3) pts++;
|
|
39689
|
+
if (signals2.decisionMarkers >= 1) pts++;
|
|
39690
|
+
if (signals2.taskSlugs.length >= 2) pts++;
|
|
39691
|
+
return Math.min(3, pts);
|
|
39692
|
+
}
|
|
39499
39693
|
function scoreFromChangeCount(count) {
|
|
39500
39694
|
if (count <= 0) return 0;
|
|
39501
39695
|
if (count <= 3) return 1;
|
|
@@ -39687,6 +39881,29 @@ function getConsolidationDirective(state) {
|
|
|
39687
39881
|
}
|
|
39688
39882
|
return null;
|
|
39689
39883
|
}
|
|
39884
|
+
function userPromptReminder(state) {
|
|
39885
|
+
const { debt, bookmarks, sleep_started_at } = state;
|
|
39886
|
+
if (sleep_started_at) {
|
|
39887
|
+
if (debt >= 4) {
|
|
39888
|
+
return `Consolidation already in progress (started: ${sleep_started_at}). Do NOT dispatch another sleep agent.`;
|
|
39889
|
+
}
|
|
39890
|
+
return null;
|
|
39891
|
+
}
|
|
39892
|
+
const criticalBookmarks = bookmarks.filter((b) => b.salience === 3);
|
|
39893
|
+
if (debt >= 10) {
|
|
39894
|
+
return `Sleep debt is ${debt}. CONSOLIDATION REQUIRED. Run sleep flow per SKILL.md (parallel specialist fan-out) NOW.`;
|
|
39895
|
+
}
|
|
39896
|
+
if (criticalBookmarks.length > 0) {
|
|
39897
|
+
return `${criticalBookmarks.length} critical bookmark(s) need consolidation. Run sleep flow per SKILL.md.`;
|
|
39898
|
+
}
|
|
39899
|
+
if (debt >= 7) {
|
|
39900
|
+
return `Sleep debt is ${debt}. Consolidation recommended before starting new work.`;
|
|
39901
|
+
}
|
|
39902
|
+
if (debt >= 4) {
|
|
39903
|
+
return `Sleep debt is ${debt}. After completing the current task, offer to consolidate.`;
|
|
39904
|
+
}
|
|
39905
|
+
return null;
|
|
39906
|
+
}
|
|
39690
39907
|
function resolveDashboardPort() {
|
|
39691
39908
|
const raw = process.env.DREAMCONTEXT_DASHBOARD_PORT;
|
|
39692
39909
|
if (raw) {
|
|
@@ -39749,7 +39966,11 @@ function registerHookCommand(program2) {
|
|
|
39749
39966
|
const stoppedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
39750
39967
|
const analysis = transcriptPath ? analyzeTranscript(transcriptPath) : ZERO_ANALYSIS;
|
|
39751
39968
|
const { changeCount, toolCount } = analysis;
|
|
39752
|
-
const score = Math.max(
|
|
39969
|
+
const score = Math.max(
|
|
39970
|
+
scoreFromChangeCount(changeCount),
|
|
39971
|
+
scoreFromToolCount(toolCount),
|
|
39972
|
+
scoreFromSubstance(analysis)
|
|
39973
|
+
);
|
|
39753
39974
|
for (const bookmark of state.bookmarks) {
|
|
39754
39975
|
if (!bookmark.session_id) {
|
|
39755
39976
|
bookmark.session_id = sessionId;
|
|
@@ -39758,35 +39979,18 @@ function registerHookCommand(program2) {
|
|
|
39758
39979
|
const bookmarkTaskSlugs = state.bookmarks.filter((b) => b.session_id === sessionId && b.task_slug).map((b) => b.task_slug);
|
|
39759
39980
|
const transcriptTaskSlugs = analysis.taskSlugs;
|
|
39760
39981
|
const taskSlugs = [.../* @__PURE__ */ new Set([...transcriptTaskSlugs, ...bookmarkTaskSlugs])];
|
|
39761
|
-
const
|
|
39762
|
-
|
|
39763
|
-
|
|
39764
|
-
|
|
39765
|
-
|
|
39766
|
-
|
|
39767
|
-
|
|
39768
|
-
|
|
39769
|
-
|
|
39770
|
-
|
|
39771
|
-
|
|
39772
|
-
|
|
39773
|
-
} else {
|
|
39774
|
-
state.sessions.unshift({
|
|
39775
|
-
session_id: sessionId,
|
|
39776
|
-
transcript_path: transcriptPath,
|
|
39777
|
-
stopped_at: stoppedAt,
|
|
39778
|
-
last_assistant_message: lastAssistantMessage,
|
|
39779
|
-
change_count: changeCount,
|
|
39780
|
-
tool_count: toolCount,
|
|
39781
|
-
score,
|
|
39782
|
-
task_slugs: taskSlugs
|
|
39783
|
-
});
|
|
39784
|
-
}
|
|
39785
|
-
state.debt += score;
|
|
39786
|
-
if (existing < 0) {
|
|
39787
|
-
state.sessions_since_last_sleep = (state.sessions_since_last_sleep || 0) + 1;
|
|
39788
|
-
}
|
|
39789
|
-
writeSleepState(root, state);
|
|
39982
|
+
const upsertInput = {
|
|
39983
|
+
session_id: sessionId,
|
|
39984
|
+
transcript_path: transcriptPath,
|
|
39985
|
+
stopped_at: stoppedAt,
|
|
39986
|
+
last_assistant_message: lastAssistantMessage,
|
|
39987
|
+
change_count: changeCount,
|
|
39988
|
+
tool_count: toolCount,
|
|
39989
|
+
score,
|
|
39990
|
+
task_slugs: taskSlugs
|
|
39991
|
+
};
|
|
39992
|
+
const nextState = upsertSessionOnStop(state, upsertInput);
|
|
39993
|
+
writeSleepState(root, nextState);
|
|
39790
39994
|
});
|
|
39791
39995
|
hook.command("session-start").description("Analyze previous session + output context snapshot (called by Claude Code SessionStart hook)").action(() => {
|
|
39792
39996
|
const input2 = readStdin();
|
|
@@ -39808,7 +40012,11 @@ function registerHookCommand(program2) {
|
|
|
39808
40012
|
continue;
|
|
39809
40013
|
}
|
|
39810
40014
|
const analysis = analyzeTranscript(session.transcript_path);
|
|
39811
|
-
const score = Math.max(
|
|
40015
|
+
const score = Math.max(
|
|
40016
|
+
scoreFromChangeCount(analysis.changeCount),
|
|
40017
|
+
scoreFromToolCount(analysis.toolCount),
|
|
40018
|
+
scoreFromSubstance(analysis)
|
|
40019
|
+
);
|
|
39812
40020
|
session.change_count = analysis.changeCount;
|
|
39813
40021
|
session.tool_count = analysis.toolCount;
|
|
39814
40022
|
session.score = score;
|
|
@@ -39913,23 +40121,12 @@ function registerHookCommand(program2) {
|
|
|
39913
40121
|
const root = resolveContextRoot();
|
|
39914
40122
|
if (!root) process.exit(0);
|
|
39915
40123
|
const state = readSleepState(root);
|
|
39916
|
-
const
|
|
39917
|
-
if (sleep_started_at) {
|
|
39918
|
-
if (
|
|
39919
|
-
console.log(`Consolidation already in progress (started: ${sleep_started_at}). Do NOT dispatch another sleep agent.`);
|
|
39920
|
-
}
|
|
40124
|
+
const reminder = userPromptReminder(state);
|
|
40125
|
+
if (state.sleep_started_at) {
|
|
40126
|
+
if (reminder) console.log(reminder);
|
|
39921
40127
|
return;
|
|
39922
40128
|
}
|
|
39923
|
-
|
|
39924
|
-
if (debt >= 10) {
|
|
39925
|
-
console.log(`Sleep debt is ${debt}. CONSOLIDATION REQUIRED. Run sleep flow per SKILL.md (parallel specialist fan-out) NOW.`);
|
|
39926
|
-
} else if (criticalBookmarks.length > 0) {
|
|
39927
|
-
console.log(`${criticalBookmarks.length} critical bookmark(s) need consolidation. Run sleep flow per SKILL.md.`);
|
|
39928
|
-
} else if (debt >= 7) {
|
|
39929
|
-
console.log(`Sleep debt is ${debt}. Consolidation recommended before starting new work.`);
|
|
39930
|
-
} else if (debt >= 4) {
|
|
39931
|
-
console.log(`Sleep debt is ${debt}. After completing the current task, offer to consolidate.`);
|
|
39932
|
-
}
|
|
40129
|
+
if (reminder) console.log(reminder);
|
|
39933
40130
|
try {
|
|
39934
40131
|
const stale = listStaleRecs(24);
|
|
39935
40132
|
if (stale.length > 0) {
|
|
@@ -40079,17 +40276,14 @@ function registerHookCommand(program2) {
|
|
|
40079
40276
|
if (!root) process.exit(0);
|
|
40080
40277
|
const state = readSleepState(root);
|
|
40081
40278
|
const trigger = input2 && typeof input2.trigger === "string" ? input2.trigger : "unknown";
|
|
40082
|
-
state
|
|
40279
|
+
const nextState = appendCompactionRecord(state, {
|
|
40083
40280
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40084
40281
|
trigger,
|
|
40085
40282
|
debt_at_compaction: state.debt,
|
|
40086
40283
|
sessions_count: state.sessions.length,
|
|
40087
40284
|
bookmarks_count: state.bookmarks.length
|
|
40088
40285
|
});
|
|
40089
|
-
|
|
40090
|
-
state.compaction_log = state.compaction_log.slice(0, 20);
|
|
40091
|
-
}
|
|
40092
|
-
writeSleepState(root, state);
|
|
40286
|
+
writeSleepState(root, nextState);
|
|
40093
40287
|
try {
|
|
40094
40288
|
const sessionId = input2 && typeof input2.session_id === "string" ? input2.session_id : "";
|
|
40095
40289
|
const transcriptPath = input2 && typeof input2.transcript_path === "string" ? input2.transcript_path : "";
|
|
@@ -40118,12 +40312,14 @@ function registerHookCommand(program2) {
|
|
|
40118
40312
|
process.exit(0);
|
|
40119
40313
|
});
|
|
40120
40314
|
}
|
|
40121
|
-
var MAX_TRANSCRIPT_BYTES2, SKILL_SCORE_THRESHOLD, ZERO_ANALYSIS, JS_TS_EXTENSIONS, MAX_WALK_LEVELS, BIOME_CONFIGS, PRETTIER_CONFIGS, DEFAULT_DASHBOARD_PORT;
|
|
40315
|
+
var MAX_TRANSCRIPT_BYTES2, SKILL_SCORE_THRESHOLD, ZERO_ANALYSIS, MAX_TEXT_BLOCK_CHARS, JS_TS_EXTENSIONS, MAX_WALK_LEVELS, BIOME_CONFIGS, PRETTIER_CONFIGS, DEFAULT_DASHBOARD_PORT;
|
|
40122
40316
|
var init_hook = __esm({
|
|
40123
40317
|
"src/cli/commands/hook.ts"() {
|
|
40124
40318
|
"use strict";
|
|
40125
40319
|
init_context_path();
|
|
40126
40320
|
init_sleep();
|
|
40321
|
+
init_sleep_consolidation();
|
|
40322
|
+
init_salience();
|
|
40127
40323
|
init_transcript();
|
|
40128
40324
|
init_session_digest();
|
|
40129
40325
|
init_salience();
|
|
@@ -40140,7 +40336,15 @@ var init_hook = __esm({
|
|
|
40140
40336
|
init_install_skill();
|
|
40141
40337
|
MAX_TRANSCRIPT_BYTES2 = 50 * 1024 * 1024;
|
|
40142
40338
|
SKILL_SCORE_THRESHOLD = 1;
|
|
40143
|
-
ZERO_ANALYSIS = {
|
|
40339
|
+
ZERO_ANALYSIS = {
|
|
40340
|
+
changeCount: 0,
|
|
40341
|
+
toolCount: 0,
|
|
40342
|
+
taskSlugs: [],
|
|
40343
|
+
userTurns: 0,
|
|
40344
|
+
assistantChars: 0,
|
|
40345
|
+
decisionMarkers: 0
|
|
40346
|
+
};
|
|
40347
|
+
MAX_TEXT_BLOCK_CHARS = 2e4;
|
|
40144
40348
|
JS_TS_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"]);
|
|
40145
40349
|
MAX_WALK_LEVELS = 10;
|
|
40146
40350
|
BIOME_CONFIGS = ["biome.json", "biome.jsonc"];
|
|
@@ -41080,8 +41284,8 @@ async function handleCoreGet(_req, res, params, contextRoot) {
|
|
|
41080
41284
|
return;
|
|
41081
41285
|
}
|
|
41082
41286
|
if (filename.endsWith(".json")) {
|
|
41083
|
-
const { readFileSync:
|
|
41084
|
-
const raw2 =
|
|
41287
|
+
const { readFileSync: readFileSync67 } = await import("fs");
|
|
41288
|
+
const raw2 = readFileSync67(filePath, "utf-8");
|
|
41085
41289
|
try {
|
|
41086
41290
|
const data = JSON.parse(raw2);
|
|
41087
41291
|
sendJson(res, 200, { filename, type: "json", data });
|
|
@@ -41115,8 +41319,8 @@ async function handleCoreGet(_req, res, params, contextRoot) {
|
|
|
41115
41319
|
});
|
|
41116
41320
|
return;
|
|
41117
41321
|
}
|
|
41118
|
-
const { readFileSync:
|
|
41119
|
-
const raw =
|
|
41322
|
+
const { readFileSync: readFileSync66 } = await import("fs");
|
|
41323
|
+
const raw = readFileSync66(filePath, "utf-8");
|
|
41120
41324
|
sendJson(res, 200, { filename, type: "text", content: raw });
|
|
41121
41325
|
}
|
|
41122
41326
|
async function handleCoreUpdate(req, res, params, contextRoot) {
|
|
@@ -41166,8 +41370,8 @@ async function handleCoreUpdate(req, res, params, contextRoot) {
|
|
|
41166
41370
|
return;
|
|
41167
41371
|
}
|
|
41168
41372
|
changedParts.push("content");
|
|
41169
|
-
const { writeFileSync:
|
|
41170
|
-
|
|
41373
|
+
const { writeFileSync: writeFileSync45 } = await import("fs");
|
|
41374
|
+
writeFileSync45(filePath, body.content, "utf-8");
|
|
41171
41375
|
}
|
|
41172
41376
|
const what = changedParts.length > 0 ? changedParts.join(" and ") : "file";
|
|
41173
41377
|
recordDashboardChange(contextRoot, {
|
|
@@ -42782,8 +42986,9 @@ function buildAskPrompt(question) {
|
|
|
42782
42986
|
|
|
42783
42987
|
Question: "${question}"`;
|
|
42784
42988
|
}
|
|
42785
|
-
function buildSleepPrompt() {
|
|
42786
|
-
|
|
42989
|
+
function buildSleepPrompt(depth) {
|
|
42990
|
+
const depthLine = isDestructiveAllowed(depth) ? `This is a DEEP consolidation: you ARE authorized to perform destructive/expensive knowledge ops (merge-with-delete, summarize-and-replace still-valid detail, archive/delete stale files) \u2014 but first copy any file you will merge/replace/delete to \`_dream_context/knowledge/.archive/<slug>-<YYYYMMDD>.md\` (create the dir if absent).` : `This is a ${depth.toUpperCase()} consolidation: do NOT merge, summarize-and-replace, or delete any knowledge. Only create/extend/retag/tick. If you spot merge or deletion candidates, FLAG them in your report instead of acting on them.`;
|
|
42991
|
+
return `Think hard. Run a dreamcontext memory consolidation ("sleep") for THIS project now, fully autonomously \u2014 do NOT ask any questions. Follow the project's dreamcontext sleep/consolidation flow: pin the epoch with \`dreamcontext sleep start\`, reconcile the task/changelog/knowledge/feature files to current truth as warranted (prefer updating existing entities over creating new ones), then close the cycle with \`dreamcontext sleep done "<one-paragraph summary>"\` to reset the debt. ${depthLine} When finished, reply with a SHORT GitHub-flavored Markdown summary (a few bullets) of what was consolidated. Keep it concise.`;
|
|
42787
42992
|
}
|
|
42788
42993
|
async function handleLauncherCapture(req, res, _params, _contextRoot) {
|
|
42789
42994
|
const body = await parseJsonBody(req);
|
|
@@ -42841,7 +43046,18 @@ async function handleLauncherCapture(req, res, _params, _contextRoot) {
|
|
|
42841
43046
|
captureRuns.set(captureId, run2);
|
|
42842
43047
|
try {
|
|
42843
43048
|
const shell = process.env.SHELL || "/bin/zsh";
|
|
42844
|
-
|
|
43049
|
+
let sleepDepth = "deep";
|
|
43050
|
+
if (mode === "sleep") {
|
|
43051
|
+
try {
|
|
43052
|
+
sleepDepth = consolidationDepth(readSleepState(cwd).debt, {
|
|
43053
|
+
userRequestedDeep: true
|
|
43054
|
+
}).depth;
|
|
43055
|
+
} catch (err) {
|
|
43056
|
+
console.error("[launcher] could not read sleep state for depth:", err);
|
|
43057
|
+
sleepDepth = "deep";
|
|
43058
|
+
}
|
|
43059
|
+
}
|
|
43060
|
+
const prompt = mode === "sleep" ? buildSleepPrompt(sleepDepth) : mode === "ask" ? buildAskPrompt(text) : buildCapturePrompt(text);
|
|
42845
43061
|
const child = spawn4(shell, ["-ilc", 'exec claude --model sonnet -p "$0"', prompt], {
|
|
42846
43062
|
cwd,
|
|
42847
43063
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -42888,6 +43104,177 @@ async function handleLauncherDefaults(_req, res, _params, _contextRoot) {
|
|
|
42888
43104
|
const home = homedir3();
|
|
42889
43105
|
sendJson(res, 200, { home, defaultParent: join59(home, "projects") });
|
|
42890
43106
|
}
|
|
43107
|
+
function computeVaultStatus(v, latest) {
|
|
43108
|
+
const exists = existsSync63(resolve15(v.path));
|
|
43109
|
+
let setupVersion = "0.0.0";
|
|
43110
|
+
let shareable = false;
|
|
43111
|
+
if (exists) {
|
|
43112
|
+
try {
|
|
43113
|
+
const cfg = readSetupConfig(resolve15(v.path));
|
|
43114
|
+
if (cfg) {
|
|
43115
|
+
setupVersion = cfg.setupVersion || "0.0.0";
|
|
43116
|
+
shareable = cfg.shareable === true;
|
|
43117
|
+
}
|
|
43118
|
+
} catch {
|
|
43119
|
+
}
|
|
43120
|
+
}
|
|
43121
|
+
const needsUpdate = exists && compareVersions(setupVersion, latest) < 0;
|
|
43122
|
+
return { name: v.name, path: v.path, exists, setupVersion, latestVersion: latest, needsUpdate, shareable };
|
|
43123
|
+
}
|
|
43124
|
+
async function handleLauncherStatus(_req, res, _params, _contextRoot) {
|
|
43125
|
+
const latest = dreamcontextVersion();
|
|
43126
|
+
const vaults = listVaults().map((v) => computeVaultStatus(v, latest));
|
|
43127
|
+
sendJson(res, 200, { vaults, latestVersion: latest });
|
|
43128
|
+
}
|
|
43129
|
+
async function handleLauncherUnregister(req, res, _params, _contextRoot) {
|
|
43130
|
+
const body = await parseJsonBody(req);
|
|
43131
|
+
if (!body) {
|
|
43132
|
+
sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
|
|
43133
|
+
return;
|
|
43134
|
+
}
|
|
43135
|
+
const name = typeof body.name === "string" ? body.name.trim() : "";
|
|
43136
|
+
if (!name) {
|
|
43137
|
+
sendError(res, 400, "invalid_name", "name must be a non-empty string.");
|
|
43138
|
+
return;
|
|
43139
|
+
}
|
|
43140
|
+
const removed = removeVault(name);
|
|
43141
|
+
sendJson(res, 200, { removed, vaults: listVaults() });
|
|
43142
|
+
}
|
|
43143
|
+
async function handleLauncherUpdate(req, res, _params, _contextRoot) {
|
|
43144
|
+
const body = await parseJsonBody(req);
|
|
43145
|
+
if (!body) {
|
|
43146
|
+
sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
|
|
43147
|
+
return;
|
|
43148
|
+
}
|
|
43149
|
+
const name = typeof body.name === "string" ? body.name.trim() : "";
|
|
43150
|
+
if (!name) {
|
|
43151
|
+
sendError(res, 400, "invalid_name", "name must be a non-empty string.");
|
|
43152
|
+
return;
|
|
43153
|
+
}
|
|
43154
|
+
const vault = listVaults().find((v) => v.name === name);
|
|
43155
|
+
if (!vault) {
|
|
43156
|
+
sendError(res, 400, "unknown_vault", `No registered vault named "${name}".`);
|
|
43157
|
+
return;
|
|
43158
|
+
}
|
|
43159
|
+
const target = resolve15(vault.path);
|
|
43160
|
+
if (!existsSync63(target)) {
|
|
43161
|
+
sendError(res, 400, "missing_vault", `Vault path no longer exists: ${target}`);
|
|
43162
|
+
return;
|
|
43163
|
+
}
|
|
43164
|
+
try {
|
|
43165
|
+
await defaultCliRunner(["update"], target);
|
|
43166
|
+
const latest = dreamcontextVersion();
|
|
43167
|
+
sendJson(res, 200, { ok: true, status: computeVaultStatus(vault, latest) });
|
|
43168
|
+
} catch (err) {
|
|
43169
|
+
console.error("[launcher] update failed:", err);
|
|
43170
|
+
const detail = err instanceof Error ? err.message : "unknown error";
|
|
43171
|
+
sendError(res, 500, "update_failed", `Update failed: ${detail}`);
|
|
43172
|
+
}
|
|
43173
|
+
}
|
|
43174
|
+
async function handleLauncherFederationGraph(_req, res, _params, _contextRoot) {
|
|
43175
|
+
const latest = dreamcontextVersion();
|
|
43176
|
+
const vaults = listVaults();
|
|
43177
|
+
const nodes = vaults.map((v) => computeVaultStatus(v, latest));
|
|
43178
|
+
const shareableByName = new Map(nodes.map((n) => [n.name, n.shareable]));
|
|
43179
|
+
const known = new Set(vaults.map((v) => v.name));
|
|
43180
|
+
const edges = [];
|
|
43181
|
+
const seen = /* @__PURE__ */ new Set();
|
|
43182
|
+
for (const v of vaults) {
|
|
43183
|
+
if (!existsSync63(resolve15(v.path))) continue;
|
|
43184
|
+
const conns = listConnections(join59(resolve15(v.path), "_dream_context"));
|
|
43185
|
+
for (const c of conns) {
|
|
43186
|
+
if (c.direction !== "out" && c.direction !== "both") continue;
|
|
43187
|
+
if (!known.has(c.vault)) continue;
|
|
43188
|
+
if (c.status === "stale") continue;
|
|
43189
|
+
const key = `${v.name}\0${c.vault}`;
|
|
43190
|
+
if (seen.has(key)) continue;
|
|
43191
|
+
seen.add(key);
|
|
43192
|
+
edges.push({ source: v.name, target: c.vault, active: shareableByName.get(c.vault) === true });
|
|
43193
|
+
}
|
|
43194
|
+
}
|
|
43195
|
+
sendJson(res, 200, { nodes, edges, latestVersion: latest });
|
|
43196
|
+
}
|
|
43197
|
+
async function handleLauncherConnectionCreate(req, res, _params, _contextRoot) {
|
|
43198
|
+
const body = await parseJsonBody(req);
|
|
43199
|
+
if (!body) {
|
|
43200
|
+
sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
|
|
43201
|
+
return;
|
|
43202
|
+
}
|
|
43203
|
+
const from = typeof body.from === "string" ? body.from.trim() : "";
|
|
43204
|
+
const to = typeof body.to === "string" ? body.to.trim() : "";
|
|
43205
|
+
if (!from || !to) {
|
|
43206
|
+
sendError(res, 400, "invalid_body", "from and to must be non-empty strings.");
|
|
43207
|
+
return;
|
|
43208
|
+
}
|
|
43209
|
+
const fromVault = listVaults().find((v) => v.name === from);
|
|
43210
|
+
if (!fromVault) {
|
|
43211
|
+
sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
|
|
43212
|
+
return;
|
|
43213
|
+
}
|
|
43214
|
+
const fromRoot = join59(resolve15(fromVault.path), "_dream_context");
|
|
43215
|
+
try {
|
|
43216
|
+
addConnection(fromRoot, from, to, "out", null);
|
|
43217
|
+
sendJson(res, 200, { ok: true });
|
|
43218
|
+
} catch (err) {
|
|
43219
|
+
if (err instanceof VaultError) {
|
|
43220
|
+
sendError(res, 400, "invalid_connection", err.message);
|
|
43221
|
+
return;
|
|
43222
|
+
}
|
|
43223
|
+
console.error("[launcher] connection create failed:", err);
|
|
43224
|
+
sendError(res, 500, "connection_failed", "Failed to create connection.");
|
|
43225
|
+
}
|
|
43226
|
+
}
|
|
43227
|
+
async function handleLauncherConnectionRemove(req, res, _params, _contextRoot) {
|
|
43228
|
+
const body = await parseJsonBody(req);
|
|
43229
|
+
if (!body) {
|
|
43230
|
+
sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
|
|
43231
|
+
return;
|
|
43232
|
+
}
|
|
43233
|
+
const from = typeof body.from === "string" ? body.from.trim() : "";
|
|
43234
|
+
const to = typeof body.to === "string" ? body.to.trim() : "";
|
|
43235
|
+
if (!from || !to) {
|
|
43236
|
+
sendError(res, 400, "invalid_body", "from and to must be non-empty strings.");
|
|
43237
|
+
return;
|
|
43238
|
+
}
|
|
43239
|
+
const fromVault = listVaults().find((v) => v.name === from);
|
|
43240
|
+
if (!fromVault) {
|
|
43241
|
+
sendError(res, 400, "unknown_vault", `No registered vault named "${from}".`);
|
|
43242
|
+
return;
|
|
43243
|
+
}
|
|
43244
|
+
const fromRoot = join59(resolve15(fromVault.path), "_dream_context");
|
|
43245
|
+
const removed = removeConnection(fromRoot, to);
|
|
43246
|
+
sendJson(res, 200, { ok: true, removed });
|
|
43247
|
+
}
|
|
43248
|
+
async function handleLauncherShareable(req, res, _params, _contextRoot) {
|
|
43249
|
+
const body = await parseJsonBody(req);
|
|
43250
|
+
if (!body) {
|
|
43251
|
+
sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
|
|
43252
|
+
return;
|
|
43253
|
+
}
|
|
43254
|
+
const name = typeof body.name === "string" ? body.name.trim() : "";
|
|
43255
|
+
const shareable = body.shareable === true;
|
|
43256
|
+
if (!name) {
|
|
43257
|
+
sendError(res, 400, "invalid_name", "name must be a non-empty string.");
|
|
43258
|
+
return;
|
|
43259
|
+
}
|
|
43260
|
+
const vault = listVaults().find((v) => v.name === name);
|
|
43261
|
+
if (!vault) {
|
|
43262
|
+
sendError(res, 400, "unknown_vault", `No registered vault named "${name}".`);
|
|
43263
|
+
return;
|
|
43264
|
+
}
|
|
43265
|
+
const root = resolve15(vault.path);
|
|
43266
|
+
if (!existsSync63(root)) {
|
|
43267
|
+
sendError(res, 400, "missing_vault", `Vault path no longer exists: ${root}`);
|
|
43268
|
+
return;
|
|
43269
|
+
}
|
|
43270
|
+
try {
|
|
43271
|
+
updateSetupConfig(root, { shareable });
|
|
43272
|
+
sendJson(res, 200, { ok: true, name, shareable });
|
|
43273
|
+
} catch (err) {
|
|
43274
|
+
console.error("[launcher] shareable toggle failed:", err);
|
|
43275
|
+
sendError(res, 500, "shareable_failed", "Failed to update sharing.");
|
|
43276
|
+
}
|
|
43277
|
+
}
|
|
42891
43278
|
var execFileAsync2, captureRuns, CAPTURE_RUN_TTL_MS, CAPTURE_RUNS_MAX, ScaffoldError, defaultCliRunner, SAFE_NAME_RE, SLEEPY_MODES;
|
|
42892
43279
|
var init_launcher = __esm({
|
|
42893
43280
|
"src/server/routes/launcher.ts"() {
|
|
@@ -42895,12 +43282,18 @@ var init_launcher = __esm({
|
|
|
42895
43282
|
init_middleware();
|
|
42896
43283
|
init_vault_discovery();
|
|
42897
43284
|
init_vaults();
|
|
43285
|
+
init_connections();
|
|
43286
|
+
init_setup_config();
|
|
43287
|
+
init_manifest();
|
|
43288
|
+
init_version_check();
|
|
42898
43289
|
init_tech_stack();
|
|
42899
43290
|
init_ensure_cli();
|
|
42900
43291
|
init_platforms();
|
|
42901
43292
|
init_catalog();
|
|
42902
43293
|
init_json_file();
|
|
42903
43294
|
init_id();
|
|
43295
|
+
init_sleep();
|
|
43296
|
+
init_sleep_consolidation();
|
|
42904
43297
|
execFileAsync2 = promisify2(execFile2);
|
|
42905
43298
|
captureRuns = /* @__PURE__ */ new Map();
|
|
42906
43299
|
CAPTURE_RUN_TTL_MS = 10 * 60 * 1e3;
|
|
@@ -42929,6 +43322,62 @@ var init_launcher = __esm({
|
|
|
42929
43322
|
}
|
|
42930
43323
|
});
|
|
42931
43324
|
|
|
43325
|
+
// src/server/routes/ui-settings.ts
|
|
43326
|
+
import { dirname as dirname30, join as join60 } from "path";
|
|
43327
|
+
import { existsSync as existsSync64, mkdirSync as mkdirSync26, readFileSync as readFileSync46, writeFileSync as writeFileSync33 } from "fs";
|
|
43328
|
+
function settingsPath(contextRoot) {
|
|
43329
|
+
return join60(contextRoot, BRAIN_SETTINGS_REL_PATH);
|
|
43330
|
+
}
|
|
43331
|
+
async function handleBrainSettingsGet(_req, res, _params, contextRoot) {
|
|
43332
|
+
const path2 = settingsPath(contextRoot);
|
|
43333
|
+
if (!existsSync64(path2)) {
|
|
43334
|
+
sendJson(res, 200, { settings: {} });
|
|
43335
|
+
return;
|
|
43336
|
+
}
|
|
43337
|
+
try {
|
|
43338
|
+
const raw = JSON.parse(readFileSync46(path2, "utf-8"));
|
|
43339
|
+
const settings = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
43340
|
+
sendJson(res, 200, { settings });
|
|
43341
|
+
} catch {
|
|
43342
|
+
sendJson(res, 200, { settings: {} });
|
|
43343
|
+
}
|
|
43344
|
+
}
|
|
43345
|
+
async function handleBrainSettingsPut(req, res, _params, contextRoot) {
|
|
43346
|
+
const body = await parseJsonBody(req);
|
|
43347
|
+
if (!body) {
|
|
43348
|
+
sendError(res, 400, "invalid_body", "Request body must be valid JSON.");
|
|
43349
|
+
return;
|
|
43350
|
+
}
|
|
43351
|
+
const settings = body.settings;
|
|
43352
|
+
if (settings === null || typeof settings !== "object" || Array.isArray(settings)) {
|
|
43353
|
+
sendError(res, 400, "invalid_settings", "settings must be a JSON object.");
|
|
43354
|
+
return;
|
|
43355
|
+
}
|
|
43356
|
+
const serialized = JSON.stringify(settings, null, 2);
|
|
43357
|
+
if (Buffer.byteLength(serialized, "utf-8") > MAX_BYTES) {
|
|
43358
|
+
sendError(res, 400, "too_large", "settings payload is too large.");
|
|
43359
|
+
return;
|
|
43360
|
+
}
|
|
43361
|
+
try {
|
|
43362
|
+
const path2 = settingsPath(contextRoot);
|
|
43363
|
+
mkdirSync26(dirname30(path2), { recursive: true });
|
|
43364
|
+
writeFileSync33(path2, serialized + "\n", "utf-8");
|
|
43365
|
+
sendJson(res, 200, { ok: true });
|
|
43366
|
+
} catch (err) {
|
|
43367
|
+
console.error("[ui-settings] brain-settings write failed:", err);
|
|
43368
|
+
sendError(res, 500, "write_failed", "Failed to persist brain settings.");
|
|
43369
|
+
}
|
|
43370
|
+
}
|
|
43371
|
+
var BRAIN_SETTINGS_REL_PATH, MAX_BYTES;
|
|
43372
|
+
var init_ui_settings = __esm({
|
|
43373
|
+
"src/server/routes/ui-settings.ts"() {
|
|
43374
|
+
"use strict";
|
|
43375
|
+
init_middleware();
|
|
43376
|
+
BRAIN_SETTINGS_REL_PATH = "state/.brain-settings.json";
|
|
43377
|
+
MAX_BYTES = 256 * 1024;
|
|
43378
|
+
}
|
|
43379
|
+
});
|
|
43380
|
+
|
|
42932
43381
|
// src/lib/federation-config.ts
|
|
42933
43382
|
function isShareable(projectRoot) {
|
|
42934
43383
|
const cfg = readSetupConfig(projectRoot);
|
|
@@ -42942,7 +43391,7 @@ var init_federation_config = __esm({
|
|
|
42942
43391
|
});
|
|
42943
43392
|
|
|
42944
43393
|
// src/lib/federation-recall.ts
|
|
42945
|
-
import { basename as basename19, dirname as
|
|
43394
|
+
import { basename as basename19, dirname as dirname31 } from "path";
|
|
42946
43395
|
function namespacedKey(vault, type, slug) {
|
|
42947
43396
|
return `${vault}::${type}/${slug}`;
|
|
42948
43397
|
}
|
|
@@ -42967,7 +43416,7 @@ function crossVaultRecall(query, opts) {
|
|
|
42967
43416
|
}
|
|
42968
43417
|
const isCurrent = target.current === true;
|
|
42969
43418
|
if (!isCurrent) {
|
|
42970
|
-
const projectRoot =
|
|
43419
|
+
const projectRoot = dirname31(contextRoot);
|
|
42971
43420
|
if (!isShareable(projectRoot)) continue;
|
|
42972
43421
|
}
|
|
42973
43422
|
const corpus = buildCorpus(contextRoot, opts.types ? { types: opts.types } : {}).filter((doc) => !isFederated(doc));
|
|
@@ -43040,9 +43489,9 @@ var init_federation_recall = __esm({
|
|
|
43040
43489
|
});
|
|
43041
43490
|
|
|
43042
43491
|
// src/server/routes/connections.ts
|
|
43043
|
-
import { dirname as
|
|
43492
|
+
import { dirname as dirname32 } from "path";
|
|
43044
43493
|
function currentVaultName(contextRoot) {
|
|
43045
|
-
return currentVaultTarget(
|
|
43494
|
+
return currentVaultTarget(dirname32(contextRoot)).name;
|
|
43046
43495
|
}
|
|
43047
43496
|
async function handleConnectionsList(_req, res, _params, contextRoot) {
|
|
43048
43497
|
sendJson(res, 200, { connections: listConnections(contextRoot) });
|
|
@@ -43117,8 +43566,8 @@ var init_connections2 = __esm({
|
|
|
43117
43566
|
});
|
|
43118
43567
|
|
|
43119
43568
|
// src/lib/federation-digest.ts
|
|
43120
|
-
import { existsSync as
|
|
43121
|
-
import { join as
|
|
43569
|
+
import { existsSync as existsSync65 } from "fs";
|
|
43570
|
+
import { join as join61 } from "path";
|
|
43122
43571
|
function buildInterestProfile(peerRoot, topics) {
|
|
43123
43572
|
if (topics && topics.length > 0) {
|
|
43124
43573
|
const terms2 = Array.from(new Set(tokenize(topics.join(" "))));
|
|
@@ -43137,8 +43586,8 @@ function buildInterestProfile(peerRoot, topics) {
|
|
|
43137
43586
|
return { terms, query: terms.join(" ") };
|
|
43138
43587
|
}
|
|
43139
43588
|
function activeTaskTerms(peerRoot) {
|
|
43140
|
-
const stateDir =
|
|
43141
|
-
if (!
|
|
43589
|
+
const stateDir = join61(peerRoot, "state");
|
|
43590
|
+
if (!existsSync65(stateDir)) return [];
|
|
43142
43591
|
let files;
|
|
43143
43592
|
try {
|
|
43144
43593
|
files = import_fast_glob17.default.sync("*.md", { cwd: stateDir, absolute: true });
|
|
@@ -43239,7 +43688,7 @@ var init_federation_digest = __esm({
|
|
|
43239
43688
|
});
|
|
43240
43689
|
|
|
43241
43690
|
// src/server/routes/federation.ts
|
|
43242
|
-
import { dirname as
|
|
43691
|
+
import { dirname as dirname33 } from "path";
|
|
43243
43692
|
async function handleFederationInboxGet(_req, res, _params, contextRoot) {
|
|
43244
43693
|
const { entries, quarantined } = drainInbox(contextRoot);
|
|
43245
43694
|
const pending = entries.map((e) => e.entry);
|
|
@@ -43251,7 +43700,7 @@ async function handleFederationInboxGet(_req, res, _params, contextRoot) {
|
|
|
43251
43700
|
});
|
|
43252
43701
|
}
|
|
43253
43702
|
async function handleFederationSyncPost(_req, res, _params, contextRoot) {
|
|
43254
|
-
const senderName = currentVaultTarget(
|
|
43703
|
+
const senderName = currentVaultTarget(dirname33(contextRoot)).name;
|
|
43255
43704
|
const outbound = listConnections(contextRoot).filter(
|
|
43256
43705
|
(c) => (c.direction === "out" || c.direction === "both") && c.status !== "stale"
|
|
43257
43706
|
);
|
|
@@ -43299,14 +43748,14 @@ var init_federation = __esm({
|
|
|
43299
43748
|
});
|
|
43300
43749
|
|
|
43301
43750
|
// src/server/routes/packs.ts
|
|
43302
|
-
import { dirname as
|
|
43751
|
+
import { dirname as dirname34 } from "path";
|
|
43303
43752
|
async function handlePacksGet(_req, res, _params, contextRoot) {
|
|
43304
43753
|
const loaded = loadCatalog();
|
|
43305
43754
|
if (!loaded) {
|
|
43306
43755
|
sendJson(res, 200, { packs: [], standalone: [] });
|
|
43307
43756
|
return;
|
|
43308
43757
|
}
|
|
43309
|
-
const projectRoot =
|
|
43758
|
+
const projectRoot = dirname34(contextRoot);
|
|
43310
43759
|
const packs = loaded.catalog.packs.map((p) => ({ ...p, installed: isSkillInstalled(projectRoot, p.name) }));
|
|
43311
43760
|
const standalone = loaded.catalog.standalone.map((s) => ({ ...s, installed: isSkillInstalled(projectRoot, s.name) }));
|
|
43312
43761
|
sendJson(res, 200, { packs, standalone });
|
|
@@ -43320,7 +43769,7 @@ var init_packs = __esm({
|
|
|
43320
43769
|
});
|
|
43321
43770
|
|
|
43322
43771
|
// src/server/routes/packs-install.ts
|
|
43323
|
-
import { dirname as
|
|
43772
|
+
import { dirname as dirname35 } from "path";
|
|
43324
43773
|
function validatePackName(name, contextRoot) {
|
|
43325
43774
|
if (name.includes("/") || name.includes("\0") || safeChildPath2("/x", name) === null) {
|
|
43326
43775
|
return { ok: false, status: 400, code: "invalid_name", message: "Invalid pack name." };
|
|
@@ -43333,7 +43782,7 @@ function validatePackName(name, contextRoot) {
|
|
|
43333
43782
|
if (!known) {
|
|
43334
43783
|
return { ok: false, status: 404, code: "unknown_pack", message: `Pack "${name}" not found.` };
|
|
43335
43784
|
}
|
|
43336
|
-
const projectRoot =
|
|
43785
|
+
const projectRoot = dirname35(contextRoot);
|
|
43337
43786
|
const config = readSetupConfig(projectRoot);
|
|
43338
43787
|
const platforms = normalizePlatforms(config?.platforms ?? []);
|
|
43339
43788
|
const resolved = platforms.length > 0 ? platforms : [...DEFAULT_PLATFORMS];
|
|
@@ -43406,10 +43855,10 @@ var init_packs_install = __esm({
|
|
|
43406
43855
|
});
|
|
43407
43856
|
|
|
43408
43857
|
// src/server/routes/version-check.ts
|
|
43409
|
-
import { dirname as
|
|
43858
|
+
import { dirname as dirname36 } from "path";
|
|
43410
43859
|
async function handleVersionCheckGet(_req, res, _params, contextRoot) {
|
|
43411
43860
|
try {
|
|
43412
|
-
const projectRoot =
|
|
43861
|
+
const projectRoot = dirname36(contextRoot);
|
|
43413
43862
|
const cache = readVersionCache(projectRoot);
|
|
43414
43863
|
const fresh = isCacheFresh(cache);
|
|
43415
43864
|
const installedCli = dreamcontextVersion();
|
|
@@ -43464,7 +43913,7 @@ var init_taxonomy2 = __esm({
|
|
|
43464
43913
|
|
|
43465
43914
|
// src/server/index.ts
|
|
43466
43915
|
import { createServer } from "http";
|
|
43467
|
-
import { join as
|
|
43916
|
+
import { join as join62, resolve as resolve16 } from "path";
|
|
43468
43917
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
43469
43918
|
import { exec } from "child_process";
|
|
43470
43919
|
function buildRouter() {
|
|
@@ -43510,6 +43959,13 @@ function buildRouter() {
|
|
|
43510
43959
|
router.get("/api/launcher/capture/status", handleLauncherCaptureStatus);
|
|
43511
43960
|
router.get("/api/launcher/sleepy-config", handleSleepyConfigGet);
|
|
43512
43961
|
router.post("/api/launcher/sleepy-config", handleSleepyConfigSet);
|
|
43962
|
+
router.get("/api/launcher/status", handleLauncherStatus);
|
|
43963
|
+
router.post("/api/launcher/unregister", handleLauncherUnregister);
|
|
43964
|
+
router.post("/api/launcher/update", handleLauncherUpdate);
|
|
43965
|
+
router.get("/api/launcher/federation-graph", handleLauncherFederationGraph);
|
|
43966
|
+
router.post("/api/launcher/connection", handleLauncherConnectionCreate);
|
|
43967
|
+
router.post("/api/launcher/connection/remove", handleLauncherConnectionRemove);
|
|
43968
|
+
router.post("/api/launcher/shareable", handleLauncherShareable);
|
|
43513
43969
|
router.get("/api/sleepy/video", handleSleepyVideo);
|
|
43514
43970
|
router.get("/api/sleepy/anim", handleSleepyAnim);
|
|
43515
43971
|
router.get("/api/vaults", handleVaultsGet);
|
|
@@ -43521,6 +43977,8 @@ function buildRouter() {
|
|
|
43521
43977
|
router.get("/api/packs", handlePacksGet);
|
|
43522
43978
|
router.post("/api/packs/:name/install", handlePackInstall);
|
|
43523
43979
|
router.delete("/api/packs/:name", handlePackUninstall);
|
|
43980
|
+
router.get("/api/brain-settings", handleBrainSettingsGet);
|
|
43981
|
+
router.put("/api/brain-settings", handleBrainSettingsPut);
|
|
43524
43982
|
router.get("/api/version-check", handleVersionCheckGet);
|
|
43525
43983
|
router.get("/api/taxonomy", handleTaxonomyGet);
|
|
43526
43984
|
router.get("/api/changelog", handleChangelogGet);
|
|
@@ -43542,7 +44000,7 @@ function resolveRequestVault(req) {
|
|
|
43542
44000
|
if (/[/\\:.\x00]/.test(h)) return "INVALID";
|
|
43543
44001
|
const v = listVaults().find((x) => x.name === h);
|
|
43544
44002
|
if (!v) return "INVALID";
|
|
43545
|
-
return
|
|
44003
|
+
return join62(v.path, "_dream_context");
|
|
43546
44004
|
}
|
|
43547
44005
|
function getDashboardDir() {
|
|
43548
44006
|
const __dirname8 = fileURLToPath7(new URL(".", import.meta.url));
|
|
@@ -43642,6 +44100,7 @@ var init_server = __esm({
|
|
|
43642
44100
|
init_config();
|
|
43643
44101
|
init_vaults2();
|
|
43644
44102
|
init_launcher();
|
|
44103
|
+
init_ui_settings();
|
|
43645
44104
|
init_connections2();
|
|
43646
44105
|
init_federation();
|
|
43647
44106
|
init_packs();
|
|
@@ -43833,8 +44292,8 @@ var init_trigger = __esm({
|
|
|
43833
44292
|
});
|
|
43834
44293
|
|
|
43835
44294
|
// src/lib/reflection.ts
|
|
43836
|
-
import { existsSync as
|
|
43837
|
-
import { join as
|
|
44295
|
+
import { existsSync as existsSync66, mkdirSync as mkdirSync27, writeFileSync as writeFileSync34 } from "fs";
|
|
44296
|
+
import { join as join63, dirname as dirname37 } from "path";
|
|
43838
44297
|
function buildExclusionSet(corpus, excludedExtra) {
|
|
43839
44298
|
const excluded = new Set(excludedExtra);
|
|
43840
44299
|
for (const doc of corpus) {
|
|
@@ -44010,13 +44469,13 @@ function formatReflection(result) {
|
|
|
44010
44469
|
return capToBytes(lines, MAX_REFLECTION_BYTES);
|
|
44011
44470
|
}
|
|
44012
44471
|
function reflectionPath(root) {
|
|
44013
|
-
return
|
|
44472
|
+
return join63(root, "state", ".reflection.md");
|
|
44014
44473
|
}
|
|
44015
44474
|
function writeReflection(root, md) {
|
|
44016
44475
|
const outPath = reflectionPath(root);
|
|
44017
|
-
const dir =
|
|
44018
|
-
if (!
|
|
44019
|
-
|
|
44476
|
+
const dir = dirname37(outPath);
|
|
44477
|
+
if (!existsSync66(dir)) {
|
|
44478
|
+
mkdirSync27(dir, { recursive: true });
|
|
44020
44479
|
}
|
|
44021
44480
|
const tsMatch = md.match(/Generated: ([^\n]+)/);
|
|
44022
44481
|
const generatedAt = tsMatch ? tsMatch[1].trim() : (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -44027,7 +44486,7 @@ function writeReflection(root, md) {
|
|
|
44027
44486
|
"---",
|
|
44028
44487
|
""
|
|
44029
44488
|
].join("\n");
|
|
44030
|
-
|
|
44489
|
+
writeFileSync34(outPath, frontmatter + md, "utf-8");
|
|
44031
44490
|
return outPath;
|
|
44032
44491
|
}
|
|
44033
44492
|
var MAX_REFLECTION_BYTES, DEFAULT_MIN_SESSIONS, DEFAULT_MAX_CANDIDATES, REFLECTION_NOISE;
|
|
@@ -44191,14 +44650,14 @@ var init_reflection = __esm({
|
|
|
44191
44650
|
});
|
|
44192
44651
|
|
|
44193
44652
|
// src/cli/commands/reflect.ts
|
|
44194
|
-
import { existsSync as
|
|
44195
|
-
import { join as
|
|
44653
|
+
import { existsSync as existsSync67, readFileSync as readFileSync49 } from "fs";
|
|
44654
|
+
import { join as join64 } from "path";
|
|
44196
44655
|
function buildBookmarkSessions(root) {
|
|
44197
|
-
const sleepPath =
|
|
44656
|
+
const sleepPath = join64(root, "state", ".sleep.json");
|
|
44198
44657
|
const result = /* @__PURE__ */ new Map();
|
|
44199
|
-
if (!
|
|
44658
|
+
if (!existsSync67(sleepPath)) return result;
|
|
44200
44659
|
try {
|
|
44201
|
-
const parsed = JSON.parse(
|
|
44660
|
+
const parsed = JSON.parse(readFileSync49(sleepPath, "utf-8"));
|
|
44202
44661
|
const bookmarks = parsed.bookmarks ?? [];
|
|
44203
44662
|
for (const b of bookmarks) {
|
|
44204
44663
|
if (b.id && b.session_id) {
|
|
@@ -44212,13 +44671,13 @@ function buildBookmarkSessions(root) {
|
|
|
44212
44671
|
function buildExcludedExtra(root) {
|
|
44213
44672
|
const excluded = /* @__PURE__ */ new Set();
|
|
44214
44673
|
const coreFiles = [
|
|
44215
|
-
|
|
44216
|
-
|
|
44674
|
+
join64(root, "core", "0.soul.md"),
|
|
44675
|
+
join64(root, "core", "1.user.md")
|
|
44217
44676
|
];
|
|
44218
44677
|
for (const filePath of coreFiles) {
|
|
44219
|
-
if (!
|
|
44678
|
+
if (!existsSync67(filePath)) continue;
|
|
44220
44679
|
try {
|
|
44221
|
-
const content =
|
|
44680
|
+
const content = readFileSync49(filePath, "utf-8");
|
|
44222
44681
|
for (const tok of tokenize(content)) {
|
|
44223
44682
|
excluded.add(tok);
|
|
44224
44683
|
}
|
|
@@ -44269,8 +44728,8 @@ var init_reflect = __esm({
|
|
|
44269
44728
|
});
|
|
44270
44729
|
|
|
44271
44730
|
// src/cli/commands/council.ts
|
|
44272
|
-
import { existsSync as
|
|
44273
|
-
import { join as
|
|
44731
|
+
import { existsSync as existsSync68, mkdirSync as mkdirSync28, readFileSync as readFileSync50, writeFileSync as writeFileSync35 } from "fs";
|
|
44732
|
+
import { join as join65 } from "path";
|
|
44274
44733
|
function roundRunningStatus(n) {
|
|
44275
44734
|
return `round_${n}_running`;
|
|
44276
44735
|
}
|
|
@@ -44312,12 +44771,12 @@ function registerCreate(council) {
|
|
|
44312
44771
|
}
|
|
44313
44772
|
const id = generateId("council");
|
|
44314
44773
|
const dir = getDebateDir(id);
|
|
44315
|
-
|
|
44774
|
+
mkdirSync28(dir, { recursive: true });
|
|
44316
44775
|
const template = loadTemplate("council-debate.md");
|
|
44317
44776
|
const content = template.replaceAll("{{ID}}", id).replaceAll("{{TOPIC}}", topic.replace(/"/g, '\\"')).replaceAll("{{ROUNDS}}", String(rounds)).replaceAll("{{INTERRUPT}}", opts.interrupt ? "true" : "false").replaceAll("{{DATE}}", today());
|
|
44318
|
-
|
|
44319
|
-
|
|
44320
|
-
|
|
44777
|
+
writeFileSync35(join65(dir, "debate.md"), content, "utf-8");
|
|
44778
|
+
writeFileSync35(
|
|
44779
|
+
join65(dir, "round-log.md"),
|
|
44321
44780
|
`# Round log \u2014 ${id}
|
|
44322
44781
|
|
|
44323
44782
|
(Main agent appends timeline entries here.)
|
|
@@ -44359,8 +44818,8 @@ function registerAgent(council) {
|
|
|
44359
44818
|
process.exit(1);
|
|
44360
44819
|
}
|
|
44361
44820
|
const personaDir = getPersonaDir(debateId, slug);
|
|
44362
|
-
const personaFile =
|
|
44363
|
-
if (
|
|
44821
|
+
const personaFile = join65(personaDir, "context-and-persona.md");
|
|
44822
|
+
if (existsSync68(personaFile) && !opts.force) {
|
|
44364
44823
|
error(`Persona already exists: ${slug}`, "Use --force to overwrite.");
|
|
44365
44824
|
process.exit(1);
|
|
44366
44825
|
}
|
|
@@ -44370,14 +44829,14 @@ function registerAgent(council) {
|
|
|
44370
44829
|
process.exit(1);
|
|
44371
44830
|
}
|
|
44372
44831
|
const aspects = opts.aspects ? opts.aspects.split(",").map((a) => a.trim()).filter(Boolean) : [];
|
|
44373
|
-
|
|
44832
|
+
mkdirSync28(personaDir, { recursive: true });
|
|
44374
44833
|
const template = loadTemplate("council-persona.md");
|
|
44375
44834
|
const personaContent = template.replaceAll("{{SLUG}}", slug).replaceAll("{{MODEL}}", opts.model).replaceAll("{{ASPECTS}}", JSON.stringify(aspects)).replaceAll("{{PERSONA_BODY}}", body.trim());
|
|
44376
|
-
|
|
44835
|
+
writeFileSync35(personaFile, personaContent, "utf-8");
|
|
44377
44836
|
const reportTemplate = loadTemplate("council-report.md");
|
|
44378
44837
|
const reportContent = reportTemplate.replaceAll("{{SLUG}}", slug);
|
|
44379
|
-
|
|
44380
|
-
const debateFile =
|
|
44838
|
+
writeFileSync35(join65(personaDir, "report.md"), reportContent, "utf-8");
|
|
44839
|
+
const debateFile = join65(getDebateDir(debateId), "debate.md");
|
|
44381
44840
|
const { data } = readFrontmatter(debateFile);
|
|
44382
44841
|
const personas = Array.isArray(data.personas) ? data.personas.slice() : [];
|
|
44383
44842
|
if (!personas.includes(slug)) personas.push(slug);
|
|
@@ -44406,7 +44865,7 @@ function registerRound(council) {
|
|
|
44406
44865
|
error(`Round ${n} exceeds planned rounds (${data.rounds_planned}).`);
|
|
44407
44866
|
process.exit(1);
|
|
44408
44867
|
}
|
|
44409
|
-
const debateFile =
|
|
44868
|
+
const debateFile = join65(getDebateDir(debateId), "debate.md");
|
|
44410
44869
|
const personas = data.personas ?? [];
|
|
44411
44870
|
if (personas.length === 0) {
|
|
44412
44871
|
error("No personas registered. Run `council agent create` first.");
|
|
@@ -44415,9 +44874,9 @@ function registerRound(council) {
|
|
|
44415
44874
|
const crossContextHeader = `## Round ${n} \u2014 Cross-context loaded`;
|
|
44416
44875
|
if (n >= 2) {
|
|
44417
44876
|
for (const persona of personas) {
|
|
44418
|
-
const personaFile =
|
|
44419
|
-
if (!
|
|
44420
|
-
const existing =
|
|
44877
|
+
const personaFile = join65(getPersonaDir(debateId, persona), "context-and-persona.md");
|
|
44878
|
+
if (!existsSync68(personaFile)) continue;
|
|
44879
|
+
const existing = readFileSync50(personaFile, "utf-8");
|
|
44421
44880
|
if (existing.includes(crossContextHeader)) {
|
|
44422
44881
|
continue;
|
|
44423
44882
|
}
|
|
@@ -44439,7 +44898,7 @@ _(no round ${n - 1} report submitted)_`);
|
|
|
44439
44898
|
|
|
44440
44899
|
${peerLines.join("\n\n")}`;
|
|
44441
44900
|
const updated = existing.trimEnd() + "\n\n" + newSection + "\n";
|
|
44442
|
-
|
|
44901
|
+
writeFileSync35(personaFile, updated, "utf-8");
|
|
44443
44902
|
}
|
|
44444
44903
|
}
|
|
44445
44904
|
updateFrontmatterFields(debateFile, {
|
|
@@ -44447,13 +44906,13 @@ ${peerLines.join("\n\n")}`;
|
|
|
44447
44906
|
current_round: n,
|
|
44448
44907
|
updated_at: today()
|
|
44449
44908
|
});
|
|
44450
|
-
const logFile =
|
|
44451
|
-
const logExisting =
|
|
44909
|
+
const logFile = join65(getDebateDir(debateId), "round-log.md");
|
|
44910
|
+
const logExisting = existsSync68(logFile) ? readFileSync50(logFile, "utf-8") : "";
|
|
44452
44911
|
const logEntry = `
|
|
44453
44912
|
## Round ${n} started \u2014 ${today()}
|
|
44454
44913
|
- Personas: ${formatPersonaList(personas)}
|
|
44455
44914
|
`;
|
|
44456
|
-
|
|
44915
|
+
writeFileSync35(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
|
|
44457
44916
|
upsertCouncilIndex({
|
|
44458
44917
|
id: debateId,
|
|
44459
44918
|
topic: data.topic,
|
|
@@ -44487,18 +44946,18 @@ ${peerLines.join("\n\n")}`;
|
|
|
44487
44946
|
error(`Round ${n} incomplete. Missing reports from: ${missing.join(", ")}`);
|
|
44488
44947
|
process.exit(1);
|
|
44489
44948
|
}
|
|
44490
|
-
const debateFile =
|
|
44949
|
+
const debateFile = join65(getDebateDir(debateId), "debate.md");
|
|
44491
44950
|
updateFrontmatterFields(debateFile, {
|
|
44492
44951
|
status: roundCompleteStatus(n),
|
|
44493
44952
|
updated_at: today()
|
|
44494
44953
|
});
|
|
44495
|
-
const logFile =
|
|
44496
|
-
const logExisting =
|
|
44954
|
+
const logFile = join65(getDebateDir(debateId), "round-log.md");
|
|
44955
|
+
const logExisting = existsSync68(logFile) ? readFileSync50(logFile, "utf-8") : "";
|
|
44497
44956
|
const logEntry = `
|
|
44498
44957
|
## Round ${n} complete \u2014 ${today()}
|
|
44499
44958
|
- All ${personas.length} personas submitted reports.
|
|
44500
44959
|
`;
|
|
44501
|
-
|
|
44960
|
+
writeFileSync35(logFile, logExisting.trimEnd() + "\n" + logEntry + "\n", "utf-8");
|
|
44502
44961
|
upsertCouncilIndex({
|
|
44503
44962
|
id: debateId,
|
|
44504
44963
|
topic: data.topic,
|
|
@@ -44521,8 +44980,8 @@ function registerRoundContext(council) {
|
|
|
44521
44980
|
try {
|
|
44522
44981
|
const data = readDebateFrontmatter(debateId);
|
|
44523
44982
|
ensurePersonaExists(debateId, personaSlug);
|
|
44524
|
-
const personaFile =
|
|
44525
|
-
const personaContent =
|
|
44983
|
+
const personaFile = join65(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
|
|
44984
|
+
const personaContent = readFileSync50(personaFile, "utf-8");
|
|
44526
44985
|
console.log(`# Council debate: ${data.topic}`);
|
|
44527
44986
|
console.log(`Debate ID: ${debateId}`);
|
|
44528
44987
|
console.log(`Current round: ${data.current_round}/${data.rounds_planned}`);
|
|
@@ -44531,8 +44990,8 @@ function registerRoundContext(council) {
|
|
|
44531
44990
|
console.log("---");
|
|
44532
44991
|
console.log("");
|
|
44533
44992
|
console.log(personaContent);
|
|
44534
|
-
const debateFile =
|
|
44535
|
-
const debateRaw =
|
|
44993
|
+
const debateFile = join65(getDebateDir(debateId), "debate.md");
|
|
44994
|
+
const debateRaw = readFileSync50(debateFile, "utf-8");
|
|
44536
44995
|
const questionMatch = debateRaw.match(/##\s+Question\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
|
|
44537
44996
|
const constraintsMatch = debateRaw.match(/##\s+Constraints & Known Facts\s*\n([\s\S]*?)(?=\n##\s|\Z)/);
|
|
44538
44997
|
if (questionMatch) {
|
|
@@ -44575,7 +45034,7 @@ function registerReport(council) {
|
|
|
44575
45034
|
process.exit(1);
|
|
44576
45035
|
}
|
|
44577
45036
|
for (const w of validation.warnings) warn(w);
|
|
44578
|
-
const reportFile =
|
|
45037
|
+
const reportFile = join65(getPersonaDir(debateId, personaSlug), "report.md");
|
|
44579
45038
|
const { data: reportData, content } = readFrontmatter(reportFile);
|
|
44580
45039
|
const existingRounds = parseReportRounds(content);
|
|
44581
45040
|
if (existingRounds.find((r) => r.round === round)) {
|
|
@@ -44597,7 +45056,7 @@ ${otherSerialized}
|
|
|
44597
45056
|
persona: personaSlug,
|
|
44598
45057
|
rounds_completed: Math.max(reportData.rounds_completed ?? 0, round)
|
|
44599
45058
|
}, "\n" + merged);
|
|
44600
|
-
const personaFile =
|
|
45059
|
+
const personaFile = join65(getPersonaDir(debateId, personaSlug), "context-and-persona.md");
|
|
44601
45060
|
const { data: pData } = readFrontmatter(personaFile);
|
|
44602
45061
|
updateFrontmatterFields(personaFile, {
|
|
44603
45062
|
round_entries: Math.max(pData.round_entries ?? 0, round)
|
|
@@ -44640,13 +45099,13 @@ function registerResearch(council) {
|
|
|
44640
45099
|
error("Research topic is required.");
|
|
44641
45100
|
process.exit(1);
|
|
44642
45101
|
}
|
|
44643
|
-
const researchesDir =
|
|
44644
|
-
|
|
44645
|
-
const indexPath2 =
|
|
44646
|
-
if (!
|
|
45102
|
+
const researchesDir = join65(getPersonaDir(debateId, personaSlug), "researches");
|
|
45103
|
+
mkdirSync28(researchesDir, { recursive: true });
|
|
45104
|
+
const indexPath2 = join65(researchesDir, "index.json");
|
|
45105
|
+
if (!existsSync68(indexPath2)) writeJsonArray(indexPath2, []);
|
|
44647
45106
|
const slug = slugify(topic);
|
|
44648
|
-
const file =
|
|
44649
|
-
if (
|
|
45107
|
+
const file = join65(researchesDir, `${slug}.md`);
|
|
45108
|
+
if (existsSync68(file)) {
|
|
44650
45109
|
error(`Research note already exists: ${slug}.md`);
|
|
44651
45110
|
process.exit(1);
|
|
44652
45111
|
}
|
|
@@ -44661,7 +45120,7 @@ _Added ${today()} by ${personaSlug}_
|
|
|
44661
45120
|
|
|
44662
45121
|
${body.trim()}
|
|
44663
45122
|
`;
|
|
44664
|
-
|
|
45123
|
+
writeFileSync35(file, noteContent, "utf-8");
|
|
44665
45124
|
insertToJsonArray(indexPath2, {
|
|
44666
45125
|
slug,
|
|
44667
45126
|
topic,
|
|
@@ -44676,9 +45135,9 @@ ${body.trim()}
|
|
|
44676
45135
|
research.command("list").argument("<debate_id>").argument("<persona_slug>").description("List this persona's prior research notes.").action((debateId, personaSlug) => {
|
|
44677
45136
|
try {
|
|
44678
45137
|
ensurePersonaExists(debateId, personaSlug);
|
|
44679
|
-
const researchesDir =
|
|
44680
|
-
const indexPath2 =
|
|
44681
|
-
if (!
|
|
45138
|
+
const researchesDir = join65(getPersonaDir(debateId, personaSlug), "researches");
|
|
45139
|
+
const indexPath2 = join65(researchesDir, "index.json");
|
|
45140
|
+
if (!existsSync68(indexPath2)) {
|
|
44682
45141
|
console.log(source_default.dim("(no researches)"));
|
|
44683
45142
|
return;
|
|
44684
45143
|
}
|
|
@@ -44700,7 +45159,7 @@ function registerSynthesize(council) {
|
|
|
44700
45159
|
council.command("synthesize").argument("<debate_id>").description("Mark status=synthesizing; print manifest of files synthesizer should read.").action((debateId) => {
|
|
44701
45160
|
try {
|
|
44702
45161
|
const data = readDebateFrontmatter(debateId);
|
|
44703
|
-
const debateFile =
|
|
45162
|
+
const debateFile = join65(getDebateDir(debateId), "debate.md");
|
|
44704
45163
|
updateFrontmatterFields(debateFile, {
|
|
44705
45164
|
status: "synthesizing",
|
|
44706
45165
|
updated_at: today()
|
|
@@ -44722,8 +45181,8 @@ function registerSynthesize(council) {
|
|
|
44722
45181
|
const personaDir = getPersonaDir(debateId, persona);
|
|
44723
45182
|
manifest.push(`_dream_context/council/${debateId}/${persona}/context-and-persona.md`);
|
|
44724
45183
|
manifest.push(`_dream_context/council/${debateId}/${persona}/report.md`);
|
|
44725
|
-
const researchesIndex =
|
|
44726
|
-
if (
|
|
45184
|
+
const researchesIndex = join65(personaDir, "researches", "index.json");
|
|
45185
|
+
if (existsSync68(researchesIndex)) {
|
|
44727
45186
|
manifest.push(`_dream_context/council/${debateId}/${persona}/researches/`);
|
|
44728
45187
|
}
|
|
44729
45188
|
}
|
|
@@ -44741,12 +45200,12 @@ function registerComplete(council) {
|
|
|
44741
45200
|
council.command("complete").argument("<debate_id>").description("Mark status=complete after final-report.md is written.").action((debateId) => {
|
|
44742
45201
|
try {
|
|
44743
45202
|
const data = readDebateFrontmatter(debateId);
|
|
44744
|
-
const finalReport =
|
|
44745
|
-
if (!
|
|
45203
|
+
const finalReport = join65(getDebateDir(debateId), "final-report.md");
|
|
45204
|
+
if (!existsSync68(finalReport)) {
|
|
44746
45205
|
error("final-report.md not found.", "Synthesizer must write it before calling `council complete`.");
|
|
44747
45206
|
process.exit(1);
|
|
44748
45207
|
}
|
|
44749
|
-
const debateFile =
|
|
45208
|
+
const debateFile = join65(getDebateDir(debateId), "debate.md");
|
|
44750
45209
|
updateFrontmatterFields(debateFile, {
|
|
44751
45210
|
status: "complete",
|
|
44752
45211
|
updated_at: today()
|
|
@@ -44778,8 +45237,8 @@ function registerPromote(council) {
|
|
|
44778
45237
|
error(`Cannot promote: debate status is "${data.status}", expected "complete".`);
|
|
44779
45238
|
process.exit(1);
|
|
44780
45239
|
}
|
|
44781
|
-
const finalReport =
|
|
44782
|
-
if (!
|
|
45240
|
+
const finalReport = join65(getDebateDir(debateId), "final-report.md");
|
|
45241
|
+
if (!existsSync68(finalReport)) {
|
|
44783
45242
|
error("final-report.md not found.");
|
|
44784
45243
|
process.exit(1);
|
|
44785
45244
|
}
|
|
@@ -44792,12 +45251,12 @@ function registerPromote(council) {
|
|
|
44792
45251
|
|
|
44793
45252
|
${sec.body.trim()}` : null;
|
|
44794
45253
|
}).filter(Boolean).join("\n\n");
|
|
44795
|
-
const knowledgeDir =
|
|
44796
|
-
|
|
45254
|
+
const knowledgeDir = join65(root, "knowledge");
|
|
45255
|
+
mkdirSync28(knowledgeDir, { recursive: true });
|
|
44797
45256
|
const slug = slugify(data.topic).slice(0, 80) || debateId;
|
|
44798
45257
|
const filename = `decision-${slug}.md`;
|
|
44799
|
-
const target =
|
|
44800
|
-
if (
|
|
45258
|
+
const target = join65(knowledgeDir, filename);
|
|
45259
|
+
if (existsSync68(target) && !opts.force) {
|
|
44801
45260
|
error(`Knowledge file exists: ${filename}`, "Use --force to overwrite.");
|
|
44802
45261
|
process.exit(1);
|
|
44803
45262
|
}
|
|
@@ -44821,7 +45280,7 @@ ${kept}
|
|
|
44821
45280
|
_Promoted from council debate \`${debateId}\` on ${today()}. See \`_dream_context/council/${debateId}/final-report.md\` for the full record._
|
|
44822
45281
|
`;
|
|
44823
45282
|
writeFrontmatter(target, knowledgeFrontmatter, body);
|
|
44824
|
-
updateFrontmatterFields(
|
|
45283
|
+
updateFrontmatterFields(join65(getDebateDir(debateId), "debate.md"), {
|
|
44825
45284
|
promoted_to_knowledge: `knowledge/${filename}`,
|
|
44826
45285
|
updated_at: today()
|
|
44827
45286
|
});
|
|
@@ -44883,10 +45342,10 @@ function registerShow(council) {
|
|
|
44883
45342
|
console.log(` promoted: ${data.promoted_to_knowledge ?? source_default.dim("(no)")}`);
|
|
44884
45343
|
console.log(` created: ${data.created_at}`);
|
|
44885
45344
|
console.log(` updated: ${data.updated_at}`);
|
|
44886
|
-
const logFile =
|
|
44887
|
-
if (
|
|
45345
|
+
const logFile = join65(getDebateDir(debateId), "round-log.md");
|
|
45346
|
+
if (existsSync68(logFile)) {
|
|
44888
45347
|
console.log("\n" + source_default.dim("\u2500\u2500\u2500 Round log \u2500\u2500\u2500"));
|
|
44889
|
-
console.log(
|
|
45348
|
+
console.log(readFileSync50(logFile, "utf-8"));
|
|
44890
45349
|
}
|
|
44891
45350
|
} catch (err) {
|
|
44892
45351
|
error(err.message);
|
|
@@ -45078,12 +45537,12 @@ var init_env_loader = __esm({
|
|
|
45078
45537
|
});
|
|
45079
45538
|
|
|
45080
45539
|
// src/lib/marketing/config.ts
|
|
45081
|
-
import { existsSync as
|
|
45082
|
-
import { dirname as
|
|
45540
|
+
import { existsSync as existsSync69, readFileSync as readFileSync51, writeFileSync as writeFileSync36, mkdirSync as mkdirSync29 } from "fs";
|
|
45541
|
+
import { dirname as dirname38 } from "path";
|
|
45083
45542
|
function readEnvFile() {
|
|
45084
45543
|
const path2 = MARKETING_PATHS.envFile();
|
|
45085
|
-
if (!
|
|
45086
|
-
const raw =
|
|
45544
|
+
if (!existsSync69(path2)) return {};
|
|
45545
|
+
const raw = readFileSync51(path2, "utf8");
|
|
45087
45546
|
const parsed = parseEnv(raw);
|
|
45088
45547
|
if (parsed.errors.length > 0) {
|
|
45089
45548
|
for (const e of parsed.errors) {
|
|
@@ -45127,9 +45586,9 @@ function requireEnv(keys = REQUIRED_KEYS) {
|
|
|
45127
45586
|
}
|
|
45128
45587
|
function loadConfig() {
|
|
45129
45588
|
const path2 = MARKETING_PATHS.configFile();
|
|
45130
|
-
if (!
|
|
45589
|
+
if (!existsSync69(path2)) return { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
|
|
45131
45590
|
try {
|
|
45132
|
-
const raw =
|
|
45591
|
+
const raw = readFileSync51(path2, "utf8");
|
|
45133
45592
|
const parsed = JSON.parse(raw);
|
|
45134
45593
|
return {
|
|
45135
45594
|
default_profile: parsed.default_profile ?? null,
|
|
@@ -45144,21 +45603,21 @@ function loadConfig() {
|
|
|
45144
45603
|
}
|
|
45145
45604
|
function writeConfig(cfg) {
|
|
45146
45605
|
const path2 = MARKETING_PATHS.configFile();
|
|
45147
|
-
|
|
45148
|
-
|
|
45606
|
+
mkdirSync29(dirname38(path2), { recursive: true });
|
|
45607
|
+
writeFileSync36(path2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
45149
45608
|
}
|
|
45150
45609
|
function ensureConfigFile() {
|
|
45151
45610
|
const path2 = MARKETING_PATHS.configFile();
|
|
45152
|
-
if (
|
|
45611
|
+
if (existsSync69(path2)) return loadConfig();
|
|
45153
45612
|
const cfg = { ...EMPTY_CONFIG, feature_flags: { ...EMPTY_CONFIG.feature_flags } };
|
|
45154
45613
|
writeConfig(cfg);
|
|
45155
45614
|
return cfg;
|
|
45156
45615
|
}
|
|
45157
45616
|
function ensureEnvFile() {
|
|
45158
45617
|
const path2 = MARKETING_PATHS.envFile();
|
|
45159
|
-
if (
|
|
45160
|
-
|
|
45161
|
-
|
|
45618
|
+
if (existsSync69(path2)) return;
|
|
45619
|
+
mkdirSync29(marketingRoot(), { recursive: true });
|
|
45620
|
+
writeFileSync36(path2, ENV_TEMPLATE, { encoding: "utf8", mode: 384 });
|
|
45162
45621
|
}
|
|
45163
45622
|
var DEFAULT_API_VERSION, EMPTY_CONFIG, REQUIRED_KEYS, OPTIONAL_KEYS, ENV_TEMPLATE;
|
|
45164
45623
|
var init_config2 = __esm({
|
|
@@ -45199,9 +45658,9 @@ REINFLUENCE_BIN= # optional override; default uses .venv
|
|
|
45199
45658
|
|
|
45200
45659
|
// src/lib/marketing/bootstrap.ts
|
|
45201
45660
|
import { spawn as spawn5, spawnSync as spawnSync2 } from "child_process";
|
|
45202
|
-
import { existsSync as
|
|
45661
|
+
import { existsSync as existsSync70, mkdirSync as mkdirSync30, cpSync as cpSync3 } from "fs";
|
|
45203
45662
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
45204
|
-
import { dirname as
|
|
45663
|
+
import { dirname as dirname39, resolve as resolve17, join as join66 } from "path";
|
|
45205
45664
|
function findBundledReinfluence() {
|
|
45206
45665
|
const candidates = [
|
|
45207
45666
|
// Installed npm package: dist/<chunk>.js -> ../tools/reinfluence
|
|
@@ -45211,7 +45670,7 @@ function findBundledReinfluence() {
|
|
|
45211
45670
|
resolve17(__dirname7, "..", "..", "..", "tools", "reinfluence")
|
|
45212
45671
|
];
|
|
45213
45672
|
for (const c of candidates) {
|
|
45214
|
-
if (
|
|
45673
|
+
if (existsSync70(join66(c, "__main__.py"))) return c;
|
|
45215
45674
|
}
|
|
45216
45675
|
throw new Error(
|
|
45217
45676
|
"Bundled reinfluence not found. Reinstall dreamcontext or set REINFLUENCE_BIN."
|
|
@@ -45242,18 +45701,18 @@ async function bootstrapMarketing(opts = {}) {
|
|
|
45242
45701
|
if (verbose) process.stderr.write(`[mk init] ${msg}
|
|
45243
45702
|
`);
|
|
45244
45703
|
};
|
|
45245
|
-
|
|
45704
|
+
mkdirSync30(marketingRoot(), { recursive: true });
|
|
45246
45705
|
const bundled = findBundledReinfluence();
|
|
45247
45706
|
const target = MARKETING_PATHS.reinfluenceDir();
|
|
45248
45707
|
log(`copying tools \u2192 ${target}`);
|
|
45249
|
-
|
|
45708
|
+
mkdirSync30(MARKETING_PATHS.toolsDir(), { recursive: true });
|
|
45250
45709
|
cpSync3(bundled, target, { recursive: true });
|
|
45251
45710
|
const py = findPython3();
|
|
45252
45711
|
if (!py) {
|
|
45253
45712
|
throw new Error("python3 not found on PATH. Install Python 3.10+ and retry.");
|
|
45254
45713
|
}
|
|
45255
45714
|
const venv = MARKETING_PATHS.venvDir();
|
|
45256
|
-
if (!
|
|
45715
|
+
if (!existsSync70(MARKETING_PATHS.venvPython())) {
|
|
45257
45716
|
log(`creating venv \u2192 ${venv}`);
|
|
45258
45717
|
const r2 = runBlocking(py, ["-m", "venv", venv]);
|
|
45259
45718
|
if (r2.code !== 0) {
|
|
@@ -45266,7 +45725,7 @@ async function bootstrapMarketing(opts = {}) {
|
|
|
45266
45725
|
log("upgrading pip");
|
|
45267
45726
|
let r = runBlocking(venvPy, ["-m", "pip", "install", "--upgrade", "pip", "--quiet"]);
|
|
45268
45727
|
if (r.code !== 0) log(`pip upgrade warning: ${r.stderr.trim().slice(0, 200)}`);
|
|
45269
|
-
const reqs =
|
|
45728
|
+
const reqs = join66(target, "requirements.txt");
|
|
45270
45729
|
log("installing python deps (whisper / yt-dlp / instaloader) \u2014 first run can take several minutes");
|
|
45271
45730
|
r = runBlocking(venvPy, ["-m", "pip", "install", "-r", reqs, "--quiet"]);
|
|
45272
45731
|
if (r.code !== 0) {
|
|
@@ -45276,7 +45735,7 @@ ${r.stderr.trim() || r.stdout.trim()}`);
|
|
|
45276
45735
|
let whisperPrimed = false;
|
|
45277
45736
|
if (whisperModel) {
|
|
45278
45737
|
log(`pre-pulling whisper model "${whisperModel}" into ${MARKETING_PATHS.whisperCacheDir()}`);
|
|
45279
|
-
|
|
45738
|
+
mkdirSync30(MARKETING_PATHS.whisperCacheDir(), { recursive: true });
|
|
45280
45739
|
whisperPrimed = await primeWhisper(whisperModel);
|
|
45281
45740
|
if (!whisperPrimed) log("whisper pre-pull failed (will retry on first ingest)");
|
|
45282
45741
|
}
|
|
@@ -45316,15 +45775,15 @@ function subprocessEnv() {
|
|
|
45316
45775
|
return {
|
|
45317
45776
|
...process.env,
|
|
45318
45777
|
XDG_CACHE_HOME: cache,
|
|
45319
|
-
HF_HOME:
|
|
45320
|
-
TRANSFORMERS_CACHE:
|
|
45778
|
+
HF_HOME: join66(cache, "hf"),
|
|
45779
|
+
TRANSFORMERS_CACHE: join66(cache, "hf", "transformers"),
|
|
45321
45780
|
WHISPER_CACHE_DIR: MARKETING_PATHS.whisperCacheDir(),
|
|
45322
45781
|
PYTHONUNBUFFERED: "1",
|
|
45323
45782
|
PYTHONPATH: MARKETING_PATHS.toolsDir()
|
|
45324
45783
|
};
|
|
45325
45784
|
}
|
|
45326
45785
|
function isBootstrapped() {
|
|
45327
|
-
return
|
|
45786
|
+
return existsSync70(MARKETING_PATHS.venvPython()) && existsSync70(join66(MARKETING_PATHS.reinfluenceDir(), "__main__.py"));
|
|
45328
45787
|
}
|
|
45329
45788
|
var __filename, __dirname7;
|
|
45330
45789
|
var init_bootstrap = __esm({
|
|
@@ -45332,12 +45791,12 @@ var init_bootstrap = __esm({
|
|
|
45332
45791
|
"use strict";
|
|
45333
45792
|
init_paths2();
|
|
45334
45793
|
__filename = fileURLToPath8(import.meta.url);
|
|
45335
|
-
__dirname7 =
|
|
45794
|
+
__dirname7 = dirname39(__filename);
|
|
45336
45795
|
}
|
|
45337
45796
|
});
|
|
45338
45797
|
|
|
45339
45798
|
// src/cli/commands/marketing/init.ts
|
|
45340
|
-
import { mkdirSync as
|
|
45799
|
+
import { mkdirSync as mkdirSync31 } from "fs";
|
|
45341
45800
|
function registerMarketingInit(parent) {
|
|
45342
45801
|
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) => {
|
|
45343
45802
|
try {
|
|
@@ -45348,7 +45807,7 @@ function registerMarketingInit(parent) {
|
|
|
45348
45807
|
}
|
|
45349
45808
|
console.log(header("Marketing init"));
|
|
45350
45809
|
const root = marketingRoot();
|
|
45351
|
-
|
|
45810
|
+
mkdirSync31(root, { recursive: true });
|
|
45352
45811
|
for (const dir of [
|
|
45353
45812
|
MARKETING_PATHS.cohortsDir(),
|
|
45354
45813
|
MARKETING_PATHS.campaignsDir(),
|
|
@@ -45361,7 +45820,7 @@ function registerMarketingInit(parent) {
|
|
|
45361
45820
|
MARKETING_PATHS.byIdemDir(),
|
|
45362
45821
|
MARKETING_PATHS.cacheDir()
|
|
45363
45822
|
]) {
|
|
45364
|
-
|
|
45823
|
+
mkdirSync31(dir, { recursive: true });
|
|
45365
45824
|
}
|
|
45366
45825
|
info(`folders ready under ${source_default.dim(root)}`);
|
|
45367
45826
|
ensureEnvFile();
|
|
@@ -45401,8 +45860,8 @@ var init_init2 = __esm({
|
|
|
45401
45860
|
});
|
|
45402
45861
|
|
|
45403
45862
|
// src/lib/marketing/vision.ts
|
|
45404
|
-
import { existsSync as
|
|
45405
|
-
import { dirname as
|
|
45863
|
+
import { existsSync as existsSync71, readFileSync as readFileSync52, writeFileSync as writeFileSync37 } from "fs";
|
|
45864
|
+
import { dirname as dirname40, join as join67 } from "path";
|
|
45406
45865
|
function pickVisionProvider(env2 = process.env) {
|
|
45407
45866
|
const oai = env2.OPENAI_VISION_API_KEY;
|
|
45408
45867
|
if (oai && oai.trim().length > 0) return { provider: "openai", apiKey: oai.trim() };
|
|
@@ -45441,11 +45900,11 @@ function parseLabelsFromText(text, allowlist = LABEL_ALLOWLIST) {
|
|
|
45441
45900
|
return out;
|
|
45442
45901
|
}
|
|
45443
45902
|
async function readImageAsBase64(framePath) {
|
|
45444
|
-
const buf =
|
|
45903
|
+
const buf = readFileSync52(framePath);
|
|
45445
45904
|
return buf.toString("base64");
|
|
45446
45905
|
}
|
|
45447
45906
|
async function labelHookFrame(framePath, opts) {
|
|
45448
|
-
if (!
|
|
45907
|
+
if (!existsSync71(framePath)) return [];
|
|
45449
45908
|
const fetcher = opts.fetcher ?? defaultFetcher;
|
|
45450
45909
|
const prompt = opts.promptOverride ?? PROMPT;
|
|
45451
45910
|
const b64 = await readImageAsBase64(framePath);
|
|
@@ -45495,7 +45954,7 @@ async function labelHookFrame(framePath, opts) {
|
|
|
45495
45954
|
return parseLabelsFromText(text);
|
|
45496
45955
|
}
|
|
45497
45956
|
async function runVisionPassOnPost(postJsonPath, opts = {}) {
|
|
45498
|
-
const raw =
|
|
45957
|
+
const raw = readFileSync52(postJsonPath, "utf-8");
|
|
45499
45958
|
const post = JSON.parse(raw);
|
|
45500
45959
|
const shortcode = post.shortcode ?? "?";
|
|
45501
45960
|
const provider = opts.provider && opts.apiKey ? { provider: opts.provider, apiKey: opts.apiKey } : pickVisionProvider();
|
|
@@ -45534,15 +45993,15 @@ async function runVisionPassOnPost(postJsonPath, opts = {}) {
|
|
|
45534
45993
|
post.pattern_tags = [...aggregated].sort();
|
|
45535
45994
|
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.`;
|
|
45536
45995
|
const tmp = postJsonPath + ".tmp";
|
|
45537
|
-
|
|
45996
|
+
writeFileSync37(tmp, JSON.stringify(post, null, 2) + "\n", "utf-8");
|
|
45538
45997
|
const fs = await import("fs");
|
|
45539
45998
|
fs.renameSync(tmp, postJsonPath);
|
|
45540
|
-
const mdPath =
|
|
45541
|
-
if (
|
|
45999
|
+
const mdPath = join67(dirname40(postJsonPath), `${shortcode}.md`);
|
|
46000
|
+
if (existsSync71(mdPath)) {
|
|
45542
46001
|
try {
|
|
45543
|
-
const md =
|
|
46002
|
+
const md = readFileSync52(mdPath, "utf-8");
|
|
45544
46003
|
const refreshed = updatePatternTagsInBridge(md, post.pattern_tags);
|
|
45545
|
-
|
|
46004
|
+
writeFileSync37(mdPath, refreshed, "utf-8");
|
|
45546
46005
|
} catch {
|
|
45547
46006
|
}
|
|
45548
46007
|
}
|
|
@@ -45617,8 +46076,8 @@ Example output: ["talking-head","prop-driven"]`;
|
|
|
45617
46076
|
// src/lib/marketing/competitors.ts
|
|
45618
46077
|
import { spawn as spawn6 } from "child_process";
|
|
45619
46078
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
45620
|
-
import { existsSync as
|
|
45621
|
-
import { dirname as
|
|
46079
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync32, statfsSync } from "fs";
|
|
46080
|
+
import { dirname as dirname41, join as join68, basename as basename20, extname as extname4 } from "path";
|
|
45622
46081
|
function which(cmd) {
|
|
45623
46082
|
const r = spawnSync3(process.platform === "win32" ? "where" : "which", [cmd], { encoding: "utf8" });
|
|
45624
46083
|
if (r.status === 0) return (r.stdout || "").trim().split("\n")[0] || null;
|
|
@@ -45695,8 +46154,8 @@ ${h.installHints.join("\n")}`);
|
|
|
45695
46154
|
skip_transcripts: !!opts.skipTranscripts,
|
|
45696
46155
|
skip_frames: !!opts.skipFrames
|
|
45697
46156
|
});
|
|
45698
|
-
const outDir =
|
|
45699
|
-
|
|
46157
|
+
const outDir = join68(MARKETING_PATHS.competitorsDir(), "_ingest-tmp", run2.id);
|
|
46158
|
+
mkdirSync32(outDir, { recursive: true });
|
|
45700
46159
|
const args = [
|
|
45701
46160
|
"-m",
|
|
45702
46161
|
"reinfluence",
|
|
@@ -45796,15 +46255,15 @@ stderr: ${stderrBuf.slice(0, 1e3)}`));
|
|
|
45796
46255
|
return { runId: run2.id, postsIngested, warnings, errors };
|
|
45797
46256
|
}
|
|
45798
46257
|
function persistPost(evt) {
|
|
45799
|
-
const handleDir =
|
|
45800
|
-
const postsDir =
|
|
45801
|
-
const mediaDir =
|
|
45802
|
-
|
|
45803
|
-
|
|
45804
|
-
const finalVideoPath = evt.video_path ? moveAsset(evt.video_path,
|
|
46258
|
+
const handleDir = join68(MARKETING_PATHS.competitorsDir(), evt.handle);
|
|
46259
|
+
const postsDir = join68(handleDir, "posts");
|
|
46260
|
+
const mediaDir = join68(handleDir, "_media", evt.shortcode);
|
|
46261
|
+
mkdirSync32(postsDir, { recursive: true });
|
|
46262
|
+
mkdirSync32(mediaDir, { recursive: true });
|
|
46263
|
+
const finalVideoPath = evt.video_path ? moveAsset(evt.video_path, join68(mediaDir, basename20(evt.video_path))) : null;
|
|
45805
46264
|
const finalFramePaths = [];
|
|
45806
46265
|
for (const fr of evt.frames) {
|
|
45807
|
-
const finalP = moveAsset(fr.path,
|
|
46266
|
+
const finalP = moveAsset(fr.path, join68(mediaDir, "frames", basename20(fr.path)));
|
|
45808
46267
|
finalFramePaths.push(finalP);
|
|
45809
46268
|
}
|
|
45810
46269
|
const id = `${evt.handle}__${evt.shortcode}`;
|
|
@@ -45824,14 +46283,14 @@ function persistPost(evt) {
|
|
|
45824
46283
|
ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
45825
46284
|
asset_paths: { video: finalVideoPath, frames: finalFramePaths }
|
|
45826
46285
|
};
|
|
45827
|
-
const jsonPath =
|
|
45828
|
-
const bridgePath =
|
|
46286
|
+
const jsonPath = join68(postsDir, `${evt.shortcode}.json`);
|
|
46287
|
+
const bridgePath = join68(postsDir, `${evt.shortcode}.md`);
|
|
45829
46288
|
writeJsonWithBridge(jsonPath, bridgePath, json, renderPostBridge(json));
|
|
45830
|
-
const metaPath =
|
|
45831
|
-
if (!
|
|
46289
|
+
const metaPath = join68(handleDir, "meta.json");
|
|
46290
|
+
if (!existsSync72(metaPath)) {
|
|
45832
46291
|
writeJsonWithBridge(
|
|
45833
46292
|
metaPath,
|
|
45834
|
-
|
|
46293
|
+
join68(handleDir, "meta.md"),
|
|
45835
46294
|
{ handle: evt.handle, first_seen_at: (/* @__PURE__ */ new Date()).toISOString() },
|
|
45836
46295
|
`---
|
|
45837
46296
|
id: competitor_${evt.handle}
|
|
@@ -45848,8 +46307,8 @@ First seen: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
|
45848
46307
|
return jsonPath;
|
|
45849
46308
|
}
|
|
45850
46309
|
function moveAsset(src, dest) {
|
|
45851
|
-
if (!
|
|
45852
|
-
|
|
46310
|
+
if (!existsSync72(src)) return dest;
|
|
46311
|
+
mkdirSync32(dirname41(dest), { recursive: true });
|
|
45853
46312
|
const fs = __require("fs");
|
|
45854
46313
|
try {
|
|
45855
46314
|
fs.renameSync(src, dest);
|
|
@@ -45910,8 +46369,8 @@ var init_competitors = __esm({
|
|
|
45910
46369
|
});
|
|
45911
46370
|
|
|
45912
46371
|
// src/cli/commands/marketing/competitor.ts
|
|
45913
|
-
import { existsSync as
|
|
45914
|
-
import { join as
|
|
46372
|
+
import { existsSync as existsSync73, readdirSync as readdirSync16, statSync as statSync11 } from "fs";
|
|
46373
|
+
import { join as join69 } from "path";
|
|
45915
46374
|
function registerMarketingCompetitor(parent) {
|
|
45916
46375
|
const cmd = parent.command("competitor").description("Ingest competitor IG / YouTube content (Reinfluence pipeline).");
|
|
45917
46376
|
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) => {
|
|
@@ -45961,13 +46420,13 @@ function registerMarketingCompetitor(parent) {
|
|
|
45961
46420
|
});
|
|
45962
46421
|
cmd.command("list").description("List ingested competitor handles.").action(() => {
|
|
45963
46422
|
const dir = MARKETING_PATHS.competitorsDir();
|
|
45964
|
-
if (!
|
|
46423
|
+
if (!existsSync73(dir)) {
|
|
45965
46424
|
info("No competitors ingested yet.");
|
|
45966
46425
|
return;
|
|
45967
46426
|
}
|
|
45968
46427
|
const handles = readdirSync16(dir).filter((name) => {
|
|
45969
46428
|
if (name.startsWith("_") || name.startsWith(".")) return false;
|
|
45970
|
-
const full =
|
|
46429
|
+
const full = join69(dir, name);
|
|
45971
46430
|
try {
|
|
45972
46431
|
return statSync11(full).isDirectory();
|
|
45973
46432
|
} catch {
|
|
@@ -45980,8 +46439,8 @@ function registerMarketingCompetitor(parent) {
|
|
|
45980
46439
|
}
|
|
45981
46440
|
console.log(header("Competitors"));
|
|
45982
46441
|
for (const handle of handles) {
|
|
45983
|
-
const postsDir =
|
|
45984
|
-
const postCount =
|
|
46442
|
+
const postsDir = join69(dir, handle, "posts");
|
|
46443
|
+
const postCount = existsSync73(postsDir) ? readdirSync16(postsDir).filter((f) => f.endsWith(".json")).length : 0;
|
|
45985
46444
|
console.log(` ${source_default.cyan("@" + handle)} ${source_default.dim(`${postCount} post(s)`)}`);
|
|
45986
46445
|
}
|
|
45987
46446
|
});
|
|
@@ -45994,11 +46453,11 @@ function registerMarketingCompetitor(parent) {
|
|
|
45994
46453
|
}
|
|
45995
46454
|
info(`Provider: ${provider.provider}`);
|
|
45996
46455
|
const competitorsDir = MARKETING_PATHS.competitorsDir();
|
|
45997
|
-
const handles = opts.handle ? [opts.handle] :
|
|
46456
|
+
const handles = opts.handle ? [opts.handle] : existsSync73(competitorsDir) ? readdirSync16(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(join69(competitorsDir, h)).isDirectory()) : [];
|
|
45998
46457
|
const matches = [];
|
|
45999
46458
|
for (const h of handles) {
|
|
46000
|
-
const candidate =
|
|
46001
|
-
if (
|
|
46459
|
+
const candidate = join69(competitorsDir, h, "posts", `${shortcode}.json`);
|
|
46460
|
+
if (existsSync73(candidate)) matches.push(candidate);
|
|
46002
46461
|
}
|
|
46003
46462
|
if (matches.length === 0) {
|
|
46004
46463
|
error(`No post JSON found for shortcode "${shortcode}".`);
|
|
@@ -46033,18 +46492,18 @@ function registerMarketingCompetitor(parent) {
|
|
|
46033
46492
|
process.exit(1);
|
|
46034
46493
|
}
|
|
46035
46494
|
const competitorsDir = MARKETING_PATHS.competitorsDir();
|
|
46036
|
-
if (!
|
|
46495
|
+
if (!existsSync73(competitorsDir)) {
|
|
46037
46496
|
warn("No competitors directory yet \u2014 nothing to relabel.");
|
|
46038
46497
|
return;
|
|
46039
46498
|
}
|
|
46040
|
-
const handles = readdirSync16(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(
|
|
46499
|
+
const handles = readdirSync16(competitorsDir).filter((h) => !h.startsWith("_") && statSync11(join69(competitorsDir, h)).isDirectory());
|
|
46041
46500
|
let labeled = 0;
|
|
46042
46501
|
let skipped = 0;
|
|
46043
46502
|
for (const h of handles) {
|
|
46044
|
-
const postsDir =
|
|
46045
|
-
if (!
|
|
46503
|
+
const postsDir = join69(competitorsDir, h, "posts");
|
|
46504
|
+
if (!existsSync73(postsDir)) continue;
|
|
46046
46505
|
for (const f of readdirSync16(postsDir).filter((n) => n.endsWith(".json"))) {
|
|
46047
|
-
const path2 =
|
|
46506
|
+
const path2 = join69(postsDir, f);
|
|
46048
46507
|
if (opts.dryRun) {
|
|
46049
46508
|
info(`would relabel: ${path2}`);
|
|
46050
46509
|
continue;
|
|
@@ -46091,8 +46550,8 @@ var init_competitor = __esm({
|
|
|
46091
46550
|
});
|
|
46092
46551
|
|
|
46093
46552
|
// src/lib/marketing/meta-fetch.ts
|
|
46094
|
-
import { existsSync as
|
|
46095
|
-
import { dirname as
|
|
46553
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync33, readFileSync as readFileSync53, writeFileSync as writeFileSync38, statSync as statSync12, openSync as openSync2, readSync, closeSync as closeSync2 } from "fs";
|
|
46554
|
+
import { dirname as dirname42, basename as basename21 } from "path";
|
|
46096
46555
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
46097
46556
|
function getQueue(accountId) {
|
|
46098
46557
|
let q = writeQueues.get(accountId);
|
|
@@ -46142,17 +46601,17 @@ function idemCachePath(key) {
|
|
|
46142
46601
|
}
|
|
46143
46602
|
function readIdem(key) {
|
|
46144
46603
|
const p = idemCachePath(key);
|
|
46145
|
-
if (!
|
|
46604
|
+
if (!existsSync74(p)) return null;
|
|
46146
46605
|
try {
|
|
46147
|
-
return JSON.parse(
|
|
46606
|
+
return JSON.parse(readFileSync53(p, "utf8"));
|
|
46148
46607
|
} catch {
|
|
46149
46608
|
return null;
|
|
46150
46609
|
}
|
|
46151
46610
|
}
|
|
46152
46611
|
function writeIdem(rec) {
|
|
46153
46612
|
const p = idemCachePath(rec.key);
|
|
46154
|
-
|
|
46155
|
-
|
|
46613
|
+
mkdirSync33(dirname42(p), { recursive: true });
|
|
46614
|
+
writeFileSync38(p, JSON.stringify(rec, null, 2) + "\n", "utf8");
|
|
46156
46615
|
}
|
|
46157
46616
|
function backoffMs(attempt, hintSec) {
|
|
46158
46617
|
if (hintSec != null && Number.isFinite(hintSec) && hintSec > 0) {
|
|
@@ -46420,7 +46879,7 @@ async function singleShotVideoUpload(ctx, filepath, fields) {
|
|
|
46420
46879
|
if (fields.name) form.set("name", fields.name);
|
|
46421
46880
|
if (fields.title) form.set("title", fields.title);
|
|
46422
46881
|
if (fields.description) form.set("description", fields.description);
|
|
46423
|
-
const buffer =
|
|
46882
|
+
const buffer = readFileSync53(filepath);
|
|
46424
46883
|
const blob = new Blob([new Uint8Array(buffer)], { type: "video/mp4" });
|
|
46425
46884
|
form.set("source", blob, basename21(filepath));
|
|
46426
46885
|
const resp = await fetch(url, {
|
|
@@ -46469,7 +46928,7 @@ async function uploadImageFile(ctx, filepath) {
|
|
|
46469
46928
|
return withWriteSlot(ctx.adAccountId, async () => {
|
|
46470
46929
|
const url = buildUrl(ctx, { method: "POST", path: `${ctx.adAccountId}/adimages` });
|
|
46471
46930
|
const form = new FormData();
|
|
46472
|
-
const buffer =
|
|
46931
|
+
const buffer = readFileSync53(filepath);
|
|
46473
46932
|
const blob = new Blob([new Uint8Array(buffer)], { type: "image/png" });
|
|
46474
46933
|
form.set("filename", blob, basename21(filepath));
|
|
46475
46934
|
const resp = await fetch(url, {
|
|
@@ -46888,7 +47347,7 @@ var init_account = __esm({
|
|
|
46888
47347
|
});
|
|
46889
47348
|
|
|
46890
47349
|
// src/lib/marketing/hypothesis.ts
|
|
46891
|
-
import { existsSync as
|
|
47350
|
+
import { existsSync as existsSync75, readFileSync as readFileSync54 } from "fs";
|
|
46892
47351
|
function validateHypothesis(raw, options2 = {}) {
|
|
46893
47352
|
const errors = [];
|
|
46894
47353
|
const fieldErrors = {};
|
|
@@ -46955,12 +47414,12 @@ function validateHypothesis(raw, options2 = {}) {
|
|
|
46955
47414
|
};
|
|
46956
47415
|
}
|
|
46957
47416
|
function loadHypothesisFile(path2, options2 = {}) {
|
|
46958
|
-
if (!
|
|
47417
|
+
if (!existsSync75(path2)) {
|
|
46959
47418
|
return { ok: false, errors: [`Hypothesis file not found: ${path2}`] };
|
|
46960
47419
|
}
|
|
46961
47420
|
let parsed;
|
|
46962
47421
|
try {
|
|
46963
|
-
parsed = JSON.parse(
|
|
47422
|
+
parsed = JSON.parse(readFileSync54(path2, "utf8"));
|
|
46964
47423
|
} catch (e) {
|
|
46965
47424
|
return { ok: false, errors: [`Failed to parse JSON at ${path2}: ${e.message}`] };
|
|
46966
47425
|
}
|
|
@@ -47148,8 +47607,8 @@ var init_cohort2 = __esm({
|
|
|
47148
47607
|
});
|
|
47149
47608
|
|
|
47150
47609
|
// src/lib/marketing/insights-cache.ts
|
|
47151
|
-
import { existsSync as
|
|
47152
|
-
import { join as
|
|
47610
|
+
import { existsSync as existsSync76, readFileSync as readFileSync55, mkdirSync as mkdirSync34, writeFileSync as writeFileSync39, readdirSync as readdirSync17, statSync as statSync13 } from "fs";
|
|
47611
|
+
import { join as join70 } from "path";
|
|
47153
47612
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
47154
47613
|
function snapshotFilename(entityId, pulledAt) {
|
|
47155
47614
|
const yyyy = pulledAt.getUTCFullYear();
|
|
@@ -47160,30 +47619,30 @@ function snapshotFilename(entityId, pulledAt) {
|
|
|
47160
47619
|
return `${safe}__${yyyy}-${mm}-${dd}-${hh}.json`;
|
|
47161
47620
|
}
|
|
47162
47621
|
function indexPath() {
|
|
47163
|
-
return
|
|
47622
|
+
return join70(MARKETING_PATHS.insightsDir(), "_index.json");
|
|
47164
47623
|
}
|
|
47165
47624
|
function readIndex() {
|
|
47166
47625
|
const p = indexPath();
|
|
47167
|
-
if (!
|
|
47626
|
+
if (!existsSync76(p)) return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
|
|
47168
47627
|
try {
|
|
47169
|
-
return JSON.parse(
|
|
47628
|
+
return JSON.parse(readFileSync55(p, "utf8"));
|
|
47170
47629
|
} catch {
|
|
47171
47630
|
return { latest: {}, updated_at: "1970-01-01T00:00:00Z" };
|
|
47172
47631
|
}
|
|
47173
47632
|
}
|
|
47174
47633
|
function writeIndex(idx) {
|
|
47175
47634
|
const p = indexPath();
|
|
47176
|
-
|
|
47635
|
+
mkdirSync34(MARKETING_PATHS.insightsDir(), { recursive: true });
|
|
47177
47636
|
const tmp = `${p}.tmp.${process.pid}.${randomBytes3(4).toString("hex")}`;
|
|
47178
|
-
|
|
47637
|
+
writeFileSync39(tmp, JSON.stringify(idx, null, 2) + "\n", "utf8");
|
|
47179
47638
|
__require("fs").renameSync(tmp, p);
|
|
47180
47639
|
}
|
|
47181
47640
|
function saveInsightsSnapshot(snap) {
|
|
47182
|
-
|
|
47641
|
+
mkdirSync34(MARKETING_PATHS.insightsDir(), { recursive: true });
|
|
47183
47642
|
const filename = snapshotFilename(snap.entity_id, new Date(snap.pulled_at));
|
|
47184
|
-
const fullPath =
|
|
47643
|
+
const fullPath = join70(MARKETING_PATHS.insightsDir(), filename);
|
|
47185
47644
|
const tmp = `${fullPath}.tmp.${process.pid}.${randomBytes3(4).toString("hex")}`;
|
|
47186
|
-
|
|
47645
|
+
writeFileSync39(tmp, JSON.stringify(snap, null, 2) + "\n", "utf8");
|
|
47187
47646
|
__require("fs").renameSync(tmp, fullPath);
|
|
47188
47647
|
const idx = readIndex();
|
|
47189
47648
|
idx.latest[snap.entity_id] = filename;
|
|
@@ -47195,10 +47654,10 @@ function getCachedInsights(entityId) {
|
|
|
47195
47654
|
const idx = readIndex();
|
|
47196
47655
|
const filename = idx.latest[entityId];
|
|
47197
47656
|
if (!filename) return null;
|
|
47198
|
-
const fullPath =
|
|
47199
|
-
if (!
|
|
47657
|
+
const fullPath = join70(MARKETING_PATHS.insightsDir(), filename);
|
|
47658
|
+
if (!existsSync76(fullPath)) return null;
|
|
47200
47659
|
try {
|
|
47201
|
-
const snap = JSON.parse(
|
|
47660
|
+
const snap = JSON.parse(readFileSync55(fullPath, "utf8"));
|
|
47202
47661
|
const ageMs = Date.now() - new Date(snap.pulled_at).getTime();
|
|
47203
47662
|
if (ageMs > INSIGHTS_TTL_MS) return null;
|
|
47204
47663
|
return snap;
|
|
@@ -47210,20 +47669,20 @@ function getLatestSnapshot(entityId) {
|
|
|
47210
47669
|
const idx = readIndex();
|
|
47211
47670
|
const filename = idx.latest[entityId];
|
|
47212
47671
|
if (!filename) return null;
|
|
47213
|
-
const fullPath =
|
|
47214
|
-
if (!
|
|
47672
|
+
const fullPath = join70(MARKETING_PATHS.insightsDir(), filename);
|
|
47673
|
+
if (!existsSync76(fullPath)) return null;
|
|
47215
47674
|
try {
|
|
47216
|
-
return JSON.parse(
|
|
47675
|
+
return JSON.parse(readFileSync55(fullPath, "utf8"));
|
|
47217
47676
|
} catch {
|
|
47218
47677
|
return null;
|
|
47219
47678
|
}
|
|
47220
47679
|
}
|
|
47221
47680
|
function getPriorSnapshot(entityId, beforeMs) {
|
|
47222
47681
|
const dir = MARKETING_PATHS.insightsDir();
|
|
47223
|
-
if (!
|
|
47682
|
+
if (!existsSync76(dir)) return null;
|
|
47224
47683
|
const safe = entityId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
47225
47684
|
const candidates = readdirSync17(dir).filter((f) => f.startsWith(`${safe}__`) && f.endsWith(".json")).map((f) => {
|
|
47226
|
-
const p =
|
|
47685
|
+
const p = join70(dir, f);
|
|
47227
47686
|
const stat = statSync13(p);
|
|
47228
47687
|
return { f, p, mtimeMs: stat.mtimeMs };
|
|
47229
47688
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
@@ -47231,7 +47690,7 @@ function getPriorSnapshot(entityId, beforeMs) {
|
|
|
47231
47690
|
for (const c of candidates) {
|
|
47232
47691
|
if (c.mtimeMs <= cutoff) {
|
|
47233
47692
|
try {
|
|
47234
|
-
return JSON.parse(
|
|
47693
|
+
return JSON.parse(readFileSync55(c.p, "utf8"));
|
|
47235
47694
|
} catch {
|
|
47236
47695
|
continue;
|
|
47237
47696
|
}
|
|
@@ -47867,8 +48326,8 @@ var init_kill = __esm({
|
|
|
47867
48326
|
});
|
|
47868
48327
|
|
|
47869
48328
|
// src/cli/commands/marketing/doctor.ts
|
|
47870
|
-
import { readFileSync as
|
|
47871
|
-
import { join as
|
|
48329
|
+
import { readFileSync as readFileSync56, readdirSync as readdirSync18, statSync as statSync14 } from "fs";
|
|
48330
|
+
import { join as join71 } from "path";
|
|
47872
48331
|
function registerMarketingDoctor(parent) {
|
|
47873
48332
|
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) => {
|
|
47874
48333
|
console.log(header("Marketing doctor"));
|
|
@@ -47949,7 +48408,7 @@ function scanForSecrets(root) {
|
|
|
47949
48408
|
for (const file of walkText(root)) {
|
|
47950
48409
|
let txt;
|
|
47951
48410
|
try {
|
|
47952
|
-
txt =
|
|
48411
|
+
txt = readFileSync56(file, "utf8");
|
|
47953
48412
|
} catch {
|
|
47954
48413
|
continue;
|
|
47955
48414
|
}
|
|
@@ -47976,7 +48435,7 @@ function* walkText(dir) {
|
|
|
47976
48435
|
}
|
|
47977
48436
|
for (const e of entries) {
|
|
47978
48437
|
if (e.startsWith(".") && (e === ".env" || e === ".env.local")) continue;
|
|
47979
|
-
const full =
|
|
48438
|
+
const full = join71(dir, e);
|
|
47980
48439
|
let stat;
|
|
47981
48440
|
try {
|
|
47982
48441
|
stat = statSync14(full);
|
|
@@ -48014,8 +48473,8 @@ var init_doctor2 = __esm({
|
|
|
48014
48473
|
});
|
|
48015
48474
|
|
|
48016
48475
|
// src/lib/marketing/entity-store.ts
|
|
48017
|
-
import { existsSync as
|
|
48018
|
-
import { join as
|
|
48476
|
+
import { existsSync as existsSync78, readFileSync as readFileSync57, readdirSync as readdirSync19 } from "fs";
|
|
48477
|
+
import { join as join72 } from "path";
|
|
48019
48478
|
function dirFor(kind) {
|
|
48020
48479
|
switch (kind) {
|
|
48021
48480
|
case "campaign":
|
|
@@ -48034,24 +48493,24 @@ function newEntityId(kind) {
|
|
|
48034
48493
|
}
|
|
48035
48494
|
function entityPaths(kind, id) {
|
|
48036
48495
|
const d = dirFor(kind);
|
|
48037
|
-
return { json:
|
|
48496
|
+
return { json: join72(d, `${id}.json`), md: join72(d, `${id}.md`) };
|
|
48038
48497
|
}
|
|
48039
48498
|
function loadEntity(kind, id) {
|
|
48040
48499
|
const { json } = entityPaths(kind, id);
|
|
48041
|
-
if (!
|
|
48500
|
+
if (!existsSync78(json)) return null;
|
|
48042
48501
|
try {
|
|
48043
|
-
return JSON.parse(
|
|
48502
|
+
return JSON.parse(readFileSync57(json, "utf8"));
|
|
48044
48503
|
} catch {
|
|
48045
48504
|
return null;
|
|
48046
48505
|
}
|
|
48047
48506
|
}
|
|
48048
48507
|
function listEntities(kind) {
|
|
48049
48508
|
const d = dirFor(kind);
|
|
48050
|
-
if (!
|
|
48509
|
+
if (!existsSync78(d)) return [];
|
|
48051
48510
|
const out = [];
|
|
48052
48511
|
for (const f of readdirSync19(d).filter((x) => x.endsWith(".json"))) {
|
|
48053
48512
|
try {
|
|
48054
|
-
out.push(JSON.parse(
|
|
48513
|
+
out.push(JSON.parse(readFileSync57(join72(d, f), "utf8")));
|
|
48055
48514
|
} catch {
|
|
48056
48515
|
}
|
|
48057
48516
|
}
|
|
@@ -48245,7 +48704,7 @@ var init_campaign = __esm({
|
|
|
48245
48704
|
});
|
|
48246
48705
|
|
|
48247
48706
|
// src/cli/commands/marketing/adset.ts
|
|
48248
|
-
import { existsSync as
|
|
48707
|
+
import { existsSync as existsSync79, readFileSync as readFileSync58 } from "fs";
|
|
48249
48708
|
function registerMarketingAdSet(parent) {
|
|
48250
48709
|
const cmd = parent.command("adset").description("Manage adsets.");
|
|
48251
48710
|
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) => {
|
|
@@ -48265,13 +48724,13 @@ function registerMarketingAdSet(parent) {
|
|
|
48265
48724
|
}
|
|
48266
48725
|
throw e;
|
|
48267
48726
|
}
|
|
48268
|
-
if (!
|
|
48727
|
+
if (!existsSync79(opts.targeting)) {
|
|
48269
48728
|
error(`Targeting file not found: ${opts.targeting}`);
|
|
48270
48729
|
process.exit(1);
|
|
48271
48730
|
}
|
|
48272
48731
|
let targeting;
|
|
48273
48732
|
try {
|
|
48274
|
-
targeting = JSON.parse(
|
|
48733
|
+
targeting = JSON.parse(readFileSync58(opts.targeting, "utf8"));
|
|
48275
48734
|
} catch (e) {
|
|
48276
48735
|
error(`Failed to parse targeting JSON: ${e.message}`);
|
|
48277
48736
|
process.exit(1);
|
|
@@ -48528,12 +48987,12 @@ var init_creative = __esm({
|
|
|
48528
48987
|
});
|
|
48529
48988
|
|
|
48530
48989
|
// src/cli/commands/marketing/asset.ts
|
|
48531
|
-
import { existsSync as
|
|
48990
|
+
import { existsSync as existsSync80, statSync as statSync15 } from "fs";
|
|
48532
48991
|
import { extname as extname5 } from "path";
|
|
48533
48992
|
function registerMarketingAsset(parent) {
|
|
48534
48993
|
const cmd = parent.command("asset").description("Upload creative assets to Meta.");
|
|
48535
48994
|
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) => {
|
|
48536
|
-
if (!
|
|
48995
|
+
if (!existsSync80(path2)) {
|
|
48537
48996
|
error(`File not found: ${path2}`);
|
|
48538
48997
|
process.exit(1);
|
|
48539
48998
|
}
|
|
@@ -48701,8 +49160,8 @@ var init_ad = __esm({
|
|
|
48701
49160
|
});
|
|
48702
49161
|
|
|
48703
49162
|
// src/lib/marketing/launch.ts
|
|
48704
|
-
import { existsSync as
|
|
48705
|
-
import { dirname as
|
|
49163
|
+
import { existsSync as existsSync81, readFileSync as readFileSync59, writeFileSync as writeFileSync40, mkdirSync as mkdirSync35, renameSync as renameSync8, readdirSync as readdirSync20 } from "fs";
|
|
49164
|
+
import { dirname as dirname43, join as join73, basename as basename22 } from "path";
|
|
48706
49165
|
import { randomBytes as randomBytes4 } from "crypto";
|
|
48707
49166
|
function buildLaunchSummary(cohortId) {
|
|
48708
49167
|
const cohort = loadCohort(cohortId);
|
|
@@ -48746,15 +49205,15 @@ function isoTs2() {
|
|
|
48746
49205
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
48747
49206
|
}
|
|
48748
49207
|
function atomicWriteFile3(path2, data) {
|
|
48749
|
-
|
|
49208
|
+
mkdirSync35(dirname43(path2), { recursive: true });
|
|
48750
49209
|
const tmp = `${path2}.tmp.${process.pid}.${randomBytes4(4).toString("hex")}`;
|
|
48751
|
-
|
|
49210
|
+
writeFileSync40(tmp, data, "utf8");
|
|
48752
49211
|
renameSync8(tmp, path2);
|
|
48753
49212
|
}
|
|
48754
49213
|
function readWal(path2) {
|
|
48755
|
-
if (!
|
|
49214
|
+
if (!existsSync81(path2)) return null;
|
|
48756
49215
|
try {
|
|
48757
|
-
return JSON.parse(
|
|
49216
|
+
return JSON.parse(readFileSync59(path2, "utf8"));
|
|
48758
49217
|
} catch {
|
|
48759
49218
|
return null;
|
|
48760
49219
|
}
|
|
@@ -48764,13 +49223,13 @@ function writeWal(path2, wal) {
|
|
|
48764
49223
|
}
|
|
48765
49224
|
function findWalByRunId(runId) {
|
|
48766
49225
|
const dir = MARKETING_PATHS.runsDir();
|
|
48767
|
-
if (!
|
|
49226
|
+
if (!existsSync81(dir)) return null;
|
|
48768
49227
|
for (const f of readdirSync20(dir)) {
|
|
48769
49228
|
if (!f.endsWith(".json")) continue;
|
|
48770
49229
|
if (f.startsWith("by-idem")) continue;
|
|
48771
49230
|
const stem = f.replace(/\.json$/, "");
|
|
48772
49231
|
if (stem === runId || f === runId || basename22(f, ".json") === runId) {
|
|
48773
|
-
return
|
|
49232
|
+
return join73(dir, f);
|
|
48774
49233
|
}
|
|
48775
49234
|
}
|
|
48776
49235
|
return null;
|
|
@@ -48810,7 +49269,7 @@ function createLaunchWal(args) {
|
|
|
48810
49269
|
flipped_count: 0,
|
|
48811
49270
|
error: null
|
|
48812
49271
|
};
|
|
48813
|
-
const walPath =
|
|
49272
|
+
const walPath = join73(MARKETING_PATHS.runsDir(), `${id}.json`);
|
|
48814
49273
|
writeWal(walPath, wal);
|
|
48815
49274
|
return { walPath, wal };
|
|
48816
49275
|
}
|
|
@@ -49041,7 +49500,7 @@ var init_launch2 = __esm({
|
|
|
49041
49500
|
});
|
|
49042
49501
|
|
|
49043
49502
|
// src/cli/commands/marketing/learnings.ts
|
|
49044
|
-
import { existsSync as
|
|
49503
|
+
import { existsSync as existsSync82, readFileSync as readFileSync60 } from "fs";
|
|
49045
49504
|
function registerMarketingLearnings(parent) {
|
|
49046
49505
|
const cmd = parent.command("learnings").description("Performance Monitor learnings ledger (per-day .md + index).");
|
|
49047
49506
|
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) => {
|
|
@@ -49184,8 +49643,8 @@ async function resolveBody(body, bodyFile) {
|
|
|
49184
49643
|
if (body) return body;
|
|
49185
49644
|
if (bodyFile === "-") return readStdin3();
|
|
49186
49645
|
if (bodyFile) {
|
|
49187
|
-
if (!
|
|
49188
|
-
return
|
|
49646
|
+
if (!existsSync82(bodyFile)) throw new Error(`Body file not found: ${bodyFile}`);
|
|
49647
|
+
return readFileSync60(bodyFile, "utf8");
|
|
49189
49648
|
}
|
|
49190
49649
|
return null;
|
|
49191
49650
|
}
|
|
@@ -49215,29 +49674,29 @@ var init_learnings2 = __esm({
|
|
|
49215
49674
|
|
|
49216
49675
|
// src/lib/marketing/rem-sleep.ts
|
|
49217
49676
|
import {
|
|
49218
|
-
existsSync as
|
|
49219
|
-
mkdirSync as
|
|
49220
|
-
readFileSync as
|
|
49221
|
-
writeFileSync as
|
|
49677
|
+
existsSync as existsSync83,
|
|
49678
|
+
mkdirSync as mkdirSync36,
|
|
49679
|
+
readFileSync as readFileSync61,
|
|
49680
|
+
writeFileSync as writeFileSync41,
|
|
49222
49681
|
readdirSync as readdirSync21,
|
|
49223
49682
|
statSync as statSync16,
|
|
49224
49683
|
unlinkSync as unlinkSync3,
|
|
49225
49684
|
renameSync as renameSync9
|
|
49226
49685
|
} from "fs";
|
|
49227
|
-
import { dirname as
|
|
49686
|
+
import { dirname as dirname44, join as join74 } from "path";
|
|
49228
49687
|
import { randomBytes as randomBytes5 } from "crypto";
|
|
49229
49688
|
function atomicWriteFile4(path2, data) {
|
|
49230
|
-
|
|
49689
|
+
mkdirSync36(dirname44(path2), { recursive: true });
|
|
49231
49690
|
const tmp = `${path2}.tmp.${process.pid}.${randomBytes5(4).toString("hex")}`;
|
|
49232
|
-
|
|
49691
|
+
writeFileSync41(tmp, data, "utf8");
|
|
49233
49692
|
renameSync9(tmp, path2);
|
|
49234
49693
|
}
|
|
49235
49694
|
function pruneRuns(opts = {}) {
|
|
49236
49695
|
const keepLast = opts.keepLast ?? 100;
|
|
49237
49696
|
const dir = MARKETING_PATHS.runsDir();
|
|
49238
|
-
if (!
|
|
49697
|
+
if (!existsSync83(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
|
|
49239
49698
|
const files = readdirSync21(dir).filter((f) => f.endsWith(".json")).map((f) => {
|
|
49240
|
-
const p =
|
|
49699
|
+
const p = join74(dir, f);
|
|
49241
49700
|
try {
|
|
49242
49701
|
return { f, p, mtimeMs: statSync16(p).mtimeMs };
|
|
49243
49702
|
} catch {
|
|
@@ -49271,13 +49730,13 @@ function compactInsights(opts = {}) {
|
|
|
49271
49730
|
const weeklyAfterDays = opts.weeklyAfterDays ?? 14;
|
|
49272
49731
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
49273
49732
|
const dir = MARKETING_PATHS.insightsDir();
|
|
49274
|
-
if (!
|
|
49733
|
+
if (!existsSync83(dir)) return { scanned: 0, kept: 0, deleted: 0, deletedFiles: [] };
|
|
49275
49734
|
const files = [];
|
|
49276
49735
|
for (const f of readdirSync21(dir)) {
|
|
49277
49736
|
if (!f.endsWith(".json") || f.startsWith("_")) continue;
|
|
49278
49737
|
const m = f.match(SNAP_RE);
|
|
49279
49738
|
if (!m) continue;
|
|
49280
|
-
const p =
|
|
49739
|
+
const p = join74(dir, f);
|
|
49281
49740
|
try {
|
|
49282
49741
|
const stat = statSync16(p);
|
|
49283
49742
|
files.push({ f, p, mtimeMs: stat.mtimeMs, entityId: m[1], bucket: m[2] });
|
|
@@ -49343,7 +49802,7 @@ function mergeDailyLearnings(opts = {}) {
|
|
|
49343
49802
|
const retainDays = opts.retainDays ?? 7;
|
|
49344
49803
|
const now = opts.now ?? /* @__PURE__ */ new Date();
|
|
49345
49804
|
const dir = MARKETING_PATHS.learningsDir();
|
|
49346
|
-
if (!
|
|
49805
|
+
if (!existsSync83(dir)) {
|
|
49347
49806
|
return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
|
|
49348
49807
|
}
|
|
49349
49808
|
const dayMs = 24 * 60 * 60 * 1e3;
|
|
@@ -49354,7 +49813,7 @@ function mergeDailyLearnings(opts = {}) {
|
|
|
49354
49813
|
if (!m) continue;
|
|
49355
49814
|
const date = m[1];
|
|
49356
49815
|
const dateMs = (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).getTime();
|
|
49357
|
-
if (dateMs < cutoff) candidates.push({ f, p:
|
|
49816
|
+
if (dateMs < cutoff) candidates.push({ f, p: join74(dir, f), date });
|
|
49358
49817
|
}
|
|
49359
49818
|
if (candidates.length === 0) {
|
|
49360
49819
|
return { scanned: 0, merged: 0, archivePath: null, droppedRejected: 0, mergedFiles: [] };
|
|
@@ -49368,10 +49827,10 @@ function mergeDailyLearnings(opts = {}) {
|
|
|
49368
49827
|
const mergedFiles = [];
|
|
49369
49828
|
let lastArchivePath = null;
|
|
49370
49829
|
for (const [q, list] of byQuarter) {
|
|
49371
|
-
const archivePath =
|
|
49830
|
+
const archivePath = join74(dir, `_archive-${q}.md`);
|
|
49372
49831
|
list.sort((a, b) => a.date.localeCompare(b.date));
|
|
49373
49832
|
for (const c of list) {
|
|
49374
|
-
const existingArchive =
|
|
49833
|
+
const existingArchive = existsSync83(archivePath) ? readFileSync61(archivePath, "utf8") : `# Marketing learnings archive \u2014 ${q}
|
|
49375
49834
|
`;
|
|
49376
49835
|
const dateMarker = `# Marketing learnings \u2014 ${c.date}`;
|
|
49377
49836
|
const alreadyMerged = existingArchive.includes(dateMarker);
|
|
@@ -49380,7 +49839,7 @@ function mergeDailyLearnings(opts = {}) {
|
|
|
49380
49839
|
continue;
|
|
49381
49840
|
}
|
|
49382
49841
|
if (!alreadyMerged) {
|
|
49383
|
-
const body =
|
|
49842
|
+
const body = readFileSync61(c.p, "utf8").trimEnd();
|
|
49384
49843
|
const next2 = existingArchive.trimEnd() + "\n\n" + body + "\n";
|
|
49385
49844
|
atomicWriteFile4(archivePath, next2);
|
|
49386
49845
|
}
|
|
@@ -49423,14 +49882,14 @@ function quarterKey(yyyymmdd) {
|
|
|
49423
49882
|
}
|
|
49424
49883
|
function redactRunsSweep(opts = {}) {
|
|
49425
49884
|
const dir = MARKETING_PATHS.runsDir();
|
|
49426
|
-
if (!
|
|
49885
|
+
if (!existsSync83(dir)) return { scanned: 0, rewritten: 0, rewrittenFiles: [] };
|
|
49427
49886
|
const files = readdirSync21(dir).filter((f) => f.endsWith(".json"));
|
|
49428
49887
|
const rewrittenFiles = [];
|
|
49429
49888
|
for (const f of files) {
|
|
49430
|
-
const p =
|
|
49889
|
+
const p = join74(dir, f);
|
|
49431
49890
|
let raw;
|
|
49432
49891
|
try {
|
|
49433
|
-
raw =
|
|
49892
|
+
raw = readFileSync61(p, "utf8");
|
|
49434
49893
|
} catch {
|
|
49435
49894
|
continue;
|
|
49436
49895
|
}
|
|
@@ -49452,7 +49911,7 @@ function redactRunsSweep(opts = {}) {
|
|
|
49452
49911
|
function runRemSleep(opts = {}) {
|
|
49453
49912
|
const ranAt = (opts.now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
49454
49913
|
const root = marketingRootIfExists();
|
|
49455
|
-
if (!root || !
|
|
49914
|
+
if (!root || !existsSync83(root)) {
|
|
49456
49915
|
return {
|
|
49457
49916
|
ranAt,
|
|
49458
49917
|
marketingPresent: false,
|
|
@@ -49474,7 +49933,7 @@ function runRemSleep(opts = {}) {
|
|
|
49474
49933
|
now: opts.now
|
|
49475
49934
|
});
|
|
49476
49935
|
const redaction = redactRunsSweep({ dryRun: opts.dryRun });
|
|
49477
|
-
void
|
|
49936
|
+
void mkdirSync36;
|
|
49478
49937
|
return { ranAt, marketingPresent: true, runs, insights, learnings, redaction };
|
|
49479
49938
|
}
|
|
49480
49939
|
var SNAP_RE;
|
|
@@ -49571,9 +50030,9 @@ var init_git_guard = __esm({
|
|
|
49571
50030
|
});
|
|
49572
50031
|
|
|
49573
50032
|
// src/cli/commands/marketing/hooks.ts
|
|
49574
|
-
import { existsSync as
|
|
50033
|
+
import { existsSync as existsSync84, readFileSync as readFileSync62, writeFileSync as writeFileSync42, chmodSync as chmodSync3, mkdirSync as mkdirSync37, statSync as statSync17 } from "fs";
|
|
49575
50034
|
import { execFileSync as execFileSync6 } from "child_process";
|
|
49576
|
-
import { join as
|
|
50035
|
+
import { join as join75 } from "path";
|
|
49577
50036
|
function findGitDir(cwd = process.cwd()) {
|
|
49578
50037
|
try {
|
|
49579
50038
|
const out = execFileSync6("git", ["rev-parse", "--git-dir"], {
|
|
@@ -49582,7 +50041,7 @@ function findGitDir(cwd = process.cwd()) {
|
|
|
49582
50041
|
stdio: ["ignore", "pipe", "ignore"]
|
|
49583
50042
|
}).trim();
|
|
49584
50043
|
if (!out) return null;
|
|
49585
|
-
return out.startsWith("/") ? out :
|
|
50044
|
+
return out.startsWith("/") ? out : join75(cwd, out);
|
|
49586
50045
|
} catch {
|
|
49587
50046
|
return null;
|
|
49588
50047
|
}
|
|
@@ -49613,11 +50072,11 @@ function registerMarketingHooks(parent) {
|
|
|
49613
50072
|
error("Not inside a git repository (or `git` is not on PATH).");
|
|
49614
50073
|
process.exit(1);
|
|
49615
50074
|
}
|
|
49616
|
-
const hooksDir =
|
|
49617
|
-
|
|
49618
|
-
const target =
|
|
49619
|
-
if (
|
|
49620
|
-
const existing =
|
|
50075
|
+
const hooksDir = join75(gitDir, "hooks");
|
|
50076
|
+
mkdirSync37(hooksDir, { recursive: true });
|
|
50077
|
+
const target = join75(hooksDir, "pre-commit");
|
|
50078
|
+
if (existsSync84(target)) {
|
|
50079
|
+
const existing = readFileSync62(target, "utf-8");
|
|
49621
50080
|
if (existing.includes(MANAGED_MARKER)) {
|
|
49622
50081
|
info("pre-commit hook already managed by dreamcontext \u2014 refreshing.");
|
|
49623
50082
|
} else if (!opts.force) {
|
|
@@ -49629,7 +50088,7 @@ function registerMarketingHooks(parent) {
|
|
|
49629
50088
|
warn("Overwriting existing pre-commit hook (--force).");
|
|
49630
50089
|
}
|
|
49631
50090
|
}
|
|
49632
|
-
|
|
50091
|
+
writeFileSync42(target, HOOK_LAUNCHER, "utf-8");
|
|
49633
50092
|
try {
|
|
49634
50093
|
chmodSync3(target, 493);
|
|
49635
50094
|
} catch {
|
|
@@ -49668,26 +50127,26 @@ exec dreamcontext mk hooks check-staged
|
|
|
49668
50127
|
});
|
|
49669
50128
|
|
|
49670
50129
|
// src/lib/marketing/council-personas.ts
|
|
49671
|
-
import { existsSync as
|
|
50130
|
+
import { existsSync as existsSync85, readFileSync as readFileSync63, readdirSync as readdirSync22 } from "fs";
|
|
49672
50131
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
49673
|
-
import { join as
|
|
50132
|
+
import { join as join76, dirname as dirname45 } from "path";
|
|
49674
50133
|
function findPersonasDir() {
|
|
49675
50134
|
const candidates = [
|
|
49676
50135
|
// dev: src/lib/marketing/council-personas.ts → ../../../skill-packs/...
|
|
49677
|
-
|
|
50136
|
+
join76(__dirname_local, "..", "..", "..", PERSONA_SUBPATH),
|
|
49678
50137
|
// built: dist/index.js → ./skill-packs/...
|
|
49679
|
-
|
|
50138
|
+
join76(__dirname_local, PERSONA_SUBPATH),
|
|
49680
50139
|
// tsup-bundled (deeper nesting if ever): ../skill-packs/...
|
|
49681
|
-
|
|
49682
|
-
|
|
50140
|
+
join76(__dirname_local, "..", PERSONA_SUBPATH),
|
|
50141
|
+
join76(__dirname_local, "..", "..", PERSONA_SUBPATH)
|
|
49683
50142
|
];
|
|
49684
50143
|
for (const candidate of candidates) {
|
|
49685
|
-
if (
|
|
50144
|
+
if (existsSync85(candidate)) return candidate;
|
|
49686
50145
|
}
|
|
49687
50146
|
return null;
|
|
49688
50147
|
}
|
|
49689
50148
|
function parsePersonaFile(filePath) {
|
|
49690
|
-
const raw =
|
|
50149
|
+
const raw = readFileSync63(filePath, "utf-8");
|
|
49691
50150
|
const parsed = (0, import_gray_matter5.default)(raw);
|
|
49692
50151
|
const data = parsed.data;
|
|
49693
50152
|
const slug = typeof data.slug === "string" ? data.slug.trim() : "";
|
|
@@ -49707,9 +50166,9 @@ function parsePersonaFile(filePath) {
|
|
|
49707
50166
|
}
|
|
49708
50167
|
function loadAllPersonas(personasDir) {
|
|
49709
50168
|
const dir = personasDir ?? findPersonasDir();
|
|
49710
|
-
if (!dir || !
|
|
50169
|
+
if (!dir || !existsSync85(dir)) return [];
|
|
49711
50170
|
const files = readdirSync22(dir).filter((n) => n.endsWith(".md")).sort();
|
|
49712
|
-
return files.map((name) => parsePersonaFile(
|
|
50171
|
+
return files.map((name) => parsePersonaFile(join76(dir, name)));
|
|
49713
50172
|
}
|
|
49714
50173
|
function selectPersonas(all, requested) {
|
|
49715
50174
|
if (requested.length === 0) return [...all];
|
|
@@ -49728,23 +50187,23 @@ var init_council_personas = __esm({
|
|
|
49728
50187
|
import_gray_matter5 = __toESM(require_gray_matter(), 1);
|
|
49729
50188
|
__dirname_local = (() => {
|
|
49730
50189
|
try {
|
|
49731
|
-
return
|
|
50190
|
+
return dirname45(fileURLToPath9(import.meta.url));
|
|
49732
50191
|
} catch {
|
|
49733
50192
|
return process.cwd();
|
|
49734
50193
|
}
|
|
49735
50194
|
})();
|
|
49736
50195
|
VALID_MODELS2 = /* @__PURE__ */ new Set(["opus", "sonnet", "haiku"]);
|
|
49737
|
-
PERSONA_SUBPATH =
|
|
50196
|
+
PERSONA_SUBPATH = join76("skill-packs", "meta-marketing", "council-personas");
|
|
49738
50197
|
}
|
|
49739
50198
|
});
|
|
49740
50199
|
|
|
49741
50200
|
// src/cli/commands/marketing/council.ts
|
|
49742
50201
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
49743
|
-
import { existsSync as
|
|
50202
|
+
import { existsSync as existsSync86 } from "fs";
|
|
49744
50203
|
function resolveDreamcontextEntry() {
|
|
49745
50204
|
const node = process.argv[0];
|
|
49746
50205
|
const script = process.argv[1];
|
|
49747
|
-
if (script &&
|
|
50206
|
+
if (script && existsSync86(script)) {
|
|
49748
50207
|
return { node, script };
|
|
49749
50208
|
}
|
|
49750
50209
|
return { node, script: null };
|
|
@@ -49916,8 +50375,8 @@ var init_marketing = __esm({
|
|
|
49916
50375
|
});
|
|
49917
50376
|
|
|
49918
50377
|
// src/cli/commands/memory.ts
|
|
49919
|
-
import { existsSync as
|
|
49920
|
-
import { join as
|
|
50378
|
+
import { existsSync as existsSync87, unlinkSync as unlinkSync4 } from "fs";
|
|
50379
|
+
import { join as join77, dirname as dirname46 } from "path";
|
|
49921
50380
|
function collectVault(value, previous) {
|
|
49922
50381
|
return [...previous, value];
|
|
49923
50382
|
}
|
|
@@ -49929,7 +50388,7 @@ function parseTypes(value) {
|
|
|
49929
50388
|
return filtered.length > 0 ? filtered : void 0;
|
|
49930
50389
|
}
|
|
49931
50390
|
function recallFederated(contextRoot, query, topK, types, opts) {
|
|
49932
|
-
const projectRoot =
|
|
50391
|
+
const projectRoot = dirname46(contextRoot);
|
|
49933
50392
|
const { target: currentTarget } = currentVaultTarget(projectRoot);
|
|
49934
50393
|
const byName = /* @__PURE__ */ new Map();
|
|
49935
50394
|
const add = (t) => {
|
|
@@ -50082,7 +50541,7 @@ function registerMemoryCommand(program2) {
|
|
|
50082
50541
|
const summary = opts.summary ?? (text.length > 200 ? text.slice(0, 197) + "..." : text);
|
|
50083
50542
|
const references = opts.references ? opts.references.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
50084
50543
|
const authors = opts.person ? opts.person.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
50085
|
-
const changelogPath =
|
|
50544
|
+
const changelogPath = join77(root, "core", "CHANGELOG.json");
|
|
50086
50545
|
const entry = {
|
|
50087
50546
|
date: today(),
|
|
50088
50547
|
type: opts.type ?? "note",
|
|
@@ -50100,8 +50559,8 @@ function registerMemoryCommand(program2) {
|
|
|
50100
50559
|
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(
|
|
50101
50560
|
async (slug, opts) => {
|
|
50102
50561
|
const root = ensureContextRoot();
|
|
50103
|
-
const filePath =
|
|
50104
|
-
if (!
|
|
50562
|
+
const filePath = join77(root, "knowledge", `${slug}.md`);
|
|
50563
|
+
if (!existsSync87(filePath)) {
|
|
50105
50564
|
error(`Knowledge file not found: ${slug}.md`);
|
|
50106
50565
|
return;
|
|
50107
50566
|
}
|
|
@@ -50148,8 +50607,8 @@ ${opts.append}
|
|
|
50148
50607
|
);
|
|
50149
50608
|
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) => {
|
|
50150
50609
|
const root = ensureContextRoot();
|
|
50151
|
-
const filePath =
|
|
50152
|
-
if (!
|
|
50610
|
+
const filePath = join77(root, "knowledge", `${slug}.md`);
|
|
50611
|
+
if (!existsSync87(filePath)) {
|
|
50153
50612
|
error(`Knowledge file not found: ${slug}.md`);
|
|
50154
50613
|
return;
|
|
50155
50614
|
}
|
|
@@ -50257,13 +50716,13 @@ var init_memory = __esm({
|
|
|
50257
50716
|
|
|
50258
50717
|
// src/cli/commands/upgrade.ts
|
|
50259
50718
|
import { execFileSync as execFileSync8 } from "child_process";
|
|
50260
|
-
import { dirname as
|
|
50719
|
+
import { dirname as dirname47 } from "path";
|
|
50261
50720
|
function defaultInstaller(args) {
|
|
50262
50721
|
execFileSync8("npm", args, { stdio: "inherit" });
|
|
50263
50722
|
}
|
|
50264
50723
|
function projectRootForCache() {
|
|
50265
50724
|
const contextDir = resolveContextRoot();
|
|
50266
|
-
return contextDir ?
|
|
50725
|
+
return contextDir ? dirname47(contextDir) : process.cwd();
|
|
50267
50726
|
}
|
|
50268
50727
|
function defaultLiveLatest() {
|
|
50269
50728
|
let latest = null;
|
|
@@ -50586,9 +51045,9 @@ var init_vaults3 = __esm({
|
|
|
50586
51045
|
});
|
|
50587
51046
|
|
|
50588
51047
|
// src/cli/commands/connections.ts
|
|
50589
|
-
import { dirname as
|
|
51048
|
+
import { dirname as dirname48 } from "path";
|
|
50590
51049
|
function currentVaultName2(contextRoot) {
|
|
50591
|
-
return currentVaultTarget(
|
|
51050
|
+
return currentVaultTarget(dirname48(contextRoot)).name;
|
|
50592
51051
|
}
|
|
50593
51052
|
function registerConnectionsCommand(program2) {
|
|
50594
51053
|
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) => {
|
|
@@ -50670,17 +51129,17 @@ var init_connections3 = __esm({
|
|
|
50670
51129
|
});
|
|
50671
51130
|
|
|
50672
51131
|
// src/lib/federation-ingest.ts
|
|
50673
|
-
import { existsSync as
|
|
50674
|
-
import { join as
|
|
51132
|
+
import { existsSync as existsSync88, mkdirSync as mkdirSync38 } from "fs";
|
|
51133
|
+
import { join as join78 } from "path";
|
|
50675
51134
|
function ingestEntry(contextRoot, entry) {
|
|
50676
|
-
const knowledgeDir =
|
|
50677
|
-
|
|
51135
|
+
const knowledgeDir = join78(contextRoot, "knowledge");
|
|
51136
|
+
mkdirSync38(knowledgeDir, { recursive: true });
|
|
50678
51137
|
const baseSlug = slugFromTitle(entry.title);
|
|
50679
|
-
const canonicalPath =
|
|
50680
|
-
const collided =
|
|
51138
|
+
const canonicalPath = join78(knowledgeDir, `${baseSlug}.md`);
|
|
51139
|
+
const collided = existsSync88(canonicalPath);
|
|
50681
51140
|
const slug = collided ? `${baseSlug}--from-${sanitizeVault(entry.origin.vault)}` : baseSlug;
|
|
50682
|
-
const targetPath =
|
|
50683
|
-
if (!
|
|
51141
|
+
const targetPath = join78(knowledgeDir, `${slug}.md`);
|
|
51142
|
+
if (!existsSync88(targetPath)) {
|
|
50684
51143
|
writeFrontmatter(
|
|
50685
51144
|
targetPath,
|
|
50686
51145
|
{
|
|
@@ -50756,9 +51215,9 @@ var init_federation_ingest = __esm({
|
|
|
50756
51215
|
});
|
|
50757
51216
|
|
|
50758
51217
|
// src/cli/commands/federation.ts
|
|
50759
|
-
import { dirname as
|
|
51218
|
+
import { dirname as dirname49 } from "path";
|
|
50760
51219
|
function currentVaultName3(contextRoot) {
|
|
50761
|
-
return currentVaultTarget(
|
|
51220
|
+
return currentVaultTarget(dirname49(contextRoot)).name;
|
|
50762
51221
|
}
|
|
50763
51222
|
function outboundConnections(contextRoot) {
|
|
50764
51223
|
return listConnections(contextRoot).filter(
|
|
@@ -50971,12 +51430,12 @@ var init_people = __esm({
|
|
|
50971
51430
|
});
|
|
50972
51431
|
|
|
50973
51432
|
// src/cli/commands/config.ts
|
|
50974
|
-
import { dirname as
|
|
50975
|
-
import { existsSync as
|
|
50976
|
-
import { join as
|
|
51433
|
+
import { dirname as dirname50 } from "path";
|
|
51434
|
+
import { existsSync as existsSync89, readFileSync as readFileSync65, writeFileSync as writeFileSync44 } from "fs";
|
|
51435
|
+
import { join as join79 } from "path";
|
|
50977
51436
|
function resolveProjectRoot() {
|
|
50978
51437
|
const contextRoot = resolveContextRoot();
|
|
50979
|
-
return contextRoot ?
|
|
51438
|
+
return contextRoot ? dirname50(contextRoot) : null;
|
|
50980
51439
|
}
|
|
50981
51440
|
function requireProjectRoot() {
|
|
50982
51441
|
const projectRoot = resolveProjectRoot();
|
|
@@ -51135,7 +51594,7 @@ function registerConfigCommand(program2) {
|
|
|
51135
51594
|
const liveToken = resolveClickUpToken(projectRoot);
|
|
51136
51595
|
let connected = false;
|
|
51137
51596
|
if (liveToken) {
|
|
51138
|
-
const contextRoot =
|
|
51597
|
+
const contextRoot = join79(projectRoot, "_dream_context");
|
|
51139
51598
|
const probe = createClickUpBackend(contextRoot, readSetupConfig(projectRoot));
|
|
51140
51599
|
const test = await probe.testConnection();
|
|
51141
51600
|
if (test.ok) {
|
|
@@ -51178,7 +51637,7 @@ function registerConfigCommand(program2) {
|
|
|
51178
51637
|
cfgNow = readSetupConfig(projectRoot);
|
|
51179
51638
|
}
|
|
51180
51639
|
if (connected && cfgNow?.clickup?.listId) {
|
|
51181
|
-
const contextRoot =
|
|
51640
|
+
const contextRoot = join79(projectRoot, "_dream_context");
|
|
51182
51641
|
const backend2 = createClickUpBackend(contextRoot, cfgNow);
|
|
51183
51642
|
if (await esm_default4({ message: "Create the recommended custom fields on the list (urgency, summary, RICE, \u2026)?", default: true })) {
|
|
51184
51643
|
const result = await backend2.provisionRemote();
|
|
@@ -51233,13 +51692,13 @@ function registerConfigCommand(program2) {
|
|
|
51233
51692
|
const contextRoot = resolveContextRoot();
|
|
51234
51693
|
let userMdSynced = false;
|
|
51235
51694
|
if (contextRoot) {
|
|
51236
|
-
const userMdPath =
|
|
51237
|
-
if (
|
|
51695
|
+
const userMdPath = join79(contextRoot, "core", "1.user.md");
|
|
51696
|
+
if (existsSync89(userMdPath)) {
|
|
51238
51697
|
try {
|
|
51239
|
-
const before =
|
|
51698
|
+
const before = readFileSync65(userMdPath, "utf-8");
|
|
51240
51699
|
const after = ensurePeopleSection(before, roster);
|
|
51241
51700
|
if (after !== before) {
|
|
51242
|
-
|
|
51701
|
+
writeFileSync44(userMdPath, after, "utf-8");
|
|
51243
51702
|
userMdSynced = true;
|
|
51244
51703
|
}
|
|
51245
51704
|
} catch (err) {
|
|
@@ -51283,7 +51742,7 @@ function registerConfigCommand(program2) {
|
|
|
51283
51742
|
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) => {
|
|
51284
51743
|
const projectRoot = requireProjectRoot();
|
|
51285
51744
|
if (!projectRoot) return;
|
|
51286
|
-
const contextRoot =
|
|
51745
|
+
const contextRoot = join79(projectRoot, "_dream_context");
|
|
51287
51746
|
const existing = readSetupConfig(projectRoot)?.clickup ?? {};
|
|
51288
51747
|
const ledger = new SyncLedger(contextRoot);
|
|
51289
51748
|
const changingList = !!existing.listId && existing.listId !== listId && ledger.readMap().length > 0;
|
|
@@ -51324,8 +51783,8 @@ function registerConfigCommand(program2) {
|
|
|
51324
51783
|
if (!value) {
|
|
51325
51784
|
if (!process.stdin.isTTY) {
|
|
51326
51785
|
try {
|
|
51327
|
-
const { readFileSync:
|
|
51328
|
-
value =
|
|
51786
|
+
const { readFileSync: readFileSync66 } = await import("fs");
|
|
51787
|
+
value = readFileSync66(0, "utf-8").trim();
|
|
51329
51788
|
} catch {
|
|
51330
51789
|
value = "";
|
|
51331
51790
|
}
|
|
@@ -51684,12 +52143,12 @@ var init_feedback2 = __esm({
|
|
|
51684
52143
|
});
|
|
51685
52144
|
|
|
51686
52145
|
// src/cli/commands/migrations.ts
|
|
51687
|
-
import { dirname as
|
|
52146
|
+
import { dirname as dirname51 } from "path";
|
|
51688
52147
|
function registerMigrationsCommand(program2) {
|
|
51689
52148
|
const migrations = program2.command("migrations").description("Inspect and record brain structure migrations");
|
|
51690
52149
|
migrations.command("pending").description("Print pending agent task instructions for any unfinished migrations").action(() => {
|
|
51691
52150
|
const root = ensureContextRoot();
|
|
51692
|
-
const projectRoot =
|
|
52151
|
+
const projectRoot = dirname51(root);
|
|
51693
52152
|
const config = readSetupConfig(projectRoot);
|
|
51694
52153
|
const fromVersion = config?.setupVersion ?? "0.0.0";
|
|
51695
52154
|
const toVersion = dreamcontextVersion();
|