project-athena 0.2.0 → 0.3.0
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/CHANGELOG.md +76 -0
- package/README.md +19 -11
- package/dist/activity-P4UUFHWV.js +77 -0
- package/dist/agents-3HTSQGL2.js +69 -0
- package/dist/ai-ASL4FFQ7.js +96 -0
- package/dist/analyze-F3YOILNL.js +49 -0
- package/dist/chunk-2DY4PUR4.js +465 -0
- package/dist/chunk-2R6PXY6Z.js +33 -0
- package/dist/chunk-2RS6TA3D.js +908 -0
- package/dist/chunk-32PRS2MG.js +169 -0
- package/dist/chunk-3IS2X2Z7.js +89 -0
- package/dist/chunk-65TSRDQ3.js +124 -0
- package/dist/chunk-673EPYYH.js +105 -0
- package/dist/chunk-AD4OZCU2.js +34 -0
- package/dist/chunk-CXUTYCZX.js +238 -0
- package/dist/chunk-DOQMAZL5.js +436 -0
- package/dist/chunk-EF6GHOIN.js +343 -0
- package/dist/chunk-ELKFRTZT.js +221 -0
- package/dist/chunk-EUPETUWA.js +14 -0
- package/dist/chunk-FQEGEVLY.js +38 -0
- package/dist/chunk-GHFRQAYT.js +112 -0
- package/dist/chunk-GR4DL2VM.js +47 -0
- package/dist/chunk-INT3IGMQ.js +111 -0
- package/dist/chunk-IQQBAWSM.js +90 -0
- package/dist/chunk-JCGDR4UV.js +182 -0
- package/dist/chunk-JY6BFIJJ.js +95 -0
- package/dist/chunk-KBO7XRBW.js +26 -0
- package/dist/chunk-LEMPCNAY.js +209 -0
- package/dist/chunk-LMOFZNTQ.js +379 -0
- package/dist/chunk-OLPSEQS5.js +264 -0
- package/dist/chunk-PANVPNYF.js +2892 -0
- package/dist/chunk-PDFQ5BFG.js +378 -0
- package/dist/chunk-PR53DT7I.js +179 -0
- package/dist/chunk-PVCIGUIT.js +64 -0
- package/dist/chunk-RXNRMIZP.js +390 -0
- package/dist/chunk-S7T6VX56.js +61 -0
- package/dist/chunk-SHKXELUX.js +295 -0
- package/dist/chunk-SJOOXO34.js +904 -0
- package/dist/chunk-TGJUUB44.js +399 -0
- package/dist/chunk-VSYBC3VY.js +28 -0
- package/dist/chunk-XB66PZ6Z.js +182 -0
- package/dist/chunk-XFN7UZCS.js +35 -0
- package/dist/chunk-XW3MLHI2.js +32 -0
- package/dist/chunk-Z6QWMJLK.js +124 -0
- package/dist/chunk-ZB7LC6FP.js +221 -0
- package/dist/clean-S7PKCOLM.js +23 -0
- package/dist/cli.js +18 -9795
- package/dist/context-AH5MFHRG.js +147 -0
- package/dist/doctor-RSJMLE2P.js +62 -0
- package/dist/event-TNT6CQZR.js +101 -0
- package/dist/git-hook-YZNZGAAP.js +252 -0
- package/dist/init-2V34DVRQ.js +37 -0
- package/dist/mcp-T2GRTEX5.js +255 -0
- package/dist/open-2QSZKKUG.js +1259 -0
- package/dist/program-V2USHGXN.js +148 -0
- package/dist/review-R3R2J5BJ.js +115 -0
- package/dist/rules-4FXJUCXB.js +83 -0
- package/dist/security-PI4LXCOB.js +175 -0
- package/dist/staged-check-HHIBKKMR.js +500 -0
- package/dist/status-6M73WX5I.js +75 -0
- package/dist/sync-3ZNJDSSU.js +216 -0
- package/dist/watch-USN5CQIV.js +121 -0
- package/dist/web/assets/{Editor-CL6A82dQ.js → Editor-BI56-HX5.js} +1 -1
- package/dist/web/assets/{abnfDiagram-O67JEVCF-BuFfjTfx.js → abnfDiagram-O67JEVCF-y_9px2ob.js} +1 -1
- package/dist/web/assets/architecture-7GRP2DOG-DyxkwYiW.js +1 -0
- package/dist/web/assets/{architectureDiagram-NJMV4G6O-BTsv87pA.js → architectureDiagram-NJMV4G6O-lB6fcVzU.js} +1 -1
- package/dist/web/assets/{blockDiagram-BEXU5L5S-CNXqyKIx.js → blockDiagram-BEXU5L5S-DcM5pEjM.js} +1 -1
- package/dist/web/assets/{c4Diagram-YGBWAQC7-kksFXQoJ.js → c4Diagram-YGBWAQC7-CJgqxTY2.js} +1 -1
- package/dist/web/assets/channel-BvDD7AMO.js +1 -0
- package/dist/web/assets/{chunk-3FUC2YCW-BY99XYBs.js → chunk-3FUC2YCW-B8l_VuWR.js} +1 -1
- package/dist/web/assets/{chunk-5DYCD2WN-h-PRThMP.js → chunk-5DYCD2WN-CZecgNhf.js} +1 -1
- package/dist/web/assets/{chunk-742MDFTN-BIxfyBUj.js → chunk-742MDFTN-BeZ7P5jB.js} +1 -1
- package/dist/web/assets/{chunk-7INBJB4K-DZtctDdk.js → chunk-7INBJB4K-IKy0pr5m.js} +1 -1
- package/dist/web/assets/{chunk-7M6MHVWA-BX9fUUbL.js → chunk-7M6MHVWA-Dg_QqJEX.js} +1 -1
- package/dist/web/assets/{chunk-7PRAP22T-X1s3e81n.js → chunk-7PRAP22T-DqQNS8oq.js} +1 -1
- package/dist/web/assets/{chunk-GTNCS2PH-Bh8eluU-.js → chunk-GTNCS2PH-x4sM51nJ.js} +1 -1
- package/dist/web/assets/{chunk-GWA4HPMP-D1KATAi0.js → chunk-GWA4HPMP-CE5GcwVN.js} +1 -1
- package/dist/web/assets/{chunk-MBY4JIJT-CEErv5kP.js → chunk-MBY4JIJT-DA_D1hjF.js} +1 -1
- package/dist/web/assets/{chunk-NETBCI7D-BXiH4aPa.js → chunk-NETBCI7D-CeJ3XBZ2.js} +1 -1
- package/dist/web/assets/{chunk-O7XYJQB3-Dede62yi.js → chunk-O7XYJQB3-BH2gESvO.js} +1 -1
- package/dist/web/assets/{chunk-UA2S7LBM-KZ9aWRTa.js → chunk-UA2S7LBM-BWr0xCux.js} +1 -1
- package/dist/web/assets/{chunk-WEXAMYUT-xf-3L2zU.js → chunk-WEXAMYUT-B4QwUZPM.js} +1 -1
- package/dist/web/assets/{chunk-Z7XXMR3K-DLpRdZ8n.js → chunk-Z7XXMR3K-BxcA-y5B.js} +1 -1
- package/dist/web/assets/{chunk-ZIGJFQKS-BdJ0_J-U.js → chunk-ZIGJFQKS-BZYvP63G.js} +1 -1
- package/dist/web/assets/{classDiagram-v2-NBCMYWYE-C5VzGDGq.js → classDiagram-v2-NBCMYWYE-BS3P_NXb.js} +1 -1
- package/dist/web/assets/{cynefin-OW5HDTMX-BqOgbE7U.js → cynefin-OW5HDTMX-BALD4Pve.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-VND7K2PF-CCC_feG5.js → cynefinDiagram-VND7K2PF-BM2y4W6d.js} +1 -1
- package/dist/web/assets/{dagre-6A5THRUB-SLP-94sd.js → dagre-6A5THRUB-PTfOrIdF.js} +1 -1
- package/dist/web/assets/{diagram-22UHCM2B-DpHwEBYM.js → diagram-22UHCM2B-CpXEHhUl.js} +1 -1
- package/dist/web/assets/{diagram-3UASUU5V-iGFwuMEk.js → diagram-3UASUU5V-DPHfXzr6.js} +1 -1
- package/dist/web/assets/{diagram-ATOU4E4O-Csx9hj0z.js → diagram-ATOU4E4O-DMBNXvAC.js} +1 -1
- package/dist/web/assets/{diagram-CDSNMT55-yGKrLRO5.js → diagram-CDSNMT55-CDLe1M7G.js} +1 -1
- package/dist/web/assets/{diagram-MLGK6HIB-mDpCormD.js → diagram-MLGK6HIB-D6L8oE7j.js} +1 -1
- package/dist/web/assets/{diagram-MPIPVDR6-BJHdatrF.js → diagram-MPIPVDR6-CP-S7rrQ.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-ZINNZB2B-ClJbCBBu.js → ebnfDiagram-ZINNZB2B-CkUc63TK.js} +1 -1
- package/dist/web/assets/{elk-276RUBZZ-C5tFZMYm.js → elk-276RUBZZ-C1CAJLH_.js} +1 -1
- package/dist/web/assets/{erDiagram-OPXOYQCR-u7_UFZot.js → erDiagram-OPXOYQCR-DXBnaTHm.js} +1 -1
- package/dist/web/assets/eventmodeling-NTZA5JFV-cLIzvgDp.js +1 -0
- package/dist/web/assets/flowDiagram-KWPJA3E3-D7Zq63VQ.js +1 -0
- package/dist/web/assets/{ganttDiagram-FUAMR5RP-B4hrLcLf.js → ganttDiagram-FUAMR5RP-BVm8SiGg.js} +1 -1
- package/dist/web/assets/{gitGraph-4MIJSDKK-Dxx-Bl-U.js → gitGraph-4MIJSDKK-Dm7xBrW0.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-X574FWY7-DKjDV5Kr.js → gitGraphDiagram-X574FWY7-D_PIKKhx.js} +1 -1
- package/dist/web/assets/index-CeOIBpu2.js +45 -0
- package/dist/web/assets/{info-A6RAGUB7-CgqIdgQA.js → info-A6RAGUB7-CLGrx8pn.js} +1 -1
- package/dist/web/assets/{infoDiagram-VRGFBTTK-D-qjWkwy.js → infoDiagram-VRGFBTTK-BlBjaKm7.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-OU5B5YK6-CzpqV6WN.js → ishikawaDiagram-OU5B5YK6-Kxe7GGS3.js} +1 -1
- package/dist/web/assets/{journeyDiagram-ZHPQQLJL-BBnOUDzw.js → journeyDiagram-ZHPQQLJL-wCMoHK4M.js} +1 -1
- package/dist/web/assets/{kanban-definition-PNTS6WVX-Di9sTFB1.js → kanban-definition-PNTS6WVX-BxdCz9Ko.js} +1 -1
- package/dist/web/assets/{line-B8ehGiwF.js → line-Zf11FnWF.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-DWsT24e5.js → mermaid-parser.core-BvFFklev.js} +3 -3
- package/dist/web/assets/{mermaid.core-DzYpaVzI.js → mermaid.core-Cd_Ssti9.js} +4 -4
- package/dist/web/assets/{mindmap-definition-NLK3R4M7-CxagBsH3.js → mindmap-definition-NLK3R4M7-BGPQl-GY.js} +1 -1
- package/dist/web/assets/{packet-AYTQ26CC-CmxbS0qf.js → packet-AYTQ26CC-6lI3cEX_.js} +1 -1
- package/dist/web/assets/{pegDiagram-GJSIUBJH-_3jnD3q8.js → pegDiagram-GJSIUBJH-BPIjlSAj.js} +1 -1
- package/dist/web/assets/{pie-WAS4IAKB-DppCWOqP.js → pie-WAS4IAKB-D6Dzj3Ja.js} +1 -1
- package/dist/web/assets/{pieDiagram-5QR66LMP-DTVThTqz.js → pieDiagram-5QR66LMP-DtA-vZmv.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-O4NWA36T-BJ_OFnht.js → quadrantDiagram-O4NWA36T-EettyqQn.js} +1 -1
- package/dist/web/assets/{radar-RG4KPBEZ-B6quSMjs.js → radar-RG4KPBEZ-xmRc3Dl8.js} +1 -1
- package/dist/web/assets/{railroad-74A4TZTK-CErU7RG3.js → railroad-74A4TZTK-BLB7dhOn.js} +1 -1
- package/dist/web/assets/railroad-abnf-HS5TGJTU-DBFym6g8.js +1 -0
- package/dist/web/assets/railroad-ebnf-LZEXJU2U-CkG28ig8.js +1 -0
- package/dist/web/assets/railroad-peg-WCYAUIDC-Df_Ifaad.js +1 -0
- package/dist/web/assets/{railroadDiagram-XR7U4H2S-Zu0N_D-D.js → railroadDiagram-XR7U4H2S-PBw4We6b.js} +1 -1
- package/dist/web/assets/{requirementDiagram-PLB6GJNP-Bl6CN3ul.js → requirementDiagram-PLB6GJNP-DjQpaUFA.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-IPEJSGJF-DdpKzZV8.js → sankeyDiagram-IPEJSGJF-CBW-_AoF.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-PO4LG4MO-BwUqrl9F.js → sequenceDiagram-PO4LG4MO-DEoPYqY9.js} +1 -1
- package/dist/web/assets/{stateDiagram-v2-GCMORJYK-C3vZGpAi.js → stateDiagram-v2-GCMORJYK-UZq5rPud.js} +1 -1
- package/dist/web/assets/{swimlanes-2SLR337P-BjoMa2HW.js → swimlanes-2SLR337P-CACfuXJR.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-TC7HE7FX-CDSrqdgx.js +8 -0
- package/dist/web/assets/{timeline-definition-EJHVYXUP-0apcf2l2.js → timeline-definition-EJHVYXUP-CYJl7mP-.js} +1 -1
- package/dist/web/assets/{treeView-Q6P3EWNA-BOPWzyg3.js → treeView-Q6P3EWNA-DtZ5nkPQ.js} +1 -1
- package/dist/web/assets/{treemap-WGGIJYW6-CC6rU6dD.js → treemap-WGGIJYW6-m49GDM-M.js} +1 -1
- package/dist/web/assets/{usecaseDiagram-POWQR4AR-BFclVNBG.js → usecaseDiagram-POWQR4AR-C2Vg20UK.js} +1 -1
- package/dist/web/assets/{vennDiagram-UO4OBE2U-D2XPv-zb.js → vennDiagram-UO4OBE2U-C07v5OGI.js} +1 -1
- package/dist/web/assets/{wardley-WFR3VGLG-Btz6ID8P.js → wardley-WFR3VGLG-C9Z7EZtz.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-VNRHLVJA-DFYPvGpS.js → wardleyDiagram-VNRHLVJA-DdA8CcSC.js} +1 -1
- package/dist/web/assets/{xychartDiagram-PMCCYNJV-DMkQD-sV.js → xychartDiagram-PMCCYNJV-C9EZw07b.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +5 -2
- package/dist/web/assets/architecture-7GRP2DOG-CGSEE8po.js +0 -1
- package/dist/web/assets/channel-Dneho6u-.js +0 -1
- package/dist/web/assets/eventmodeling-NTZA5JFV-CA-vzJb3.js +0 -1
- package/dist/web/assets/flowDiagram-KWPJA3E3-Ca_1cbbS.js +0 -1
- package/dist/web/assets/index-s6lwoj84.js +0 -45
- package/dist/web/assets/railroad-abnf-HS5TGJTU-CWsEvTRR.js +0 -1
- package/dist/web/assets/railroad-ebnf-LZEXJU2U-Cyq9ELNn.js +0 -1
- package/dist/web/assets/railroad-peg-WCYAUIDC-BX1hI1hV.js +0 -1
- package/dist/web/assets/swimlanesDiagram-TC7HE7FX-BGNz1HGG.js +0 -8
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
AnalysisScheduler
|
|
4
|
+
} from "./chunk-XB66PZ6Z.js";
|
|
5
|
+
import {
|
|
6
|
+
applySync,
|
|
7
|
+
needsIndexRefreshOnly
|
|
8
|
+
} from "./chunk-TGJUUB44.js";
|
|
9
|
+
import {
|
|
10
|
+
readExclude
|
|
11
|
+
} from "./chunk-PANVPNYF.js";
|
|
12
|
+
import {
|
|
13
|
+
IgnoreMatcher,
|
|
14
|
+
factsConfigHash
|
|
15
|
+
} from "./chunk-ELKFRTZT.js";
|
|
16
|
+
import {
|
|
17
|
+
git
|
|
18
|
+
} from "./chunk-OLPSEQS5.js";
|
|
19
|
+
import {
|
|
20
|
+
loadConfig
|
|
21
|
+
} from "./chunk-2DY4PUR4.js";
|
|
22
|
+
import {
|
|
23
|
+
toPosix
|
|
24
|
+
} from "./chunk-XW3MLHI2.js";
|
|
25
|
+
|
|
26
|
+
// src/services/watch.ts
|
|
27
|
+
import { promises as fs } from "fs";
|
|
28
|
+
import path from "path";
|
|
29
|
+
import { watch as chokidarWatch } from "chokidar";
|
|
30
|
+
async function gitDir(root) {
|
|
31
|
+
const r = await git(root, ["rev-parse", "--absolute-git-dir"]);
|
|
32
|
+
return r.ok ? r.stdout.trim() : null;
|
|
33
|
+
}
|
|
34
|
+
async function watchProject(root, opts) {
|
|
35
|
+
const debounceMs = opts.debounceMs ?? 1500;
|
|
36
|
+
const maxWaitMs = opts.maxWaitMs ?? 1e4;
|
|
37
|
+
const { config } = await loadConfig(root);
|
|
38
|
+
const [matcher, excludeText] = await Promise.all([IgnoreMatcher.load(root, config), readExclude(root)]);
|
|
39
|
+
const ownScheduler = !opts.scheduler;
|
|
40
|
+
const scheduler = opts.scheduler ?? new AnalysisScheduler(root);
|
|
41
|
+
let timer = null;
|
|
42
|
+
let firstChangeAt = 0;
|
|
43
|
+
let latest = null;
|
|
44
|
+
let closed = false;
|
|
45
|
+
const toRel = (abs) => toPosix(path.relative(root, abs));
|
|
46
|
+
scheduler.hooks.onStart = (run2) => {
|
|
47
|
+
if (!closed) opts.onEvent({ type: "planning", paths: run2.paths });
|
|
48
|
+
};
|
|
49
|
+
scheduler.hooks.onPlan = async (plan) => {
|
|
50
|
+
if (closed) return;
|
|
51
|
+
latest = plan;
|
|
52
|
+
if (plan.upToDate) {
|
|
53
|
+
latest = null;
|
|
54
|
+
if (needsIndexRefreshOnly(plan)) {
|
|
55
|
+
const result = await applySync(root, plan);
|
|
56
|
+
opts.onEvent({ type: "refreshed", plan, result });
|
|
57
|
+
} else {
|
|
58
|
+
opts.onEvent({ type: "plan", plan });
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (opts.autoApply && !plan.ignored) {
|
|
63
|
+
const result = await applySync(root, plan);
|
|
64
|
+
latest = null;
|
|
65
|
+
opts.onEvent({ type: "applied", plan, result });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
opts.onEvent({ type: "plan", plan });
|
|
69
|
+
};
|
|
70
|
+
const run = async () => {
|
|
71
|
+
if (closed) return null;
|
|
72
|
+
firstChangeAt = 0;
|
|
73
|
+
try {
|
|
74
|
+
return await scheduler.request({ reason: "watch", supersede: true });
|
|
75
|
+
} catch (err) {
|
|
76
|
+
if (!closed && !opts.signal?.aborted && err?.name !== "AbortError") opts.onEvent({ type: "error", error: err });
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const schedule = () => {
|
|
81
|
+
if (closed) return;
|
|
82
|
+
const now = Date.now();
|
|
83
|
+
if (!firstChangeAt) firstChangeAt = now;
|
|
84
|
+
if (timer) clearTimeout(timer);
|
|
85
|
+
const wait = Math.max(0, Math.min(debounceMs, firstChangeAt + maxWaitMs - now));
|
|
86
|
+
timer = setTimeout(() => {
|
|
87
|
+
timer = null;
|
|
88
|
+
void run();
|
|
89
|
+
}, wait);
|
|
90
|
+
};
|
|
91
|
+
const onPath = (abs) => {
|
|
92
|
+
const rel = toRel(abs);
|
|
93
|
+
if (!rel || rel.startsWith("..")) return;
|
|
94
|
+
if (rel === ".gitignore" || rel.endsWith("/.gitignore")) {
|
|
95
|
+
scheduler.setTracking(false);
|
|
96
|
+
const dir = rel === ".gitignore" ? "" : rel.slice(0, -"/.gitignore".length);
|
|
97
|
+
void fs.readFile(abs, "utf8").then((text) => matcher.setGitignore(dir, text)).catch(() => matcher.removeGitignore(dir));
|
|
98
|
+
}
|
|
99
|
+
scheduler.noteChanges([rel]);
|
|
100
|
+
opts.onEvent({ type: "changes", paths: [rel] });
|
|
101
|
+
schedule();
|
|
102
|
+
};
|
|
103
|
+
const watcher = chokidarWatch(root, {
|
|
104
|
+
ignoreInitial: true,
|
|
105
|
+
persistent: true,
|
|
106
|
+
followSymlinks: false,
|
|
107
|
+
ignored: (abs, stats) => {
|
|
108
|
+
const rel = toRel(abs);
|
|
109
|
+
if (!rel || rel === ".") return false;
|
|
110
|
+
if (rel.startsWith("..")) return true;
|
|
111
|
+
if (rel === ".git" || rel.startsWith(".git/")) return true;
|
|
112
|
+
if (stats) return matcher.ignores(rel, stats.isDirectory());
|
|
113
|
+
return matcher.ignores(rel, false) || matcher.ignores(rel, true);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
const ready = new Promise((resolve) => watcher.once("ready", () => resolve()));
|
|
117
|
+
watcher.on("add", onPath).on("change", onPath).on("unlink", onPath).on("addDir", onPath).on("unlinkDir", onPath);
|
|
118
|
+
watcher.on("error", (err) => {
|
|
119
|
+
scheduler.resetBaseline();
|
|
120
|
+
opts.onEvent({ type: "error", error: err });
|
|
121
|
+
});
|
|
122
|
+
let headWatcher = null;
|
|
123
|
+
const gd = await gitDir(root);
|
|
124
|
+
let lastHead = null;
|
|
125
|
+
if (gd) {
|
|
126
|
+
lastHead = (await git(root, ["rev-parse", "HEAD"])).stdout.trim() || null;
|
|
127
|
+
headWatcher = chokidarWatch([path.join(gd, "HEAD"), path.join(gd, "refs", "heads")], { ignoreInitial: true, persistent: true, depth: 5 });
|
|
128
|
+
headWatcher.on("all", () => {
|
|
129
|
+
void git(root, ["rev-parse", "HEAD"]).then((r) => {
|
|
130
|
+
const head = r.ok ? r.stdout.trim() : null;
|
|
131
|
+
if (head && head !== lastHead) {
|
|
132
|
+
opts.onEvent({ type: "git-head", head: { from: lastHead, to: head } });
|
|
133
|
+
lastHead = head;
|
|
134
|
+
schedule();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
headWatcher.on("error", () => {
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
await ready;
|
|
142
|
+
scheduler.setTracking(true, { configHash: factsConfigHash(config), excludeText });
|
|
143
|
+
opts.onEvent({ type: "ready" });
|
|
144
|
+
const close = async () => {
|
|
145
|
+
if (closed) return;
|
|
146
|
+
closed = true;
|
|
147
|
+
if (timer) clearTimeout(timer);
|
|
148
|
+
scheduler.setTracking(false);
|
|
149
|
+
scheduler.hooks.onStart = void 0;
|
|
150
|
+
scheduler.hooks.onPlan = void 0;
|
|
151
|
+
if (ownScheduler) scheduler.close();
|
|
152
|
+
await Promise.all([watcher.close(), headWatcher?.close()]);
|
|
153
|
+
};
|
|
154
|
+
opts.signal?.addEventListener("abort", () => void close(), { once: true });
|
|
155
|
+
return {
|
|
156
|
+
planNow: () => {
|
|
157
|
+
if (timer) clearTimeout(timer);
|
|
158
|
+
timer = null;
|
|
159
|
+
return run();
|
|
160
|
+
},
|
|
161
|
+
latestPlan: () => latest,
|
|
162
|
+
close
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export {
|
|
167
|
+
watchProject
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=chunk-32PRS2MG.js.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/core/knowledge/rules.ts
|
|
4
|
+
var RULE_RE = /^([-*+])\s+(?:\[(disabled)\]\s+)?(.+?)\s*$/;
|
|
5
|
+
var SECTION_RE = /^##\s+(.+?)\s*#*\s*$/;
|
|
6
|
+
var DISABLED_PREFIX = "[disabled]";
|
|
7
|
+
function parseRules(text) {
|
|
8
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
9
|
+
const lines = [];
|
|
10
|
+
let section = "General";
|
|
11
|
+
let inFence = false;
|
|
12
|
+
const raw = text.split(/\r?\n/);
|
|
13
|
+
if (raw.length && raw[raw.length - 1] === "") raw.pop();
|
|
14
|
+
for (const l of raw) {
|
|
15
|
+
if (/^\s*(```|~~~)/.test(l)) inFence = !inFence;
|
|
16
|
+
const sm = !inFence ? SECTION_RE.exec(l) : null;
|
|
17
|
+
if (sm) section = sm[1];
|
|
18
|
+
const rm = !inFence ? RULE_RE.exec(l) : null;
|
|
19
|
+
if (rm && !/^\[[ xX]\]/.test(rm[3])) {
|
|
20
|
+
lines.push({ kind: "rule", section, text: rm[3], enabled: rm[2] !== "disabled", bullet: rm[1] });
|
|
21
|
+
} else {
|
|
22
|
+
lines.push({ kind: "other", raw: l });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return { lines, eol };
|
|
26
|
+
}
|
|
27
|
+
function serializeRules(doc) {
|
|
28
|
+
return doc.lines.map((l) => l.kind === "other" ? l.raw : `${l.bullet} ${l.enabled ? "" : `${DISABLED_PREFIX} `}${l.text}`).join(doc.eol) + doc.eol;
|
|
29
|
+
}
|
|
30
|
+
function listRules(doc) {
|
|
31
|
+
const out = [];
|
|
32
|
+
for (const l of doc.lines) if (l.kind === "rule") out.push({ index: out.length + 1, section: l.section, text: l.text, enabled: l.enabled });
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function ruleAt(doc, index) {
|
|
36
|
+
let n = 0;
|
|
37
|
+
for (const l of doc.lines) if (l.kind === "rule" && ++n === index) return l;
|
|
38
|
+
throw new RangeError(`No rule #${index} (there are ${n} rules)`);
|
|
39
|
+
}
|
|
40
|
+
function validateRuleText(text) {
|
|
41
|
+
const t = text.replace(/[\r\n]+/g, " ").trim();
|
|
42
|
+
if (!t) throw new Error("Rule text cannot be empty");
|
|
43
|
+
if (t.length > 1e3) throw new Error("Rule text is too long (max 1000 characters)");
|
|
44
|
+
return t;
|
|
45
|
+
}
|
|
46
|
+
function addRule(doc, section, text) {
|
|
47
|
+
const clean = validateRuleText(text);
|
|
48
|
+
const sec = section.replace(/[\r\n#]+/g, " ").trim() || "General";
|
|
49
|
+
const lines = [...doc.lines];
|
|
50
|
+
let lastRuleIdx = -1;
|
|
51
|
+
let headingIdx = -1;
|
|
52
|
+
lines.forEach((l, i) => {
|
|
53
|
+
if (l.kind === "other" && SECTION_RE.exec(l.raw)?.[1]?.toLowerCase() === sec.toLowerCase()) headingIdx = i;
|
|
54
|
+
if (l.kind === "rule" && l.section.toLowerCase() === sec.toLowerCase()) lastRuleIdx = i;
|
|
55
|
+
});
|
|
56
|
+
const existingSection = headingIdx >= 0 ? SECTION_RE.exec(lines[headingIdx].raw)?.[1] ?? sec : sec;
|
|
57
|
+
const rule = { kind: "rule", section: existingSection, text: clean, enabled: true, bullet: "-" };
|
|
58
|
+
if (lastRuleIdx >= 0) lines.splice(lastRuleIdx + 1, 0, rule);
|
|
59
|
+
else if (headingIdx >= 0) {
|
|
60
|
+
let at = headingIdx + 1;
|
|
61
|
+
while (at < lines.length && lines[at].kind === "other" && lines[at].raw.trim() === "") at++;
|
|
62
|
+
lines.splice(at, 0, rule);
|
|
63
|
+
} else {
|
|
64
|
+
while (lines.length && lines[lines.length - 1].kind === "other" && lines[lines.length - 1].raw.trim() === "") lines.pop();
|
|
65
|
+
lines.push({ kind: "other", raw: "" }, { kind: "other", raw: `## ${sec}` }, { kind: "other", raw: "" }, rule);
|
|
66
|
+
}
|
|
67
|
+
return { ...doc, lines };
|
|
68
|
+
}
|
|
69
|
+
function updateRule(doc, index, patch) {
|
|
70
|
+
const target = ruleAt(doc, index);
|
|
71
|
+
return {
|
|
72
|
+
...doc,
|
|
73
|
+
lines: doc.lines.map((l) => l === target ? { ...target, ...patch.text !== void 0 ? { text: validateRuleText(patch.text) } : {}, ...patch.enabled !== void 0 ? { enabled: patch.enabled } : {} } : l)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function removeRule(doc, index) {
|
|
77
|
+
const target = ruleAt(doc, index);
|
|
78
|
+
return { ...doc, lines: doc.lines.filter((l) => l !== target) };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
parseRules,
|
|
83
|
+
serializeRules,
|
|
84
|
+
listRules,
|
|
85
|
+
addRule,
|
|
86
|
+
updateRule,
|
|
87
|
+
removeRule
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=chunk-3IS2X2Z7.js.map
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
redact
|
|
4
|
+
} from "./chunk-JCGDR4UV.js";
|
|
5
|
+
import {
|
|
6
|
+
toPosix
|
|
7
|
+
} from "./chunk-XW3MLHI2.js";
|
|
8
|
+
import {
|
|
9
|
+
athenaDir
|
|
10
|
+
} from "./chunk-EUPETUWA.js";
|
|
11
|
+
|
|
12
|
+
// src/services/agent-activity.ts
|
|
13
|
+
import { promises as fs } from "fs";
|
|
14
|
+
import path from "path";
|
|
15
|
+
var ACTIVITY_FILE = ".agent-events.jsonl";
|
|
16
|
+
var ROTATED_ACTIVITY_FILE = ".agent-events.1.jsonl";
|
|
17
|
+
var ROTATE_LOCK = ".agent-events.rotate.lock";
|
|
18
|
+
var MAX_ACTIVITY_BYTES = 512 * 1024;
|
|
19
|
+
function activityFile(root) {
|
|
20
|
+
return path.join(athenaDir(root), ACTIVITY_FILE);
|
|
21
|
+
}
|
|
22
|
+
function rotatedActivityFile(root) {
|
|
23
|
+
return path.join(athenaDir(root), ROTATED_ACTIVITY_FILE);
|
|
24
|
+
}
|
|
25
|
+
var MASK = "<redacted>";
|
|
26
|
+
var COMMAND_SECRETS = [
|
|
27
|
+
// Authorization: Bearer <token> / Basic <b64> (headers, curl -H, etc.)
|
|
28
|
+
[/(\bauthorization\s*[:=]\s*["']?\s*(?:bearer|basic|token|digest)\s+)[^\s"',;]+/gi, `$1${MASK}`],
|
|
29
|
+
[/(\bbearer\s+)[A-Za-z0-9._~+/=-]{6,}/gi, `$1${MASK}`],
|
|
30
|
+
// --password=x, --password x, --passwd "x y"
|
|
31
|
+
[/(--(?:password|passwd|pass)(?:=|\s+))("[^"]*"|'[^']*'|[^\s"']+)/gi, `$1${MASK}`],
|
|
32
|
+
// mysql -psecret (attached value; `-p` alone prompts)
|
|
33
|
+
[/(\b(?:mysql|mysqldump|mysqladmin|mysqlimport|mariadb|mariadb-dump)\b[^|;&\n]*?\s-p)("[^"]*"|'[^']*'|[^\s"']+)/gi, `$1${MASK}`],
|
|
34
|
+
// scheme://user:password@host
|
|
35
|
+
[/(\b[a-z][a-z0-9+.-]*:\/\/[^\s:@/]*:)([^\s@/]+)(@)/gi, `$1${MASK}$3`]
|
|
36
|
+
];
|
|
37
|
+
function redactCommandSecrets(text) {
|
|
38
|
+
let out = text;
|
|
39
|
+
for (const [re, rep] of COMMAND_SECRETS) out = out.replace(re, rep);
|
|
40
|
+
return redact(out);
|
|
41
|
+
}
|
|
42
|
+
function sanitizeEvent(root, event) {
|
|
43
|
+
const rel = (p) => {
|
|
44
|
+
const abs = path.isAbsolute(p) ? p : path.resolve(root, p);
|
|
45
|
+
const r = toPosix(path.relative(root, abs));
|
|
46
|
+
return !r || r.startsWith("..") ? toPosix(p) : r;
|
|
47
|
+
};
|
|
48
|
+
const stripRoot = (text) => text.split(`${root}${path.sep}`).join("").split(toPosix(root) + "/").join("");
|
|
49
|
+
return {
|
|
50
|
+
...event,
|
|
51
|
+
message: redactCommandSecrets(stripRoot(event.message)),
|
|
52
|
+
command: event.command ? redactCommandSecrets(stripRoot(event.command)) : null,
|
|
53
|
+
files: event.files.map(rel)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function appendEvent(root, event) {
|
|
57
|
+
const file = activityFile(root);
|
|
58
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
59
|
+
await fs.appendFile(file, `${JSON.stringify(sanitizeEvent(root, event))}
|
|
60
|
+
`);
|
|
61
|
+
await rotateIfNeeded(file);
|
|
62
|
+
}
|
|
63
|
+
async function rotateIfNeeded(file, maxBytes = MAX_ACTIVITY_BYTES) {
|
|
64
|
+
try {
|
|
65
|
+
const st = await fs.stat(file);
|
|
66
|
+
if (st.size < maxBytes) return;
|
|
67
|
+
const dir = path.dirname(file);
|
|
68
|
+
const lock = path.join(dir, ROTATE_LOCK);
|
|
69
|
+
let handle;
|
|
70
|
+
try {
|
|
71
|
+
handle = await fs.open(lock, "wx");
|
|
72
|
+
} catch {
|
|
73
|
+
const age = await fs.stat(lock).then((l) => Date.now() - l.mtimeMs).catch(() => 0);
|
|
74
|
+
if (age > 1e4) await fs.rm(lock, { force: true });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const again = await fs.stat(file).catch(() => null);
|
|
79
|
+
if (again && again.size >= maxBytes) await fs.rename(file, path.join(dir, ROTATED_ACTIVITY_FILE));
|
|
80
|
+
} finally {
|
|
81
|
+
await handle.close();
|
|
82
|
+
await fs.rm(lock, { force: true });
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function parseEventLines(text) {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const line of text.split("\n")) {
|
|
90
|
+
if (!line.trim()) continue;
|
|
91
|
+
try {
|
|
92
|
+
const e = JSON.parse(line);
|
|
93
|
+
if (e && typeof e.id === "string" && typeof e.ts === "string" && typeof e.agent === "string") out.push(e);
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
async function readRecentEvents(root, limit = 200) {
|
|
100
|
+
const current = parseEventLines(await fs.readFile(activityFile(root), "utf8").catch(() => ""));
|
|
101
|
+
if (current.length >= limit) return current.slice(-limit);
|
|
102
|
+
const previous = parseEventLines(await fs.readFile(rotatedActivityFile(root), "utf8").catch(() => ""));
|
|
103
|
+
return [...previous, ...current].slice(-limit);
|
|
104
|
+
}
|
|
105
|
+
function summarizeSessions(events) {
|
|
106
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
107
|
+
for (const e of events) {
|
|
108
|
+
const key = `${e.agent}:${e.session ?? "-"}`;
|
|
109
|
+
const cur = byKey.get(key);
|
|
110
|
+
byKey.set(key, { agent: e.agent, session: e.session, lastEventAt: e.ts, lastMessage: e.message, events: (cur?.events ?? 0) + 1 });
|
|
111
|
+
}
|
|
112
|
+
return [...byKey.values()].sort((a, b) => b.lastEventAt.localeCompare(a.lastEventAt));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export {
|
|
116
|
+
ACTIVITY_FILE,
|
|
117
|
+
activityFile,
|
|
118
|
+
rotatedActivityFile,
|
|
119
|
+
appendEvent,
|
|
120
|
+
parseEventLines,
|
|
121
|
+
readRecentEvents,
|
|
122
|
+
summarizeSessions
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=chunk-65TSRDQ3.js.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
sha256
|
|
4
|
+
} from "./chunk-IQQBAWSM.js";
|
|
5
|
+
|
|
6
|
+
// src/core/knowledge/managed-blocks.ts
|
|
7
|
+
var START_RE = /<!-- athena:generated:start id=([a-z0-9-]+) hash=([a-f0-9]*) -->\n?/g;
|
|
8
|
+
function blockHash(content) {
|
|
9
|
+
return sha256(content.trim()).slice(0, 12);
|
|
10
|
+
}
|
|
11
|
+
function renderBlock(section) {
|
|
12
|
+
const body = section.content.trim();
|
|
13
|
+
return `<!-- athena:generated:start id=${section.id} hash=${blockHash(body)} -->
|
|
14
|
+
${body}
|
|
15
|
+
<!-- athena:generated:end id=${section.id} -->`;
|
|
16
|
+
}
|
|
17
|
+
function parseBlocks(text) {
|
|
18
|
+
const blocks = [];
|
|
19
|
+
START_RE.lastIndex = 0;
|
|
20
|
+
for (let m = START_RE.exec(text); m; m = START_RE.exec(text)) {
|
|
21
|
+
const id = m[1];
|
|
22
|
+
const endMarker = `<!-- athena:generated:end id=${id} -->`;
|
|
23
|
+
const endIdx = text.indexOf(endMarker, m.index + m[0].length);
|
|
24
|
+
if (endIdx === -1) continue;
|
|
25
|
+
blocks.push({ id, hash: m[2], content: text.slice(m.index + m[0].length, endIdx).trim(), start: m.index, end: endIdx + endMarker.length });
|
|
26
|
+
START_RE.lastIndex = endIdx + endMarker.length;
|
|
27
|
+
}
|
|
28
|
+
return blocks;
|
|
29
|
+
}
|
|
30
|
+
function isBlockModified(block) {
|
|
31
|
+
return blockHash(block.content) !== block.hash;
|
|
32
|
+
}
|
|
33
|
+
function mergeDocument(existing, sections, opts = {}) {
|
|
34
|
+
const blocks = parseBlocks(existing);
|
|
35
|
+
const byId = new Map(blocks.map((b) => [b.id, b]));
|
|
36
|
+
const result = { text: existing, changed: false, preservedModified: [], updated: [], added: [] };
|
|
37
|
+
const replacements = [];
|
|
38
|
+
for (const s of sections) {
|
|
39
|
+
const b = byId.get(s.id);
|
|
40
|
+
if (!b) continue;
|
|
41
|
+
if (isBlockModified(b) && !opts.force) {
|
|
42
|
+
result.preservedModified.push(s.id);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (b.content === s.content.trim() && !isBlockModified(b)) continue;
|
|
46
|
+
replacements.push({ start: b.start, end: b.end, text: renderBlock(s) });
|
|
47
|
+
result.updated.push(s.id);
|
|
48
|
+
}
|
|
49
|
+
let text = existing;
|
|
50
|
+
for (const r of replacements.sort((a, b) => b.start - a.start)) text = text.slice(0, r.start) + r.text + text.slice(r.end);
|
|
51
|
+
const known = new Set(opts.previouslyKnown ?? []);
|
|
52
|
+
const toAdd = sections.filter((s) => !byId.has(s.id) && !known.has(s.id));
|
|
53
|
+
if (toAdd.length) {
|
|
54
|
+
const insert = toAdd.map((s) => renderBlock(s)).join("\n\n");
|
|
55
|
+
const marker = opts.insertBefore ? text.indexOf(opts.insertBefore) : -1;
|
|
56
|
+
text = marker >= 0 ? `${text.slice(0, marker)}${insert}
|
|
57
|
+
|
|
58
|
+
${text.slice(marker)}` : `${text.replace(/\s*$/, "")}
|
|
59
|
+
|
|
60
|
+
${insert}
|
|
61
|
+
`;
|
|
62
|
+
result.added.push(...toAdd.map((s) => s.id));
|
|
63
|
+
}
|
|
64
|
+
result.text = text;
|
|
65
|
+
result.changed = text !== existing;
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
var INTEGRATION_START = "<!-- athena:start -->";
|
|
69
|
+
var INTEGRATION_END = "<!-- athena:end -->";
|
|
70
|
+
function upsertIntegrationBlock(existing, body) {
|
|
71
|
+
const block = `${INTEGRATION_START}
|
|
72
|
+
${body.trim()}
|
|
73
|
+
${INTEGRATION_END}`;
|
|
74
|
+
if (!existing) return `${block}
|
|
75
|
+
`;
|
|
76
|
+
const s = existing.indexOf(INTEGRATION_START);
|
|
77
|
+
const e = existing.indexOf(INTEGRATION_END);
|
|
78
|
+
if (s !== -1 && e > s) return existing.slice(0, s) + block + existing.slice(e + INTEGRATION_END.length);
|
|
79
|
+
return `${existing.replace(/\s*$/, "")}
|
|
80
|
+
|
|
81
|
+
${block}
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
function removeIntegrationBlock(existing) {
|
|
85
|
+
const s = existing.indexOf(INTEGRATION_START);
|
|
86
|
+
const e = existing.indexOf(INTEGRATION_END);
|
|
87
|
+
if (s === -1 || e < s) return existing;
|
|
88
|
+
const before = existing.slice(0, s).replace(/\s*$/, "");
|
|
89
|
+
const after = existing.slice(e + INTEGRATION_END.length).replace(/^\s*/, "");
|
|
90
|
+
const joined = [before, after.replace(/\s*$/, "")].filter(Boolean).join("\n\n");
|
|
91
|
+
return joined ? `${joined}
|
|
92
|
+
` : "";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
renderBlock,
|
|
97
|
+
parseBlocks,
|
|
98
|
+
isBlockModified,
|
|
99
|
+
mergeDocument,
|
|
100
|
+
INTEGRATION_START,
|
|
101
|
+
INTEGRATION_END,
|
|
102
|
+
upsertIntegrationBlock,
|
|
103
|
+
removeIntegrationBlock
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=chunk-673EPYYH.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/services/errors.ts
|
|
4
|
+
var EXIT = {
|
|
5
|
+
OK: 0,
|
|
6
|
+
ERROR: 1,
|
|
7
|
+
NOT_AVAILABLE: 2,
|
|
8
|
+
NOT_INITIALIZED: 3,
|
|
9
|
+
INTERRUPTED: 130
|
|
10
|
+
};
|
|
11
|
+
var AthenaError = class extends Error {
|
|
12
|
+
constructor(message, hint, exitCode = EXIT.ERROR, kind, details) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.hint = hint;
|
|
15
|
+
this.exitCode = exitCode;
|
|
16
|
+
this.details = details;
|
|
17
|
+
this.name = "AthenaError";
|
|
18
|
+
this.kind = kind ?? (exitCode === EXIT.NOT_INITIALIZED ? "not-initialized" : "invalid");
|
|
19
|
+
}
|
|
20
|
+
hint;
|
|
21
|
+
exitCode;
|
|
22
|
+
details;
|
|
23
|
+
kind;
|
|
24
|
+
};
|
|
25
|
+
var notFound = (message) => new AthenaError(message, void 0, EXIT.ERROR, "not-found");
|
|
26
|
+
var conflict = (message, hint, details) => new AthenaError(message, hint, EXIT.ERROR, "conflict", details);
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
EXIT,
|
|
30
|
+
AthenaError,
|
|
31
|
+
notFound,
|
|
32
|
+
conflict
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=chunk-AD4OZCU2.js.map
|