@triedotdev/mcp 1.0.113 → 1.0.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-fix-apply-PCAHWLXF.js +10 -0
- package/dist/autonomy-config-JXB7WCZ2.js +30 -0
- package/dist/chunk-2GIAROBF.js +173 -0
- package/dist/chunk-2GIAROBF.js.map +1 -0
- package/dist/{chunk-33WL3D7A.js → chunk-2SIFK7OW.js} +7 -419
- package/dist/chunk-2SIFK7OW.js.map +1 -0
- package/dist/chunk-43X6JBEM.js +36 -0
- package/dist/chunk-43X6JBEM.js.map +1 -0
- package/dist/chunk-55DOQNHJ.js +772 -0
- package/dist/chunk-55DOQNHJ.js.map +1 -0
- package/dist/chunk-6LXSA2OZ.js +425 -0
- package/dist/chunk-6LXSA2OZ.js.map +1 -0
- package/dist/{chunk-SDS3UVFY.js → chunk-AOFYU6T3.js} +113 -559
- package/dist/chunk-AOFYU6T3.js.map +1 -0
- package/dist/{chunk-6QR6QZIX.js → chunk-D3EXBJE2.js} +25 -658
- package/dist/chunk-D3EXBJE2.js.map +1 -0
- package/dist/chunk-DJ2YAGHK.js +50 -0
- package/dist/chunk-DJ2YAGHK.js.map +1 -0
- package/dist/chunk-DZREHOGW.js +706 -0
- package/dist/chunk-DZREHOGW.js.map +1 -0
- package/dist/chunk-I2GFI3AM.js +340 -0
- package/dist/chunk-I2GFI3AM.js.map +1 -0
- package/dist/chunk-KRH642MT.js +947 -0
- package/dist/chunk-KRH642MT.js.map +1 -0
- package/dist/{chunk-QYOACM2C.js → chunk-MVNJPJBK.js} +22 -252
- package/dist/chunk-MVNJPJBK.js.map +1 -0
- package/dist/chunk-NS2MSZMB.js +394 -0
- package/dist/chunk-NS2MSZMB.js.map +1 -0
- package/dist/chunk-SWSK7ANT.js +340 -0
- package/dist/chunk-SWSK7ANT.js.map +1 -0
- package/dist/chunk-VRLMTOB6.js +566 -0
- package/dist/chunk-VRLMTOB6.js.map +1 -0
- package/dist/chunk-YR4BMGYO.js +130 -0
- package/dist/chunk-YR4BMGYO.js.map +1 -0
- package/dist/chunk-ZV2K6M7T.js +74 -0
- package/dist/chunk-ZV2K6M7T.js.map +1 -0
- package/dist/{chunk-2764KZZQ.js → chunk-ZYKEILVK.js} +451 -1069
- package/dist/chunk-ZYKEILVK.js.map +1 -0
- package/dist/cli/main.js +107 -375
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +18 -8
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/client-7XZHCMD3.js +28 -0
- package/dist/client-7XZHCMD3.js.map +1 -0
- package/dist/{goal-manager-AP4LTE6U.js → goal-manager-LMS6ZJB7.js} +7 -3
- package/dist/goal-manager-LMS6ZJB7.js.map +1 -0
- package/dist/goal-validator-T5HEYBC5.js +186 -0
- package/dist/goal-validator-T5HEYBC5.js.map +1 -0
- package/dist/graph-U5JWSAB5.js +10 -0
- package/dist/graph-U5JWSAB5.js.map +1 -0
- package/dist/guardian-agent-EXP7APLC.js +25 -0
- package/dist/guardian-agent-EXP7APLC.js.map +1 -0
- package/dist/hypothesis-KGC3P54C.js +19 -0
- package/dist/hypothesis-KGC3P54C.js.map +1 -0
- package/dist/incident-index-PNIVT47T.js +11 -0
- package/dist/incident-index-PNIVT47T.js.map +1 -0
- package/dist/index.js +369 -43
- package/dist/index.js.map +1 -1
- package/dist/ledger-SR6OEBLO.js +15 -0
- package/dist/ledger-SR6OEBLO.js.map +1 -0
- package/dist/output-manager-BOTMXSND.js +13 -0
- package/dist/output-manager-BOTMXSND.js.map +1 -0
- package/dist/pattern-discovery-F7LU5K6E.js +8 -0
- package/dist/pattern-discovery-F7LU5K6E.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-2764KZZQ.js.map +0 -1
- package/dist/chunk-33WL3D7A.js.map +0 -1
- package/dist/chunk-6JPPYG7F.js +0 -1813
- package/dist/chunk-6JPPYG7F.js.map +0 -1
- package/dist/chunk-6QR6QZIX.js.map +0 -1
- package/dist/chunk-QYOACM2C.js.map +0 -1
- package/dist/chunk-SDS3UVFY.js.map +0 -1
- package/dist/guardian-agent-XEYNG7RH.js +0 -18
- /package/dist/{goal-manager-AP4LTE6U.js.map → auto-fix-apply-PCAHWLXF.js.map} +0 -0
- /package/dist/{guardian-agent-XEYNG7RH.js.map → autonomy-config-JXB7WCZ2.js.map} +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGuardian
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AOFYU6T3.js";
|
|
4
4
|
import {
|
|
5
|
-
IncidentIndex,
|
|
6
5
|
LearningEngine,
|
|
7
6
|
exportToJson,
|
|
8
7
|
formatFriendlyError,
|
|
@@ -11,20 +10,30 @@ import {
|
|
|
11
10
|
perceiveCurrentChanges,
|
|
12
11
|
reasonAboutChangesHumanReadable,
|
|
13
12
|
saveCheckpoint
|
|
14
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MVNJPJBK.js";
|
|
15
14
|
import {
|
|
16
|
-
ContextGraph,
|
|
17
15
|
TieredStorage,
|
|
18
16
|
findCrossProjectPatterns,
|
|
17
|
+
getStorage
|
|
18
|
+
} from "./chunk-D3EXBJE2.js";
|
|
19
|
+
import {
|
|
19
20
|
getKeyFromKeychain,
|
|
20
|
-
getStorage,
|
|
21
21
|
isAIAvailable,
|
|
22
22
|
runAIWithTools,
|
|
23
23
|
setAPIKey
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-SWSK7ANT.js";
|
|
25
25
|
import {
|
|
26
26
|
getGuardianState
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-KRH642MT.js";
|
|
28
|
+
import {
|
|
29
|
+
ContextGraph
|
|
30
|
+
} from "./chunk-NS2MSZMB.js";
|
|
31
|
+
import {
|
|
32
|
+
IncidentIndex
|
|
33
|
+
} from "./chunk-2GIAROBF.js";
|
|
34
|
+
import {
|
|
35
|
+
getOutputManager
|
|
36
|
+
} from "./chunk-VRLMTOB6.js";
|
|
28
37
|
import {
|
|
29
38
|
getTrieDirectory,
|
|
30
39
|
getWorkingDirectory
|
|
@@ -269,10 +278,10 @@ var StreamingManager = class {
|
|
|
269
278
|
|
|
270
279
|
// src/cli/dashboard/index.ts
|
|
271
280
|
import { render } from "ink";
|
|
272
|
-
import
|
|
281
|
+
import React9 from "react";
|
|
273
282
|
|
|
274
283
|
// src/cli/dashboard/App.tsx
|
|
275
|
-
import { useState as
|
|
284
|
+
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback6, useRef as useRef2 } from "react";
|
|
276
285
|
import { Box as Box12, useInput as useInput8, useApp } from "ink";
|
|
277
286
|
|
|
278
287
|
// src/cli/dashboard/state.tsx
|
|
@@ -438,6 +447,7 @@ function applyAgentConfigPatch(current, patch) {
|
|
|
438
447
|
}
|
|
439
448
|
if (patch.performance) config.performance = { ...config.performance, ...patch.performance };
|
|
440
449
|
if (patch.riskThresholds) config.riskThresholds = { ...config.riskThresholds, ...patch.riskThresholds };
|
|
450
|
+
if (patch.aiWatcher) config.aiWatcher = { ...config.aiWatcher, ...patch.aiWatcher };
|
|
441
451
|
return config;
|
|
442
452
|
}
|
|
443
453
|
function dashboardReducer(state, action) {
|
|
@@ -729,7 +739,8 @@ function createInitialState() {
|
|
|
729
739
|
memoryRetentionDays: 30
|
|
730
740
|
},
|
|
731
741
|
performance: { parallel: true, cache: true, maxConcurrency: 4, timeoutMs: 12e4, workers: true, streaming: true },
|
|
732
|
-
riskThresholds: { critical: 70, high: 40, medium: 20 }
|
|
742
|
+
riskThresholds: { critical: 70, high: 40, medium: 20 },
|
|
743
|
+
aiWatcher: { enabled: true, hourlyTokenLimit: 5e4, scanCooldownSec: 30, cleanFileCooldownSec: 300, maxFilesPerScan: 5, maxCharsPerFile: 4e3 }
|
|
733
744
|
},
|
|
734
745
|
goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
735
746
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0 },
|
|
@@ -750,604 +761,44 @@ function useDashboard() {
|
|
|
750
761
|
return ctx;
|
|
751
762
|
}
|
|
752
763
|
|
|
753
|
-
// src/utils/output-manager.ts
|
|
754
|
-
import pc from "picocolors";
|
|
755
|
-
var OutputManagerImpl = class {
|
|
756
|
-
mode = "console";
|
|
757
|
-
streamingManager;
|
|
758
|
-
markdownBuffer = [];
|
|
759
|
-
jsonBuffer = [];
|
|
760
|
-
rawLogBuffer = [];
|
|
761
|
-
// Callbacks for TUI integration (explicitly allow undefined for exactOptionalPropertyTypes)
|
|
762
|
-
onBanner = void 0;
|
|
763
|
-
onSnippet = void 0;
|
|
764
|
-
onCost = void 0;
|
|
765
|
-
onReadiness = void 0;
|
|
766
|
-
onSemantic = void 0;
|
|
767
|
-
onAttack = void 0;
|
|
768
|
-
onActivity = void 0;
|
|
769
|
-
onLog = void 0;
|
|
770
|
-
onNudge = void 0;
|
|
771
|
-
/**
|
|
772
|
-
* Set the output mode
|
|
773
|
-
*/
|
|
774
|
-
setMode(mode) {
|
|
775
|
-
this.mode = mode;
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* Get current output mode
|
|
779
|
-
*/
|
|
780
|
-
getMode() {
|
|
781
|
-
return this.mode;
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Set streaming manager for TUI updates
|
|
785
|
-
*/
|
|
786
|
-
setStreamingManager(manager) {
|
|
787
|
-
this.streamingManager = manager;
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Register TUI callbacks for rich content
|
|
791
|
-
*/
|
|
792
|
-
registerTUICallbacks(callbacks) {
|
|
793
|
-
this.onBanner = callbacks.onBanner;
|
|
794
|
-
this.onSnippet = callbacks.onSnippet;
|
|
795
|
-
this.onCost = callbacks.onCost;
|
|
796
|
-
this.onReadiness = callbacks.onReadiness;
|
|
797
|
-
this.onSemantic = callbacks.onSemantic;
|
|
798
|
-
this.onAttack = callbacks.onAttack;
|
|
799
|
-
this.onActivity = callbacks.onActivity;
|
|
800
|
-
this.onLog = callbacks.onLog;
|
|
801
|
-
this.onNudge = callbacks.onNudge;
|
|
802
|
-
}
|
|
803
|
-
/**
|
|
804
|
-
* Clear TUI callbacks (when dashboard stops)
|
|
805
|
-
*/
|
|
806
|
-
clearTUICallbacks() {
|
|
807
|
-
this.onBanner = void 0;
|
|
808
|
-
this.onSnippet = void 0;
|
|
809
|
-
this.onCost = void 0;
|
|
810
|
-
this.onReadiness = void 0;
|
|
811
|
-
this.onSemantic = void 0;
|
|
812
|
-
this.onAttack = void 0;
|
|
813
|
-
this.onActivity = void 0;
|
|
814
|
-
this.onLog = void 0;
|
|
815
|
-
this.onNudge = void 0;
|
|
816
|
-
}
|
|
817
|
-
/**
|
|
818
|
-
* Emit content - routes to appropriate handler based on mode
|
|
819
|
-
*/
|
|
820
|
-
emit(content) {
|
|
821
|
-
content.timestamp = content.timestamp ?? Date.now();
|
|
822
|
-
switch (this.mode) {
|
|
823
|
-
case "tui":
|
|
824
|
-
this.routeToTUI(content);
|
|
825
|
-
break;
|
|
826
|
-
case "console":
|
|
827
|
-
this.routeToConsole(content);
|
|
828
|
-
break;
|
|
829
|
-
case "mcp":
|
|
830
|
-
this.routeToMarkdown(content);
|
|
831
|
-
break;
|
|
832
|
-
case "json":
|
|
833
|
-
this.routeToJson(content);
|
|
834
|
-
break;
|
|
835
|
-
case "silent":
|
|
836
|
-
break;
|
|
837
|
-
}
|
|
838
|
-
this.captureRawLog(content);
|
|
839
|
-
}
|
|
840
|
-
/**
|
|
841
|
-
* Route content to TUI (dashboard callbacks)
|
|
842
|
-
*/
|
|
843
|
-
routeToTUI(content) {
|
|
844
|
-
switch (content.type) {
|
|
845
|
-
case "banner":
|
|
846
|
-
this.onBanner?.(content.content);
|
|
847
|
-
break;
|
|
848
|
-
case "snippet":
|
|
849
|
-
this.onSnippet?.(content.content);
|
|
850
|
-
break;
|
|
851
|
-
case "cost":
|
|
852
|
-
this.onCost?.(content.content);
|
|
853
|
-
break;
|
|
854
|
-
case "readiness":
|
|
855
|
-
this.onReadiness?.(content.content);
|
|
856
|
-
break;
|
|
857
|
-
case "semantic":
|
|
858
|
-
this.onSemantic?.(content.content);
|
|
859
|
-
break;
|
|
860
|
-
case "attack":
|
|
861
|
-
this.onAttack?.(content.content);
|
|
862
|
-
break;
|
|
863
|
-
case "activity":
|
|
864
|
-
this.onActivity?.(content.content);
|
|
865
|
-
break;
|
|
866
|
-
case "log":
|
|
867
|
-
const level = content.metadata?.severity ?? "info";
|
|
868
|
-
this.onLog?.(level, content.content);
|
|
869
|
-
break;
|
|
870
|
-
case "issue":
|
|
871
|
-
this.streamingManager?.reportIssue(content.content);
|
|
872
|
-
break;
|
|
873
|
-
case "progress":
|
|
874
|
-
break;
|
|
875
|
-
case "report":
|
|
876
|
-
break;
|
|
877
|
-
case "nudge":
|
|
878
|
-
this.onNudge?.(content.content);
|
|
879
|
-
break;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
/**
|
|
883
|
-
* Route content to console (ANSI formatted)
|
|
884
|
-
*/
|
|
885
|
-
routeToConsole(content) {
|
|
886
|
-
switch (content.type) {
|
|
887
|
-
case "banner":
|
|
888
|
-
const banner = content.content;
|
|
889
|
-
console.error("\n" + "=".repeat(60));
|
|
890
|
-
console.error(banner.art);
|
|
891
|
-
if (banner.version) {
|
|
892
|
-
console.error(` ${banner.skill} v${banner.version}`);
|
|
893
|
-
}
|
|
894
|
-
console.error("");
|
|
895
|
-
if (banner.quote) {
|
|
896
|
-
console.error(` "${banner.quote}"`);
|
|
897
|
-
}
|
|
898
|
-
console.error("=".repeat(60) + "\n");
|
|
899
|
-
break;
|
|
900
|
-
case "snippet":
|
|
901
|
-
const snippet = content.content;
|
|
902
|
-
console.error(`
|
|
903
|
-
${pc.dim("File:")} ${snippet.file}`);
|
|
904
|
-
for (let i = 0; i < snippet.lines.length; i++) {
|
|
905
|
-
const lineNum = snippet.startLine + i;
|
|
906
|
-
const isHighlight = lineNum === snippet.highlightLine;
|
|
907
|
-
const prefix = isHighlight ? pc.red("\u2192") : " ";
|
|
908
|
-
const lineNumStr = pc.dim(lineNum.toString().padStart(4));
|
|
909
|
-
const line = isHighlight ? pc.yellow(snippet.lines[i]) : snippet.lines[i];
|
|
910
|
-
console.error(`${prefix} ${lineNumStr} | ${line}`);
|
|
911
|
-
}
|
|
912
|
-
console.error("");
|
|
913
|
-
break;
|
|
914
|
-
case "cost":
|
|
915
|
-
const cost = content.content;
|
|
916
|
-
console.error("\n" + pc.cyan("[$] Cost Estimate:"));
|
|
917
|
-
console.error(` Fix now: ${pc.green(this.formatCurrency(cost.fixNowCost))}`);
|
|
918
|
-
console.error(` If production: ${pc.red(this.formatCurrency(cost.productionCost))}`);
|
|
919
|
-
console.error(` Savings: ${pc.yellow(this.formatCurrency(cost.savings))}`);
|
|
920
|
-
console.error("");
|
|
921
|
-
break;
|
|
922
|
-
case "readiness":
|
|
923
|
-
const readiness = content.content;
|
|
924
|
-
const statusColor = readiness.status === "ready" ? pc.green : readiness.status === "caution" ? pc.yellow : pc.red;
|
|
925
|
-
console.error("\n" + pc.cyan("[%] Production Readiness:"));
|
|
926
|
-
console.error(` Score: ${statusColor(readiness.score + "/100")}`);
|
|
927
|
-
console.error(` Requirements: ${readiness.requirementsMet}/${readiness.total}`);
|
|
928
|
-
console.error(` Status: ${statusColor(readiness.status.toUpperCase())}`);
|
|
929
|
-
console.error("");
|
|
930
|
-
break;
|
|
931
|
-
case "semantic":
|
|
932
|
-
const semantic = content.content;
|
|
933
|
-
console.error("\n" + pc.cyan("[?] Semantic Analysis:"));
|
|
934
|
-
if (semantic.dataFlowIssues > 0) {
|
|
935
|
-
console.error(` ${pc.red("[!]")} ${semantic.dataFlowIssues} data flow vulnerabilities`);
|
|
936
|
-
}
|
|
937
|
-
if (semantic.raceConditions > 0) {
|
|
938
|
-
console.error(` ${pc.yellow("[~]")} ${semantic.raceConditions} race conditions`);
|
|
939
|
-
}
|
|
940
|
-
if (semantic.authIssues > 0) {
|
|
941
|
-
console.error(` ${pc.red("[!]")} ${semantic.authIssues} authentication issues`);
|
|
942
|
-
}
|
|
943
|
-
console.error("");
|
|
944
|
-
break;
|
|
945
|
-
case "attack":
|
|
946
|
-
const attack = content.content;
|
|
947
|
-
console.error("\n" + pc.cyan("[>] Attack Surface:"));
|
|
948
|
-
console.error(` Endpoints: ${attack.totalEndpoints}`);
|
|
949
|
-
if (attack.unprotected > 0) {
|
|
950
|
-
console.error(` ${pc.red("Unprotected:")} ${attack.unprotected}`);
|
|
951
|
-
}
|
|
952
|
-
console.error(` Risk Score: ${attack.riskScore}/100`);
|
|
953
|
-
console.error("");
|
|
954
|
-
break;
|
|
955
|
-
case "activity":
|
|
956
|
-
console.error(pc.dim(`[${this.formatTime()}]`) + ` ${content.content}`);
|
|
957
|
-
break;
|
|
958
|
-
case "log":
|
|
959
|
-
const logLevel = String(content.metadata?.severity ?? "info");
|
|
960
|
-
const levelColor = logLevel === "error" || logLevel === "critical" ? pc.red : logLevel === "warn" || logLevel === "serious" ? pc.yellow : logLevel === "info" || logLevel === "moderate" ? pc.blue : pc.dim;
|
|
961
|
-
console.error(levelColor(`[${logLevel.toUpperCase()}]`) + ` ${content.content}`);
|
|
962
|
-
break;
|
|
963
|
-
case "issue":
|
|
964
|
-
const issue = content.content;
|
|
965
|
-
const sevColor = issue.severity === "critical" ? pc.red : issue.severity === "serious" ? pc.yellow : issue.severity === "moderate" ? pc.blue : pc.dim;
|
|
966
|
-
console.error(`${sevColor(`[${issue.severity.toUpperCase()}]`)} ${issue.issue}`);
|
|
967
|
-
console.error(` ${pc.dim("File:")} ${issue.file}:${issue.line ?? "?"}`);
|
|
968
|
-
break;
|
|
969
|
-
case "report":
|
|
970
|
-
console.error(content.content);
|
|
971
|
-
break;
|
|
972
|
-
case "nudge":
|
|
973
|
-
const nudge = content.content;
|
|
974
|
-
const nudgeColor = nudge.severity === "critical" ? pc.red : nudge.severity === "warning" ? pc.yellow : pc.cyan;
|
|
975
|
-
const nudgeIcon = nudge.severity === "critical" ? "[!!!]" : nudge.severity === "warning" ? "[!]" : "[>]";
|
|
976
|
-
console.error("");
|
|
977
|
-
console.error(nudgeColor("\u2501".repeat(60)));
|
|
978
|
-
console.error(nudgeColor(`${nudgeIcon} TRIE AGENT SAYS:`));
|
|
979
|
-
console.error(nudgeColor("\u2501".repeat(60)));
|
|
980
|
-
console.error("");
|
|
981
|
-
console.error(` ${pc.bold(nudge.message)}`);
|
|
982
|
-
if (nudge.file) {
|
|
983
|
-
console.error(` ${pc.dim("File:")} ${nudge.file}`);
|
|
984
|
-
}
|
|
985
|
-
console.error("");
|
|
986
|
-
console.error(nudgeColor("\u2501".repeat(60)));
|
|
987
|
-
console.error("");
|
|
988
|
-
break;
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
/**
|
|
992
|
-
* Route content to markdown buffer
|
|
993
|
-
*/
|
|
994
|
-
routeToMarkdown(content) {
|
|
995
|
-
switch (content.type) {
|
|
996
|
-
case "banner":
|
|
997
|
-
const banner = content.content;
|
|
998
|
-
this.markdownBuffer.push(`## ${banner.skill}
|
|
999
|
-
`);
|
|
1000
|
-
if (banner.quote) {
|
|
1001
|
-
this.markdownBuffer.push(`> ${banner.quote}
|
|
1002
|
-
`);
|
|
1003
|
-
}
|
|
1004
|
-
break;
|
|
1005
|
-
case "snippet":
|
|
1006
|
-
const snippet = content.content;
|
|
1007
|
-
this.markdownBuffer.push(`
|
|
1008
|
-
**File:** \`${snippet.file}\`
|
|
1009
|
-
`);
|
|
1010
|
-
this.markdownBuffer.push("```\n");
|
|
1011
|
-
for (let i = 0; i < snippet.lines.length; i++) {
|
|
1012
|
-
const lineNum = snippet.startLine + i;
|
|
1013
|
-
const prefix = lineNum === snippet.highlightLine ? "\u2192" : " ";
|
|
1014
|
-
this.markdownBuffer.push(`${prefix} ${lineNum.toString().padStart(4)} | ${snippet.lines[i]}
|
|
1015
|
-
`);
|
|
1016
|
-
}
|
|
1017
|
-
this.markdownBuffer.push("```\n");
|
|
1018
|
-
break;
|
|
1019
|
-
case "cost":
|
|
1020
|
-
const cost = content.content;
|
|
1021
|
-
this.markdownBuffer.push(`
|
|
1022
|
-
### Cost Estimate
|
|
1023
|
-
`);
|
|
1024
|
-
this.markdownBuffer.push(`- Fix now: ${this.formatCurrency(cost.fixNowCost)}
|
|
1025
|
-
`);
|
|
1026
|
-
this.markdownBuffer.push(`- If production: ${this.formatCurrency(cost.productionCost)}
|
|
1027
|
-
`);
|
|
1028
|
-
this.markdownBuffer.push(`- Savings: ${this.formatCurrency(cost.savings)}
|
|
1029
|
-
`);
|
|
1030
|
-
break;
|
|
1031
|
-
case "readiness":
|
|
1032
|
-
const readiness = content.content;
|
|
1033
|
-
this.markdownBuffer.push(`
|
|
1034
|
-
### Production Readiness
|
|
1035
|
-
`);
|
|
1036
|
-
this.markdownBuffer.push(`- Score: ${readiness.score}/100
|
|
1037
|
-
`);
|
|
1038
|
-
this.markdownBuffer.push(`- Requirements: ${readiness.requirementsMet}/${readiness.total}
|
|
1039
|
-
`);
|
|
1040
|
-
this.markdownBuffer.push(`- Status: **${readiness.status.toUpperCase()}**
|
|
1041
|
-
`);
|
|
1042
|
-
break;
|
|
1043
|
-
case "semantic":
|
|
1044
|
-
const semantic = content.content;
|
|
1045
|
-
this.markdownBuffer.push(`
|
|
1046
|
-
### Semantic Analysis
|
|
1047
|
-
`);
|
|
1048
|
-
if (semantic.dataFlowIssues > 0) {
|
|
1049
|
-
this.markdownBuffer.push(`- [CRITICAL] ${semantic.dataFlowIssues} data flow vulnerabilities
|
|
1050
|
-
`);
|
|
1051
|
-
}
|
|
1052
|
-
if (semantic.raceConditions > 0) {
|
|
1053
|
-
this.markdownBuffer.push(`- [WARN] ${semantic.raceConditions} race conditions
|
|
1054
|
-
`);
|
|
1055
|
-
}
|
|
1056
|
-
if (semantic.authIssues > 0) {
|
|
1057
|
-
this.markdownBuffer.push(`- [CRITICAL] ${semantic.authIssues} authentication issues
|
|
1058
|
-
`);
|
|
1059
|
-
}
|
|
1060
|
-
break;
|
|
1061
|
-
case "attack":
|
|
1062
|
-
const attack = content.content;
|
|
1063
|
-
this.markdownBuffer.push(`
|
|
1064
|
-
### Attack Surface
|
|
1065
|
-
`);
|
|
1066
|
-
this.markdownBuffer.push(`- Endpoints: ${attack.totalEndpoints}
|
|
1067
|
-
`);
|
|
1068
|
-
this.markdownBuffer.push(`- Unprotected: ${attack.unprotected}
|
|
1069
|
-
`);
|
|
1070
|
-
this.markdownBuffer.push(`- Risk Score: ${attack.riskScore}/100
|
|
1071
|
-
`);
|
|
1072
|
-
break;
|
|
1073
|
-
case "report":
|
|
1074
|
-
this.markdownBuffer.push(content.content);
|
|
1075
|
-
break;
|
|
1076
|
-
default:
|
|
1077
|
-
this.jsonBuffer.push(content);
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
/**
|
|
1081
|
-
* Route content to JSON buffer
|
|
1082
|
-
*/
|
|
1083
|
-
routeToJson(content) {
|
|
1084
|
-
this.jsonBuffer.push(content);
|
|
1085
|
-
}
|
|
1086
|
-
/**
|
|
1087
|
-
* Capture content in raw log buffer
|
|
1088
|
-
*/
|
|
1089
|
-
captureRawLog(content) {
|
|
1090
|
-
const time = this.formatTime(content.timestamp);
|
|
1091
|
-
const level = content.metadata?.severity ?? content.type;
|
|
1092
|
-
let message = "";
|
|
1093
|
-
switch (content.type) {
|
|
1094
|
-
case "banner":
|
|
1095
|
-
message = `[BANNER] ${content.content.skill}`;
|
|
1096
|
-
break;
|
|
1097
|
-
case "activity":
|
|
1098
|
-
case "log":
|
|
1099
|
-
message = content.content;
|
|
1100
|
-
break;
|
|
1101
|
-
case "issue":
|
|
1102
|
-
const issue = content.content;
|
|
1103
|
-
message = `[${issue.severity.toUpperCase()}] ${issue.issue}`;
|
|
1104
|
-
break;
|
|
1105
|
-
default:
|
|
1106
|
-
message = `[${content.type.toUpperCase()}] Content received`;
|
|
1107
|
-
}
|
|
1108
|
-
this.rawLogBuffer.push({ time, level, message });
|
|
1109
|
-
if (this.rawLogBuffer.length > 500) {
|
|
1110
|
-
this.rawLogBuffer = this.rawLogBuffer.slice(-500);
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
/**
|
|
1114
|
-
* Get raw log buffer for display
|
|
1115
|
-
*/
|
|
1116
|
-
getRawLog() {
|
|
1117
|
-
return [...this.rawLogBuffer];
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* Get accumulated markdown output
|
|
1121
|
-
*/
|
|
1122
|
-
getMarkdown() {
|
|
1123
|
-
return this.markdownBuffer.join("\n");
|
|
1124
|
-
}
|
|
1125
|
-
/**
|
|
1126
|
-
* Get accumulated JSON output
|
|
1127
|
-
*/
|
|
1128
|
-
getJson() {
|
|
1129
|
-
return [...this.jsonBuffer];
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* Clear buffers
|
|
1133
|
-
*/
|
|
1134
|
-
clearBuffers() {
|
|
1135
|
-
this.markdownBuffer = [];
|
|
1136
|
-
this.jsonBuffer = [];
|
|
1137
|
-
}
|
|
1138
|
-
// ============================================
|
|
1139
|
-
// Convenience methods for common output types
|
|
1140
|
-
// ============================================
|
|
1141
|
-
/**
|
|
1142
|
-
* Display a skill banner
|
|
1143
|
-
*/
|
|
1144
|
-
banner(skill, art, options) {
|
|
1145
|
-
this.emit({
|
|
1146
|
-
type: "banner",
|
|
1147
|
-
content: { skill, art, quote: options?.quote, version: options?.version },
|
|
1148
|
-
metadata: { agent: skill }
|
|
1149
|
-
});
|
|
1150
|
-
}
|
|
1151
|
-
/**
|
|
1152
|
-
* Display a code snippet
|
|
1153
|
-
*/
|
|
1154
|
-
snippet(file, lines, startLine, highlightLine) {
|
|
1155
|
-
this.emit({
|
|
1156
|
-
type: "snippet",
|
|
1157
|
-
content: { file, lines, startLine, highlightLine },
|
|
1158
|
-
metadata: { file }
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Display cost estimate
|
|
1163
|
-
*/
|
|
1164
|
-
cost(fixNowCost, productionCost, savings, perIssue) {
|
|
1165
|
-
this.emit({
|
|
1166
|
-
type: "cost",
|
|
1167
|
-
content: { fixNowCost, productionCost, savings, perIssue }
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
/**
|
|
1171
|
-
* Display production readiness
|
|
1172
|
-
*/
|
|
1173
|
-
readiness(score, requirementsMet, total, status, requirements) {
|
|
1174
|
-
const content = { score, requirementsMet, total, status };
|
|
1175
|
-
if (requirements) {
|
|
1176
|
-
content.requirements = requirements;
|
|
1177
|
-
}
|
|
1178
|
-
this.emit({
|
|
1179
|
-
type: "readiness",
|
|
1180
|
-
content
|
|
1181
|
-
});
|
|
1182
|
-
}
|
|
1183
|
-
/**
|
|
1184
|
-
* Display semantic analysis results
|
|
1185
|
-
*/
|
|
1186
|
-
semantic(dataFlowIssues, raceConditions, authIssues) {
|
|
1187
|
-
this.emit({
|
|
1188
|
-
type: "semantic",
|
|
1189
|
-
content: { dataFlowIssues, raceConditions, authIssues }
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
/**
|
|
1193
|
-
* Display attack surface analysis
|
|
1194
|
-
*/
|
|
1195
|
-
attack(totalEndpoints, unprotected, riskScore) {
|
|
1196
|
-
this.emit({
|
|
1197
|
-
type: "attack",
|
|
1198
|
-
content: { totalEndpoints, unprotected, riskScore }
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
* Log an activity message
|
|
1203
|
-
*/
|
|
1204
|
-
activity(message) {
|
|
1205
|
-
this.emit({
|
|
1206
|
-
type: "activity",
|
|
1207
|
-
content: message
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
/**
|
|
1211
|
-
* Log a message at specified level
|
|
1212
|
-
*/
|
|
1213
|
-
log(level, message) {
|
|
1214
|
-
this.emit({
|
|
1215
|
-
type: "log",
|
|
1216
|
-
content: message,
|
|
1217
|
-
metadata: { severity: level }
|
|
1218
|
-
});
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* Log info message
|
|
1222
|
-
*/
|
|
1223
|
-
info(message) {
|
|
1224
|
-
this.log("info", message);
|
|
1225
|
-
}
|
|
1226
|
-
/**
|
|
1227
|
-
* Log warning message
|
|
1228
|
-
*/
|
|
1229
|
-
warn(message) {
|
|
1230
|
-
this.log("warn", message);
|
|
1231
|
-
}
|
|
1232
|
-
/**
|
|
1233
|
-
* Log error message
|
|
1234
|
-
*/
|
|
1235
|
-
error(message) {
|
|
1236
|
-
this.log("error", message);
|
|
1237
|
-
}
|
|
1238
|
-
/**
|
|
1239
|
-
* Log debug message
|
|
1240
|
-
*/
|
|
1241
|
-
debug(message) {
|
|
1242
|
-
this.log("debug", message);
|
|
1243
|
-
}
|
|
1244
|
-
/**
|
|
1245
|
-
* Report an issue
|
|
1246
|
-
*/
|
|
1247
|
-
issue(issue) {
|
|
1248
|
-
this.emit({
|
|
1249
|
-
type: "issue",
|
|
1250
|
-
content: issue,
|
|
1251
|
-
metadata: { severity: issue.severity, agent: issue.agent, file: issue.file }
|
|
1252
|
-
});
|
|
1253
|
-
}
|
|
1254
|
-
/**
|
|
1255
|
-
* Add a report section
|
|
1256
|
-
*/
|
|
1257
|
-
report(content) {
|
|
1258
|
-
this.emit({
|
|
1259
|
-
type: "report",
|
|
1260
|
-
content
|
|
1261
|
-
});
|
|
1262
|
-
}
|
|
1263
|
-
/**
|
|
1264
|
-
* Send a proactive notification/nudge to the user
|
|
1265
|
-
* This creates a prominent popup in TUI mode or a boxed message in console mode
|
|
1266
|
-
*/
|
|
1267
|
-
nudge(message, severity = "warning", file, autoHideMs) {
|
|
1268
|
-
const metadata = {};
|
|
1269
|
-
if (severity === "critical") metadata.severity = "critical";
|
|
1270
|
-
else if (severity === "warning") metadata.severity = "moderate";
|
|
1271
|
-
else metadata.severity = "low";
|
|
1272
|
-
if (file !== void 0) metadata.file = file;
|
|
1273
|
-
this.emit({
|
|
1274
|
-
type: "nudge",
|
|
1275
|
-
content: { message, severity, file, autoHideMs },
|
|
1276
|
-
metadata
|
|
1277
|
-
});
|
|
1278
|
-
}
|
|
1279
|
-
// ============================================
|
|
1280
|
-
// Helpers
|
|
1281
|
-
// ============================================
|
|
1282
|
-
formatCurrency(amount) {
|
|
1283
|
-
if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
|
|
1284
|
-
if (amount >= 1e3) return `$${(amount / 1e3).toFixed(1)}k`;
|
|
1285
|
-
return `$${amount}`;
|
|
1286
|
-
}
|
|
1287
|
-
formatTime(timestamp) {
|
|
1288
|
-
const date = timestamp ? new Date(timestamp) : /* @__PURE__ */ new Date();
|
|
1289
|
-
return date.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
1290
|
-
}
|
|
1291
|
-
};
|
|
1292
|
-
var instance = null;
|
|
1293
|
-
function getOutputManager() {
|
|
1294
|
-
if (!instance) {
|
|
1295
|
-
instance = new OutputManagerImpl();
|
|
1296
|
-
if (isInteractiveMode()) {
|
|
1297
|
-
instance.setMode("tui");
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
return instance;
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
764
|
// src/cli/dashboard/App.tsx
|
|
1304
|
-
import { existsSync as
|
|
765
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1305
766
|
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
1306
|
-
import { join } from "path";
|
|
767
|
+
import { join as join2 } from "path";
|
|
1307
768
|
|
|
1308
769
|
// src/cli/dashboard/components/Header.tsx
|
|
1309
|
-
import { useState, useEffect } from "react";
|
|
1310
770
|
import { Box, Text } from "ink";
|
|
1311
771
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
1312
|
-
var WATCH_FRAMES = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
1313
772
|
function Header() {
|
|
1314
773
|
const { state } = useDashboard();
|
|
1315
774
|
const { signalExtraction, watch, alerts } = state;
|
|
1316
775
|
const totalExtracted = signalExtraction.decisionsExtracted + signalExtraction.factsExtracted + signalExtraction.blockersExtracted + signalExtraction.questionsExtracted;
|
|
1317
|
-
|
|
1318
|
-
useEffect(() => {
|
|
1319
|
-
if (!watch.watching) return;
|
|
1320
|
-
const id = setInterval(() => setFrame((f) => (f + 1) % WATCH_FRAMES.length), 150);
|
|
1321
|
-
return () => clearInterval(id);
|
|
1322
|
-
}, [watch.watching]);
|
|
1323
|
-
let statusLabel;
|
|
776
|
+
let status;
|
|
1324
777
|
if (watch.watching) {
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
778
|
+
status = totalExtracted > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
779
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", children: "\u25CF" }),
|
|
780
|
+
" ",
|
|
781
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", children: "Learning" }),
|
|
1328
782
|
" ",
|
|
1329
|
-
/* @__PURE__ */ jsx2(Text, { color: "green", bold: true, children: "Learning" }),
|
|
1330
|
-
" ",
|
|
1331
783
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1332
784
|
totalExtracted,
|
|
1333
785
|
" signals"
|
|
1334
786
|
] })
|
|
1335
787
|
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
1336
|
-
/* @__PURE__ */ jsx2(Text, { color: "green", children:
|
|
1337
|
-
" "
|
|
1338
|
-
/* @__PURE__ */ jsx2(Text, { bold: true, children: "Watching" })
|
|
788
|
+
/* @__PURE__ */ jsx2(Text, { color: "green", children: "\u25CF" }),
|
|
789
|
+
" Watching"
|
|
1339
790
|
] });
|
|
1340
791
|
} else {
|
|
1341
|
-
|
|
792
|
+
status = /* @__PURE__ */ jsxs(Text, { children: [
|
|
1342
793
|
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "\u25CB" }),
|
|
1343
794
|
" ",
|
|
1344
795
|
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "Idle" })
|
|
1345
796
|
] });
|
|
1346
797
|
}
|
|
1347
798
|
return /* @__PURE__ */ jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [
|
|
1348
|
-
/* @__PURE__ */ jsx2(Text, {
|
|
799
|
+
/* @__PURE__ */ jsx2(Text, { bold: true, children: "Trie" }),
|
|
1349
800
|
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
1350
|
-
|
|
801
|
+
status,
|
|
1351
802
|
alerts.hasCritical && /* @__PURE__ */ jsx2(Text, { color: "red", bold: true, children: "\u25CF Alert" })
|
|
1352
803
|
] })
|
|
1353
804
|
] });
|
|
@@ -1366,35 +817,26 @@ var VIEW_LABELS = {
|
|
|
1366
817
|
chat: "Chat"
|
|
1367
818
|
};
|
|
1368
819
|
var TAB_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
820
|
+
var CONTEXT_HINTS = {
|
|
821
|
+
goals: "j/k nav \xB7 a add \xB7 enter complete \xB7 d delete",
|
|
822
|
+
hypotheses: "j/k nav \xB7 a add \xB7 v validate \xB7 x invalidate",
|
|
823
|
+
agent: "j/k nav \xB7 enter expand \xB7 d dismiss",
|
|
824
|
+
memory: "j/k nav \xB7 enter expand",
|
|
825
|
+
chat: "type to ask \xB7 enter send \xB7 esc clear",
|
|
826
|
+
rawlog: "n/p pages \xB7 b back"
|
|
827
|
+
};
|
|
1369
828
|
function Footer() {
|
|
1370
829
|
const { state } = useDashboard();
|
|
1371
|
-
const { view } = state;
|
|
1372
|
-
let
|
|
1373
|
-
if (view === "goals" &&
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
} else if (view === "agent") {
|
|
1382
|
-
contextHints = "tab views \xB7 j/k nav \xB7 enter expand \xB7 d dismiss";
|
|
1383
|
-
} else if (view === "memory") {
|
|
1384
|
-
contextHints = "tab views \xB7 j/k nav \xB7 enter expand";
|
|
1385
|
-
} else if (view === "chat") {
|
|
1386
|
-
contextHints = "tab views \xB7 type to ask \xB7 enter send \xB7 esc clear";
|
|
1387
|
-
} else if (view === "rawlog") {
|
|
1388
|
-
contextHints = "tab views \xB7 n/p pages \xB7 b back";
|
|
1389
|
-
} else {
|
|
1390
|
-
contextHints = "tab views \xB7 n/p pages \xB7 s settings";
|
|
1391
|
-
}
|
|
1392
|
-
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
|
|
1393
|
-
/* @__PURE__ */ jsxs2(Box2, { justifyContent: "space-between", children: [
|
|
1394
|
-
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => v === view ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: VIEW_LABELS[v] }, v) : /* @__PURE__ */ jsx3(Text2, { children: VIEW_LABELS[v] }, v)) }),
|
|
1395
|
-
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "q quit" })
|
|
1396
|
-
] }),
|
|
1397
|
-
/* @__PURE__ */ jsx3(Text2, { dimColor: true, children: contextHints })
|
|
830
|
+
const { view, goalsPanel, hypothesesPanel } = state;
|
|
831
|
+
let hints = CONTEXT_HINTS[view] || "n/p pages \xB7 s settings";
|
|
832
|
+
if (view === "goals" && goalsPanel.inputMode === "add") hints = "enter save \xB7 esc cancel";
|
|
833
|
+
if (view === "hypotheses" && hypothesesPanel.inputMode === "add") hints = "enter save \xB7 esc cancel";
|
|
834
|
+
return /* @__PURE__ */ jsxs2(Box2, { paddingX: 1, justifyContent: "space-between", children: [
|
|
835
|
+
/* @__PURE__ */ jsx3(Box2, { gap: 1, children: TAB_VIEWS.map((v) => v === view ? /* @__PURE__ */ jsx3(Text2, { color: "green", bold: true, children: VIEW_LABELS[v] }, v) : /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: VIEW_LABELS[v] }, v)) }),
|
|
836
|
+
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
837
|
+
hints,
|
|
838
|
+
" \xB7 q quit"
|
|
839
|
+
] })
|
|
1398
840
|
] });
|
|
1399
841
|
}
|
|
1400
842
|
|
|
@@ -1406,40 +848,46 @@ function Notification() {
|
|
|
1406
848
|
const { notification } = state;
|
|
1407
849
|
if (!notification || !notification.active) return null;
|
|
1408
850
|
if (notification.autoHideAt && Date.now() > notification.autoHideAt) return null;
|
|
1409
|
-
const
|
|
1410
|
-
const icon = notification.severity === "critical" ? "[!]" : notification.severity === "warning" ? "[!]" : "[>]";
|
|
851
|
+
const color = notification.severity === "critical" ? "red" : notification.severity === "warning" ? "yellow" : "blue";
|
|
1411
852
|
return /* @__PURE__ */ jsxs3(Box3, { paddingX: 1, children: [
|
|
1412
|
-
/* @__PURE__ */ jsx4(Text3, {
|
|
853
|
+
/* @__PURE__ */ jsx4(Text3, { color, bold: true, children: "\u25CF " }),
|
|
854
|
+
/* @__PURE__ */ jsx4(Text3, { children: notification.message }),
|
|
1413
855
|
notification.file && /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
1414
|
-
"
|
|
1415
|
-
notification.file
|
|
1416
|
-
")"
|
|
856
|
+
" ",
|
|
857
|
+
notification.file
|
|
1417
858
|
] })
|
|
1418
859
|
] });
|
|
1419
860
|
}
|
|
1420
861
|
|
|
1421
862
|
// src/cli/dashboard/components/ConfigDialog.tsx
|
|
1422
|
-
import { useState
|
|
863
|
+
import { useState } from "react";
|
|
1423
864
|
import { Box as Box4, Text as Text4, useInput } from "ink";
|
|
1424
|
-
import {
|
|
865
|
+
import { existsSync } from "fs";
|
|
866
|
+
import { rm } from "fs/promises";
|
|
867
|
+
import { join } from "path";
|
|
868
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1425
869
|
function maskKey(key) {
|
|
1426
870
|
if (!key || key.length < 12) return "Not set";
|
|
1427
871
|
return key.slice(0, 7) + "..." + key.slice(-4);
|
|
1428
872
|
}
|
|
1429
873
|
function ConfigDialog({ onClose }) {
|
|
1430
874
|
const { state, dispatch } = useDashboard();
|
|
1431
|
-
const [section, setSection] =
|
|
1432
|
-
const [selectedIndex, setSelectedIndex] =
|
|
1433
|
-
const [editing, setEditing] =
|
|
1434
|
-
const [editBuffer, setEditBuffer] =
|
|
1435
|
-
const [editIsText, setEditIsText] =
|
|
875
|
+
const [section, setSection] = useState("main");
|
|
876
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
877
|
+
const [editing, setEditing] = useState(false);
|
|
878
|
+
const [editBuffer, setEditBuffer] = useState("");
|
|
879
|
+
const [editIsText, setEditIsText] = useState(false);
|
|
880
|
+
const [showConfirmClear, setShowConfirmClear] = useState(false);
|
|
881
|
+
const [clearingMemory, setClearingMemory] = useState(false);
|
|
1436
882
|
const config = state.agentConfig;
|
|
1437
883
|
const currentKeyDisplay = isAIAvailable() ? maskKey(getKeyFromKeychain() || process.env.ANTHROPIC_API_KEY || null) : "Not set";
|
|
1438
884
|
const keyActive = isAIAvailable();
|
|
1439
885
|
const mainMenu = [
|
|
1440
886
|
{ label: "API Keys", key: "apiKeys", value: keyActive ? "Active" : "Not set", section: "main" },
|
|
1441
|
-
{ label: "
|
|
1442
|
-
{ label: "
|
|
887
|
+
{ label: "AI Watcher", key: "aiWatcher", value: config.aiWatcher.enabled ? `${(config.aiWatcher.hourlyTokenLimit / 1e3).toFixed(0)}k/hr` : "Off", section: "main" },
|
|
888
|
+
{ label: "Performance", key: "performance", value: `${config.performance.maxConcurrency} concurrent`, section: "main" },
|
|
889
|
+
{ label: "Risk Thresholds", key: "riskThresholds", value: `critical: ${config.riskThresholds.critical}%`, section: "main" },
|
|
890
|
+
{ label: "Memory", key: "memory", value: "Clear & Reset", section: "main" }
|
|
1443
891
|
];
|
|
1444
892
|
const apiKeysItems = [
|
|
1445
893
|
{ label: "Anthropic", key: "anthropic", value: currentKeyDisplay, section: "apiKeys" }
|
|
@@ -1452,12 +900,41 @@ function ConfigDialog({ onClose }) {
|
|
|
1452
900
|
{ label: "Workers", key: "workers", value: config.performance.workers ? "on" : "off", section: "performance" }
|
|
1453
901
|
];
|
|
1454
902
|
const riskItems = [
|
|
1455
|
-
{ label: "Critical
|
|
1456
|
-
{ label: "High
|
|
1457
|
-
{ label: "Medium
|
|
903
|
+
{ label: "Critical", key: "critical", value: String(config.riskThresholds.critical), section: "riskThresholds" },
|
|
904
|
+
{ label: "High", key: "high", value: String(config.riskThresholds.high), section: "riskThresholds" },
|
|
905
|
+
{ label: "Medium", key: "medium", value: String(config.riskThresholds.medium), section: "riskThresholds" }
|
|
906
|
+
];
|
|
907
|
+
const aiWatcherItems = [
|
|
908
|
+
{ label: "Enabled", key: "enabled", value: config.aiWatcher.enabled ? "on" : "off", section: "aiWatcher" },
|
|
909
|
+
{ label: "Token Budget /hr", key: "hourlyTokenLimit", value: String(config.aiWatcher.hourlyTokenLimit), section: "aiWatcher" },
|
|
910
|
+
{ label: "Scan Cooldown (s)", key: "scanCooldownSec", value: String(config.aiWatcher.scanCooldownSec), section: "aiWatcher" },
|
|
911
|
+
{ label: "Clean Cooldown (s)", key: "cleanFileCooldownSec", value: String(config.aiWatcher.cleanFileCooldownSec), section: "aiWatcher" },
|
|
912
|
+
{ label: "Max Files/Scan", key: "maxFilesPerScan", value: String(config.aiWatcher.maxFilesPerScan), section: "aiWatcher" },
|
|
913
|
+
{ label: "Max Chars/File", key: "maxCharsPerFile", value: String(config.aiWatcher.maxCharsPerFile), section: "aiWatcher" }
|
|
1458
914
|
];
|
|
1459
|
-
const
|
|
915
|
+
const memoryItems = [
|
|
916
|
+
{ label: "Clear All Memory", key: "clearAll", value: "Reset ledger, context graph", section: "memory" }
|
|
917
|
+
];
|
|
918
|
+
const items = section === "main" ? mainMenu : section === "apiKeys" ? apiKeysItems : section === "performance" ? performanceItems : section === "riskThresholds" ? riskItems : section === "aiWatcher" ? aiWatcherItems : section === "memory" ? memoryItems : mainMenu;
|
|
1460
919
|
useInput((_input, key) => {
|
|
920
|
+
if (showConfirmClear) {
|
|
921
|
+
if (_input === "y" || _input === "Y") {
|
|
922
|
+
setClearingMemory(true);
|
|
923
|
+
clearMemory().then(() => {
|
|
924
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Memory cleared successfully" });
|
|
925
|
+
setShowConfirmClear(false);
|
|
926
|
+
setClearingMemory(false);
|
|
927
|
+
setSection("main");
|
|
928
|
+
}).catch(() => {
|
|
929
|
+
dispatch({ type: "ADD_ACTIVITY", message: "Failed to clear memory" });
|
|
930
|
+
setShowConfirmClear(false);
|
|
931
|
+
setClearingMemory(false);
|
|
932
|
+
});
|
|
933
|
+
} else if (_input === "n" || _input === "N" || key.escape) {
|
|
934
|
+
setShowConfirmClear(false);
|
|
935
|
+
}
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
1461
938
|
if (editing) {
|
|
1462
939
|
if (key.escape) {
|
|
1463
940
|
setEditing(false);
|
|
@@ -1481,10 +958,12 @@ function ConfigDialog({ onClose }) {
|
|
|
1481
958
|
}
|
|
1482
959
|
} else if (section === "riskThresholds") {
|
|
1483
960
|
patch.riskThresholds = { ...config.riskThresholds, [item.key]: val };
|
|
961
|
+
} else if (section === "aiWatcher") {
|
|
962
|
+
patch.aiWatcher = { ...config.aiWatcher, [item.key]: val };
|
|
1484
963
|
}
|
|
1485
964
|
if (Object.keys(patch).length > 0) {
|
|
1486
965
|
dispatch({ type: "SET_AGENT_CONFIG", config: patch });
|
|
1487
|
-
dispatch({ type: "ADD_ACTIVITY", message:
|
|
966
|
+
dispatch({ type: "ADD_ACTIVITY", message: `${item.label} set to ${val}` });
|
|
1488
967
|
}
|
|
1489
968
|
}
|
|
1490
969
|
}
|
|
@@ -1524,10 +1003,21 @@ function ConfigDialog({ onClose }) {
|
|
|
1524
1003
|
setEditing(true);
|
|
1525
1004
|
setEditBuffer("");
|
|
1526
1005
|
setEditIsText(true);
|
|
1006
|
+
} else if (section === "memory") {
|
|
1007
|
+
const item = items[selectedIndex];
|
|
1008
|
+
if (item && item.key === "clearAll") {
|
|
1009
|
+
setShowConfirmClear(true);
|
|
1010
|
+
}
|
|
1527
1011
|
} else {
|
|
1528
1012
|
const item = items[selectedIndex];
|
|
1529
1013
|
if (item) {
|
|
1530
|
-
if (
|
|
1014
|
+
if (section === "aiWatcher" && item.key === "enabled") {
|
|
1015
|
+
const patch = {
|
|
1016
|
+
aiWatcher: { ...config.aiWatcher, enabled: !config.aiWatcher.enabled }
|
|
1017
|
+
};
|
|
1018
|
+
dispatch({ type: "SET_AGENT_CONFIG", config: patch });
|
|
1019
|
+
dispatch({ type: "ADD_ACTIVITY", message: `AI Watcher ${!config.aiWatcher.enabled ? "enabled" : "disabled"}` });
|
|
1020
|
+
} else if (["parallel", "cache", "workers"].includes(item.key)) {
|
|
1531
1021
|
const patch = {
|
|
1532
1022
|
performance: { ...config.performance, [item.key]: !config.performance[item.key] }
|
|
1533
1023
|
};
|
|
@@ -1540,53 +1030,76 @@ function ConfigDialog({ onClose }) {
|
|
|
1540
1030
|
}
|
|
1541
1031
|
}
|
|
1542
1032
|
});
|
|
1543
|
-
const sectionTitle = section === "main" ? "
|
|
1544
|
-
|
|
1033
|
+
const sectionTitle = section === "main" ? "Settings" : section === "apiKeys" ? "API Keys" : section === "aiWatcher" ? "AI Watcher" : section === "performance" ? "Performance" : section === "riskThresholds" ? "Risk Thresholds" : section === "memory" ? "Memory" : "Settings";
|
|
1034
|
+
async function clearMemory() {
|
|
1035
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
1036
|
+
const trieDir = getTrieDirectory(workDir);
|
|
1037
|
+
const filesToDelete = [
|
|
1038
|
+
join(trieDir, "context-graph.json"),
|
|
1039
|
+
join(trieDir, "incident-trie.json"),
|
|
1040
|
+
join(trieDir, "memory", "ledger.json"),
|
|
1041
|
+
join(trieDir, "memory", "issue-store.db"),
|
|
1042
|
+
join(trieDir, "memory", "insights.json")
|
|
1043
|
+
];
|
|
1044
|
+
for (const file of filesToDelete) {
|
|
1045
|
+
if (existsSync(file)) {
|
|
1046
|
+
await rm(file, { force: true });
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, children: [
|
|
1545
1051
|
/* @__PURE__ */ jsx5(Text4, { bold: true, children: sectionTitle }),
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
|
|
1052
|
+
showConfirmClear && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1053
|
+
/* @__PURE__ */ jsx5(Text4, { color: "red", bold: true, children: "Clear all memory?" }),
|
|
1054
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Risk hotspots, decisions, incidents, insights" }),
|
|
1055
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Goals, hypotheses, and config are preserved" }),
|
|
1056
|
+
clearingMemory ? /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Clearing..." }) : /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1057
|
+
" ",
|
|
1058
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, children: "y" }),
|
|
1059
|
+
" confirm ",
|
|
1060
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, children: "n" }),
|
|
1061
|
+
" cancel"
|
|
1062
|
+
] })
|
|
1063
|
+
] }),
|
|
1064
|
+
!showConfirmClear && section === "memory" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1065
|
+
/* @__PURE__ */ jsx5(Text4, { children: " Clear All Memory" }),
|
|
1066
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " Reset ledger, context graph, issue store" }),
|
|
1067
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to clear \xB7 esc back" })
|
|
1068
|
+
] }),
|
|
1069
|
+
!showConfirmClear && section === "apiKeys" && !editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1548
1070
|
/* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1549
1071
|
" ",
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
/* @__PURE__ */ jsx5(Text4, { children: currentKeyDisplay }),
|
|
1072
|
+
"Anthropic: ",
|
|
1073
|
+
currentKeyDisplay,
|
|
1553
1074
|
" ",
|
|
1554
1075
|
keyActive ? /* @__PURE__ */ jsx5(Text4, { color: "green", children: "\u25CF Active" }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "\u25CB Not set" })
|
|
1555
1076
|
] }),
|
|
1556
|
-
/* @__PURE__ */ jsx5(Text4, { children: " " })
|
|
1557
|
-
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to update esc back" })
|
|
1077
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter to update \xB7 esc back" })
|
|
1558
1078
|
] }),
|
|
1559
|
-
section === "apiKeys" && editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
1560
|
-
/* @__PURE__ */ jsx5(Box4, { borderStyle: "
|
|
1079
|
+
!showConfirmClear && section === "apiKeys" && editing && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1080
|
+
/* @__PURE__ */ jsx5(Box4, { borderStyle: "single", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1561
1081
|
editBuffer || /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "sk-ant-..." }),
|
|
1562
1082
|
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "|" })
|
|
1563
1083
|
] }) }),
|
|
1084
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
1085
|
+
] }),
|
|
1086
|
+
!showConfirmClear && section !== "apiKeys" && section !== "memory" && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1087
|
+
items.map((item, idx) => {
|
|
1088
|
+
const isSelected = selectedIndex === idx;
|
|
1089
|
+
return /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1090
|
+
isSelected ? /* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "> " }) : " ",
|
|
1091
|
+
/* @__PURE__ */ jsx5(Text4, { bold: isSelected, children: item.label }),
|
|
1092
|
+
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: " " }),
|
|
1093
|
+
editing && isSelected ? /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1094
|
+
editBuffer,
|
|
1095
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "|" })
|
|
1096
|
+
] }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: item.value })
|
|
1097
|
+
] }, item.key);
|
|
1098
|
+
}),
|
|
1564
1099
|
/* @__PURE__ */ jsxs4(Text4, { dimColor: true, children: [
|
|
1565
|
-
"
|
|
1566
|
-
|
|
1567
|
-
") esc cancel"
|
|
1100
|
+
" ",
|
|
1101
|
+
section === "main" ? "enter select \xB7 esc close" : "enter edit \xB7 esc back"
|
|
1568
1102
|
] })
|
|
1569
|
-
] }),
|
|
1570
|
-
section !== "apiKeys" && items.map((item, idx) => {
|
|
1571
|
-
const isSelected = selectedIndex === idx;
|
|
1572
|
-
return /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1573
|
-
isSelected ? /* @__PURE__ */ jsxs4(Text4, { bold: true, color: "green", children: [
|
|
1574
|
-
">",
|
|
1575
|
-
" "
|
|
1576
|
-
] }) : /* @__PURE__ */ jsx5(Text4, { children: " " }),
|
|
1577
|
-
/* @__PURE__ */ jsxs4(Text4, { bold: isSelected, children: [
|
|
1578
|
-
item.label,
|
|
1579
|
-
": "
|
|
1580
|
-
] }),
|
|
1581
|
-
editing && isSelected ? /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
1582
|
-
editBuffer,
|
|
1583
|
-
/* @__PURE__ */ jsx5(Text4, { bold: true, color: "green", children: "|" })
|
|
1584
|
-
] }) : /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: item.value })
|
|
1585
|
-
] }, item.key);
|
|
1586
|
-
}),
|
|
1587
|
-
section !== "apiKeys" && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1588
|
-
/* @__PURE__ */ jsx5(Text4, { children: " " }),
|
|
1589
|
-
/* @__PURE__ */ jsx5(Text4, { dimColor: true, children: section === "main" ? "enter select \xB7 esc close" : "enter edit \xB7 esc/b back" })
|
|
1590
1103
|
] })
|
|
1591
1104
|
] });
|
|
1592
1105
|
}
|
|
@@ -1605,96 +1118,78 @@ function OverviewView() {
|
|
|
1605
1118
|
const startIdx = activityPage * activityRows;
|
|
1606
1119
|
const pageActivities = activityLog.slice(startIdx, startIdx + activityRows);
|
|
1607
1120
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, children: [
|
|
1608
|
-
/* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
elapsed,
|
|
1615
|
-
"s"
|
|
1616
|
-
] })
|
|
1121
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1122
|
+
"Scanned ",
|
|
1123
|
+
watch.filesScannedSession,
|
|
1124
|
+
" files ",
|
|
1125
|
+
elapsed,
|
|
1126
|
+
"s"
|
|
1617
1127
|
] }),
|
|
1618
|
-
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs5(
|
|
1619
|
-
/* @__PURE__ */
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "enabled" })
|
|
1623
|
-
] }),
|
|
1624
|
-
(signalExtraction.decisionsExtracted > 0 || signalExtraction.factsExtracted > 0 || signalExtraction.blockersExtracted > 0) && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1128
|
+
watch.watching && signalExtraction.enabled && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1129
|
+
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CF" }),
|
|
1130
|
+
" Signal extraction",
|
|
1131
|
+
(signalExtraction.decisionsExtracted > 0 || signalExtraction.factsExtracted > 0 || signalExtraction.blockersExtracted > 0) && /* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1625
1132
|
" ",
|
|
1626
|
-
|
|
1627
|
-
" ",
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " facts" }),
|
|
1633
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " \xB7 " }),
|
|
1634
|
-
/* @__PURE__ */ jsx6(Text5, { bold: true, children: signalExtraction.blockersExtracted }),
|
|
1635
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " blockers" })
|
|
1133
|
+
signalExtraction.decisionsExtracted,
|
|
1134
|
+
" decisions \xB7 ",
|
|
1135
|
+
signalExtraction.factsExtracted,
|
|
1136
|
+
" facts \xB7 ",
|
|
1137
|
+
signalExtraction.blockersExtracted,
|
|
1138
|
+
" blockers"
|
|
1636
1139
|
] })
|
|
1637
1140
|
] }),
|
|
1638
|
-
criticalIssues.length > 0 &&
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
"
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
] })
|
|
1653
|
-
] }, i);
|
|
1654
|
-
})
|
|
1655
|
-
] }),
|
|
1141
|
+
criticalIssues.length > 0 && criticalIssues.map((issue, i) => {
|
|
1142
|
+
const filename = issue.file.split("/").pop() || issue.file;
|
|
1143
|
+
const lineNum = issue.line ? `:${issue.line}` : "";
|
|
1144
|
+
return /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1145
|
+
/* @__PURE__ */ jsx6(Text5, { color: "red", children: "\u25CF" }),
|
|
1146
|
+
" ",
|
|
1147
|
+
/* @__PURE__ */ jsx6(Text5, { color: "red", children: issue.issue.slice(0, 55) }),
|
|
1148
|
+
/* @__PURE__ */ jsxs5(Text5, { dimColor: true, children: [
|
|
1149
|
+
" ",
|
|
1150
|
+
filename,
|
|
1151
|
+
lineNum
|
|
1152
|
+
] })
|
|
1153
|
+
] }, i);
|
|
1154
|
+
}),
|
|
1656
1155
|
totalIssues === 0 && criticalIssues.length === 0 && /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1657
1156
|
/* @__PURE__ */ jsx6(Text5, { color: "green", children: "\u25CF" }),
|
|
1658
|
-
" No issues
|
|
1157
|
+
" No issues"
|
|
1659
1158
|
] }),
|
|
1660
1159
|
/* @__PURE__ */ jsx6(Text5, { children: " " }),
|
|
1661
|
-
/* @__PURE__ */
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: entry.time })
|
|
1670
|
-
] }, i)),
|
|
1671
|
-
pageActivities.length === 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " No activity yet." })
|
|
1672
|
-
] })
|
|
1160
|
+
/* @__PURE__ */ jsx6(Text5, { bold: true, children: "Activity" }),
|
|
1161
|
+
pageActivities.map((entry, i) => /* @__PURE__ */ jsxs5(Text5, { children: [
|
|
1162
|
+
" ",
|
|
1163
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, children: entry.time }),
|
|
1164
|
+
" ",
|
|
1165
|
+
entry.message
|
|
1166
|
+
] }, i)),
|
|
1167
|
+
pageActivities.length === 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: " No activity yet" })
|
|
1673
1168
|
] });
|
|
1674
1169
|
}
|
|
1675
1170
|
|
|
1676
1171
|
// src/cli/dashboard/views/AgentView.tsx
|
|
1677
|
-
import { useEffect
|
|
1172
|
+
import { useEffect, useCallback } from "react";
|
|
1678
1173
|
import { Box as Box6, Text as Text6, useInput as useInput2 } from "ink";
|
|
1679
1174
|
|
|
1680
1175
|
// src/cli/dashboard/theme.ts
|
|
1681
|
-
import
|
|
1176
|
+
import pc from "picocolors";
|
|
1682
1177
|
var colors = {
|
|
1683
|
-
border: (s) =>
|
|
1684
|
-
header: (s) =>
|
|
1685
|
-
brand: (s) =>
|
|
1686
|
-
dim: (s) =>
|
|
1687
|
-
critical: (s) =>
|
|
1688
|
-
serious: (s) =>
|
|
1689
|
-
moderate: (s) =>
|
|
1690
|
-
low: (s) =>
|
|
1691
|
-
success: (s) =>
|
|
1692
|
-
running: (s) =>
|
|
1693
|
-
waiting: (s) =>
|
|
1694
|
-
alert: (s) =>
|
|
1695
|
-
selected: (s) =>
|
|
1696
|
-
highlight: (s) =>
|
|
1697
|
-
yellow: (s) =>
|
|
1178
|
+
border: (s) => pc.dim(s),
|
|
1179
|
+
header: (s) => pc.bold(pc.white(s)),
|
|
1180
|
+
brand: (s) => pc.bold(pc.green(s)),
|
|
1181
|
+
dim: (s) => pc.dim(s),
|
|
1182
|
+
critical: (s) => pc.bold(pc.red(s)),
|
|
1183
|
+
serious: (s) => pc.yellow(s),
|
|
1184
|
+
moderate: (s) => pc.blue(s),
|
|
1185
|
+
low: (s) => pc.dim(s),
|
|
1186
|
+
success: (s) => pc.green(s),
|
|
1187
|
+
running: (s) => pc.yellow(s),
|
|
1188
|
+
waiting: (s) => pc.dim(s),
|
|
1189
|
+
alert: (s) => pc.bold(pc.red(s)),
|
|
1190
|
+
selected: (s) => pc.bold(pc.green(s)),
|
|
1191
|
+
highlight: (s) => pc.bold(pc.white(s)),
|
|
1192
|
+
yellow: (s) => pc.yellow(s)
|
|
1698
1193
|
};
|
|
1699
1194
|
function formatTimeAgo(timestamp) {
|
|
1700
1195
|
const seconds = Math.floor((Date.now() - timestamp) / 1e3);
|
|
@@ -1744,26 +1239,21 @@ function AgentView() {
|
|
|
1744
1239
|
dispatch({ type: "ADD_ACTIVITY", message: "Agent brain load error" });
|
|
1745
1240
|
}
|
|
1746
1241
|
}, [dispatch]);
|
|
1747
|
-
|
|
1242
|
+
useEffect(() => {
|
|
1748
1243
|
if (!loaded) {
|
|
1749
1244
|
void loadBrain();
|
|
1750
1245
|
}
|
|
1751
1246
|
}, [loaded, loadBrain]);
|
|
1752
1247
|
useInput2((input, key) => {
|
|
1753
|
-
if (key.upArrow || input === "k") {
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
} else if (key.return) {
|
|
1758
|
-
dispatch({ type: "TOGGLE_INSIGHT", index: selectedInsight });
|
|
1759
|
-
} else if (input === "d") {
|
|
1760
|
-
dispatch({ type: "DISMISS_INSIGHT", index: selectedInsight });
|
|
1761
|
-
}
|
|
1248
|
+
if (key.upArrow || input === "k") dispatch({ type: "NAVIGATE_UP" });
|
|
1249
|
+
else if (key.downArrow || input === "j") dispatch({ type: "NAVIGATE_DOWN" });
|
|
1250
|
+
else if (key.return) dispatch({ type: "TOGGLE_INSIGHT", index: selectedInsight });
|
|
1251
|
+
else if (input === "d") dispatch({ type: "DISMISS_INSIGHT", index: selectedInsight });
|
|
1762
1252
|
});
|
|
1763
1253
|
const alertCount = alerts.length;
|
|
1764
1254
|
const decCount = decisions.length;
|
|
1765
1255
|
const patCount = patterns.length;
|
|
1766
|
-
if (
|
|
1256
|
+
if (!loaded) {
|
|
1767
1257
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
|
|
1768
1258
|
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Nudges" }),
|
|
1769
1259
|
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " Loading..." })
|
|
@@ -1772,108 +1262,80 @@ function AgentView() {
|
|
|
1772
1262
|
if (alertCount === 0 && decCount === 0 && patCount === 0) {
|
|
1773
1263
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
|
|
1774
1264
|
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Nudges" }),
|
|
1775
|
-
/* @__PURE__ */ jsx7(Text6, { children: " " })
|
|
1776
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " No nudges yet." }),
|
|
1777
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " Trie will alert you here when it spots issues in your code." })
|
|
1265
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " No nudges yet. Trie will alert you here when it spots issues." })
|
|
1778
1266
|
] });
|
|
1779
1267
|
}
|
|
1780
|
-
const confidentPatterns = patterns.filter((p) => p.confidence > 0.7).length;
|
|
1781
|
-
const learningPatterns = patterns.filter((p) => p.confidence <= 0.7).length;
|
|
1782
1268
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 1, children: [
|
|
1783
1269
|
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1784
1270
|
/* @__PURE__ */ jsx7(Text6, { bold: true, children: "Nudges" }),
|
|
1785
|
-
" ",
|
|
1786
1271
|
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1787
|
-
alertCount,
|
|
1788
|
-
" alert",
|
|
1789
|
-
alertCount !== 1 ? "s" : "",
|
|
1790
1272
|
" ",
|
|
1273
|
+
alertCount,
|
|
1274
|
+
" alerts \xB7 ",
|
|
1791
1275
|
decCount,
|
|
1792
|
-
"
|
|
1793
|
-
decCount !== 1 ? "s" : "",
|
|
1794
|
-
" ",
|
|
1276
|
+
" decisions \xB7 ",
|
|
1795
1277
|
patCount,
|
|
1796
|
-
"
|
|
1797
|
-
patCount !== 1 ? "s" : ""
|
|
1278
|
+
" patterns"
|
|
1798
1279
|
] })
|
|
1799
1280
|
] }),
|
|
1800
|
-
/* @__PURE__ */ jsx7(
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
" "
|
|
1814
|
-
] }) : /* @__PURE__ */ jsx7(Text6, { children: " " }),
|
|
1815
|
-
riskColor ? /* @__PURE__ */ jsx7(Text6, { color: riskColor, children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1816
|
-
" ",
|
|
1817
|
-
isSelected ? /* @__PURE__ */ jsx7(Text6, { bold: true, children: msg }) : /* @__PURE__ */ jsx7(Text6, { children: msg }),
|
|
1281
|
+
alertCount > 0 && /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", marginTop: 1, children: alerts.map((insight, idx) => {
|
|
1282
|
+
const isSelected = idx === selectedInsight;
|
|
1283
|
+
const isExpanded = idx === expandedInsight;
|
|
1284
|
+
const ago = formatTimeAgo(insight.timestamp);
|
|
1285
|
+
const msg = insight.message.slice(0, 60) + (insight.message.length > 60 ? "..." : "");
|
|
1286
|
+
const riskColor = insight.priority >= 8 ? "red" : insight.priority >= 5 ? "yellow" : void 0;
|
|
1287
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1288
|
+
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1289
|
+
isSelected ? /* @__PURE__ */ jsx7(Text6, { bold: true, color: "green", children: "> " }) : " ",
|
|
1290
|
+
riskColor ? /* @__PURE__ */ jsx7(Text6, { color: riskColor, children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1291
|
+
" ",
|
|
1292
|
+
isSelected ? /* @__PURE__ */ jsx7(Text6, { bold: true, children: msg }) : /* @__PURE__ */ jsx7(Text6, { children: msg }),
|
|
1293
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1818
1294
|
" ",
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
ago
|
|
1823
|
-
] })
|
|
1824
|
-
] }),
|
|
1825
|
-
(isExpanded || isSelected) && insight.suggestedAction && /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1826
|
-
" ",
|
|
1827
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u2192" }),
|
|
1828
|
-
" ",
|
|
1829
|
-
/* @__PURE__ */ jsx7(Text6, { bold: true, children: insight.suggestedAction })
|
|
1295
|
+
insight.category,
|
|
1296
|
+
" \xB7 ",
|
|
1297
|
+
ago
|
|
1830
1298
|
] })
|
|
1831
|
-
] },
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1299
|
+
] }),
|
|
1300
|
+
(isExpanded || isSelected) && insight.suggestedAction && /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1301
|
+
" ",
|
|
1302
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1303
|
+
"->",
|
|
1304
|
+
" "
|
|
1305
|
+
] }),
|
|
1306
|
+
/* @__PURE__ */ jsx7(Text6, { children: insight.suggestedAction })
|
|
1307
|
+
] })
|
|
1308
|
+
] }, insight.id);
|
|
1309
|
+
}) }),
|
|
1310
|
+
decCount > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, children: [
|
|
1311
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " Decisions" }),
|
|
1837
1312
|
decisions.slice(0, 10).map((dec) => {
|
|
1838
1313
|
const ago = timeAgo(dec.when);
|
|
1839
|
-
const hash = dec.hash ? dec.hash.slice(0, 6) : "";
|
|
1840
1314
|
const active = dec.status === "active";
|
|
1841
1315
|
return /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1842
1316
|
" ",
|
|
1843
1317
|
active ? /* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1844
1318
|
" ",
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
] }),
|
|
1849
|
-
" ",
|
|
1850
|
-
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: ago }),
|
|
1851
|
-
hash && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1319
|
+
dec.decision.slice(0, 50),
|
|
1320
|
+
dec.decision.length > 50 ? "..." : "",
|
|
1321
|
+
/* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1852
1322
|
" ",
|
|
1853
|
-
|
|
1323
|
+
ago
|
|
1854
1324
|
] })
|
|
1855
1325
|
] }, dec.id);
|
|
1856
|
-
})
|
|
1857
|
-
/* @__PURE__ */ jsx7(Text6, { children: " " })
|
|
1326
|
+
})
|
|
1858
1327
|
] }),
|
|
1859
|
-
patCount > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
1860
|
-
/* @__PURE__ */ jsx7(Text6, {
|
|
1861
|
-
confidentPatterns > 0 && /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1862
|
-
" ",
|
|
1863
|
-
confidentPatterns,
|
|
1864
|
-
" confident ",
|
|
1865
|
-
learningPatterns,
|
|
1866
|
-
" learning"
|
|
1867
|
-
] }),
|
|
1328
|
+
patCount > 0 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginTop: 1, children: [
|
|
1329
|
+
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: " Patterns" }),
|
|
1868
1330
|
patterns.slice(0, 8).map((pat, idx) => {
|
|
1869
1331
|
const conf = Math.round(pat.confidence * 100);
|
|
1870
1332
|
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
1871
|
-
const desc = pat.description.slice(0, 45) + (pat.description.length > 45 ? "..." : "");
|
|
1872
1333
|
return /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1873
1334
|
" ",
|
|
1874
1335
|
pat.isAntiPattern ? /* @__PURE__ */ jsx7(Text6, { color: "red", children: "\u25CF" }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB" }),
|
|
1875
1336
|
" ",
|
|
1876
|
-
|
|
1337
|
+
pat.description.slice(0, 48),
|
|
1338
|
+
pat.description.length > 48 ? "..." : "",
|
|
1877
1339
|
" ",
|
|
1878
1340
|
confColor ? /* @__PURE__ */ jsxs6(Text6, { color: confColor, children: [
|
|
1879
1341
|
conf,
|
|
@@ -1881,18 +1343,16 @@ function AgentView() {
|
|
|
1881
1343
|
] }) : /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
|
|
1882
1344
|
conf,
|
|
1883
1345
|
"%"
|
|
1884
|
-
] })
|
|
1885
|
-
pat.isAntiPattern && /* @__PURE__ */ jsx7(Text6, { color: "red", children: " anti-pattern" })
|
|
1346
|
+
] })
|
|
1886
1347
|
] }, idx);
|
|
1887
1348
|
})
|
|
1888
1349
|
] }),
|
|
1889
|
-
/* @__PURE__ */
|
|
1890
|
-
/* @__PURE__ */ jsxs6(Box6, { gap: 2, children: [
|
|
1350
|
+
/* @__PURE__ */ jsxs6(Box6, { marginTop: 1, gap: 2, children: [
|
|
1891
1351
|
isAIAvailable() ? /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1892
1352
|
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1893
1353
|
" ",
|
|
1894
1354
|
/* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "AI" })
|
|
1895
|
-
] }) : /* @__PURE__ */ jsx7(Text6, {
|
|
1355
|
+
] }) : /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "\u25CB AI off" }),
|
|
1896
1356
|
agentInsights.filter((i) => i.type === "celebration").length > 0 && /* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1897
1357
|
/* @__PURE__ */ jsx7(Text6, { color: "green", children: "\u25CF" }),
|
|
1898
1358
|
" ",
|
|
@@ -1908,7 +1368,7 @@ function AgentView() {
|
|
|
1908
1368
|
// src/cli/dashboard/views/GoalsView.tsx
|
|
1909
1369
|
import { useCallback as useCallback2 } from "react";
|
|
1910
1370
|
import { Box as Box7, Text as Text7, useInput as useInput3 } from "ink";
|
|
1911
|
-
import { Fragment
|
|
1371
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1912
1372
|
function calculateGoalProgress(goal) {
|
|
1913
1373
|
if (goal.target <= 0) return 0;
|
|
1914
1374
|
const startValue = goal.startValue ?? goal.currentValue;
|
|
@@ -2036,50 +1496,35 @@ function GoalsView() {
|
|
|
2036
1496
|
}
|
|
2037
1497
|
});
|
|
2038
1498
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 1, children: [
|
|
2039
|
-
/* @__PURE__ */
|
|
2040
|
-
|
|
2041
|
-
"
|
|
2042
|
-
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Track progress, achieve targets" })
|
|
2043
|
-
] }),
|
|
2044
|
-
/* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
2045
|
-
goalsPanel.inputMode === "add" ? /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
2046
|
-
/* @__PURE__ */ jsx8(Box7, { borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
1499
|
+
/* @__PURE__ */ jsx8(Text7, { bold: true, children: "Goals" }),
|
|
1500
|
+
goalsPanel.inputMode === "add" ? /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, children: [
|
|
1501
|
+
/* @__PURE__ */ jsx8(Box7, { borderStyle: "single", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2047
1502
|
goalsPanel.inputBuffer,
|
|
2048
1503
|
/* @__PURE__ */ jsx8(Text7, { bold: true, color: "green", children: "|" })
|
|
2049
1504
|
] }) }),
|
|
2050
1505
|
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2051
|
-
] }) : /* @__PURE__ */ jsx8(
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
] }) : /* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
2066
|
-
/* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CB" }),
|
|
1506
|
+
] }) : /* @__PURE__ */ jsx8(Fragment, { children: goalsPanel.goals.length === 0 ? /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " No goals yet. Press a to add one." }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1507
|
+
activeGoals.map((goal, idx) => {
|
|
1508
|
+
const isSelected = goalsPanel.selectedIndex === idx;
|
|
1509
|
+
const progress = calculateGoalProgress(goal);
|
|
1510
|
+
const bar = progressBar(progress, 100, 8);
|
|
1511
|
+
const source = goal.autoGenerated ? "auto" : "";
|
|
1512
|
+
return /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
1513
|
+
isSelected ? /* @__PURE__ */ jsx8(Text7, { bold: true, color: "green", children: "> " }) : " ",
|
|
1514
|
+
/* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CB" }),
|
|
1515
|
+
" ",
|
|
1516
|
+
goal.description.slice(0, 45),
|
|
1517
|
+
/* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
|
|
1518
|
+
" ",
|
|
1519
|
+
bar,
|
|
2067
1520
|
" ",
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
progress,
|
|
2076
|
-
"%"
|
|
2077
|
-
] })
|
|
2078
|
-
] }, goal.id);
|
|
2079
|
-
}),
|
|
2080
|
-
/* @__PURE__ */ jsx8(Text7, { children: " " })
|
|
2081
|
-
] }),
|
|
2082
|
-
achievedGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1521
|
+
progress,
|
|
1522
|
+
"%",
|
|
1523
|
+
source ? ` ${source}` : ""
|
|
1524
|
+
] })
|
|
1525
|
+
] }, goal.id);
|
|
1526
|
+
}),
|
|
1527
|
+
achievedGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, children: [
|
|
2083
1528
|
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " Achieved" }),
|
|
2084
1529
|
achievedGoals.slice(0, 5).map((g) => /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2085
1530
|
" ",
|
|
@@ -2091,20 +1536,17 @@ function GoalsView() {
|
|
|
2091
1536
|
" +",
|
|
2092
1537
|
achievedGoals.length - 5,
|
|
2093
1538
|
" more"
|
|
2094
|
-
] })
|
|
2095
|
-
/* @__PURE__ */ jsx8(Text7, { children: " " })
|
|
1539
|
+
] })
|
|
2096
1540
|
] }),
|
|
2097
|
-
otherGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1541
|
+
otherGoals.length > 0 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, children: [
|
|
2098
1542
|
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: " Other" }),
|
|
2099
1543
|
otherGoals.slice(0, 2).map((g) => /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
2100
1544
|
" ",
|
|
2101
1545
|
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "\u25CB" }),
|
|
2102
1546
|
" ",
|
|
2103
1547
|
g.description.slice(0, 50),
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
g.status
|
|
2107
|
-
] })
|
|
1548
|
+
" ",
|
|
1549
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: g.status })
|
|
2108
1550
|
] }, g.id))
|
|
2109
1551
|
] })
|
|
2110
1552
|
] }) })
|
|
@@ -2114,7 +1556,7 @@ function GoalsView() {
|
|
|
2114
1556
|
// src/cli/dashboard/views/HypothesesView.tsx
|
|
2115
1557
|
import { useCallback as useCallback3 } from "react";
|
|
2116
1558
|
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
2117
|
-
import { Fragment as
|
|
1559
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2118
1560
|
function HypothesesView() {
|
|
2119
1561
|
const { state, dispatch } = useDashboard();
|
|
2120
1562
|
const { hypothesesPanel } = state;
|
|
@@ -2218,46 +1660,32 @@ function HypothesesView() {
|
|
|
2218
1660
|
}
|
|
2219
1661
|
});
|
|
2220
1662
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 1, children: [
|
|
2221
|
-
/* @__PURE__ */
|
|
2222
|
-
|
|
2223
|
-
"
|
|
2224
|
-
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Test theories about your codebase" })
|
|
2225
|
-
] }),
|
|
2226
|
-
/* @__PURE__ */ jsx9(Text8, { children: " " }),
|
|
2227
|
-
hypothesesPanel.inputMode === "add" ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
2228
|
-
/* @__PURE__ */ jsx9(Box8, { borderStyle: "round", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
1663
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, children: "Hypotheses" }),
|
|
1664
|
+
hypothesesPanel.inputMode === "add" ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
1665
|
+
/* @__PURE__ */ jsx9(Box8, { borderStyle: "single", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2229
1666
|
hypothesesPanel.inputBuffer,
|
|
2230
1667
|
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "|" })
|
|
2231
1668
|
] }) }),
|
|
2232
1669
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " enter save \xB7 esc cancel" })
|
|
2233
|
-
] }) : /* @__PURE__ */ jsx9(
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
" "
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
"% \xB7 ",
|
|
2253
|
-
hypo.evidenceCount,
|
|
2254
|
-
" evidence"
|
|
2255
|
-
] })
|
|
2256
|
-
] }) }, hypo.id);
|
|
2257
|
-
}),
|
|
2258
|
-
/* @__PURE__ */ jsx9(Text8, { children: " " })
|
|
2259
|
-
] }),
|
|
2260
|
-
validated.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1670
|
+
] }) : /* @__PURE__ */ jsx9(Fragment2, { children: hypothesesPanel.hypotheses.length === 0 ? /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " No hypotheses yet. Press a to add one." }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1671
|
+
testing.map((hypo, idx) => {
|
|
1672
|
+
const isSelected = hypothesesPanel.selectedIndex === idx;
|
|
1673
|
+
const conf = Math.round(hypo.confidence * 100);
|
|
1674
|
+
return /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
1675
|
+
isSelected ? /* @__PURE__ */ jsx9(Text8, { bold: true, color: "green", children: "> " }) : " ",
|
|
1676
|
+
/* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "\u25CB" }),
|
|
1677
|
+
" ",
|
|
1678
|
+
hypo.statement.slice(0, 50),
|
|
1679
|
+
/* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
1680
|
+
" ",
|
|
1681
|
+
conf,
|
|
1682
|
+
"% \xB7 ",
|
|
1683
|
+
hypo.evidenceCount,
|
|
1684
|
+
" evidence"
|
|
1685
|
+
] })
|
|
1686
|
+
] }, hypo.id);
|
|
1687
|
+
}),
|
|
1688
|
+
validated.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
2261
1689
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Validated" }),
|
|
2262
1690
|
validated.slice(0, 3).map((h) => /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2263
1691
|
" ",
|
|
@@ -2269,10 +1697,9 @@ function HypothesesView() {
|
|
|
2269
1697
|
" +",
|
|
2270
1698
|
validated.length - 3,
|
|
2271
1699
|
" more"
|
|
2272
|
-
] })
|
|
2273
|
-
/* @__PURE__ */ jsx9(Text8, { children: " " })
|
|
1700
|
+
] })
|
|
2274
1701
|
] }),
|
|
2275
|
-
invalidated.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1702
|
+
invalidated.length > 0 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
2276
1703
|
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: " Invalidated" }),
|
|
2277
1704
|
invalidated.slice(0, 2).map((h) => /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
2278
1705
|
" ",
|
|
@@ -2291,9 +1718,9 @@ function HypothesesView() {
|
|
|
2291
1718
|
}
|
|
2292
1719
|
|
|
2293
1720
|
// src/cli/dashboard/views/MemoryTreeView.tsx
|
|
2294
|
-
import { useEffect as
|
|
1721
|
+
import { useEffect as useEffect2, useCallback as useCallback4 } from "react";
|
|
2295
1722
|
import { Box as Box9, Text as Text9, useInput as useInput5 } from "ink";
|
|
2296
|
-
import { Fragment as
|
|
1723
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2297
1724
|
function timeAgo2(iso) {
|
|
2298
1725
|
const ms = Date.now() - new Date(iso).getTime();
|
|
2299
1726
|
const mins = Math.floor(ms / 6e4);
|
|
@@ -2319,7 +1746,7 @@ function MemoryTreeView() {
|
|
|
2319
1746
|
dispatch({ type: "ADD_ACTIVITY", message: "Context graph load error" });
|
|
2320
1747
|
}
|
|
2321
1748
|
}, [dispatch]);
|
|
2322
|
-
|
|
1749
|
+
useEffect2(() => {
|
|
2323
1750
|
if (!loaded) {
|
|
2324
1751
|
void loadData();
|
|
2325
1752
|
}
|
|
@@ -2339,9 +1766,7 @@ function MemoryTreeView() {
|
|
|
2339
1766
|
if (!snapshot || snapshot.nodes.length === 0 && globalPatterns.length === 0) {
|
|
2340
1767
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, children: [
|
|
2341
1768
|
/* @__PURE__ */ jsx10(Text9, { bold: true, children: "Ledger" }),
|
|
2342
|
-
/* @__PURE__ */ jsx10(Text9, { children: " " })
|
|
2343
|
-
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " No entries yet." }),
|
|
2344
|
-
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " Use trie tell, trie ok/bad, or trie watch to build memory." })
|
|
1769
|
+
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: " No entries yet. Use trie tell or trie watch to build memory." })
|
|
2345
1770
|
] });
|
|
2346
1771
|
}
|
|
2347
1772
|
const decisionNodes = snapshot.nodes.filter((n) => n.type === "decision") ?? [];
|
|
@@ -2356,91 +1781,81 @@ function MemoryTreeView() {
|
|
|
2356
1781
|
function renderHeader(id, label, count, emptyHint) {
|
|
2357
1782
|
const expanded = expandedNodes.has(id);
|
|
2358
1783
|
const isEmpty = count === 0;
|
|
2359
|
-
return /* @__PURE__ */ jsxs9(
|
|
2360
|
-
/* @__PURE__ */
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
1784
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
1785
|
+
sel(id) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
1786
|
+
expanded && !isEmpty ? /* @__PURE__ */ jsx10(Text9, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
1787
|
+
" ",
|
|
1788
|
+
sel(id) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: label }) : /* @__PURE__ */ jsx10(Text9, { bold: true, children: label }),
|
|
1789
|
+
count > 0 ? /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
1790
|
+
" (",
|
|
1791
|
+
count,
|
|
1792
|
+
")"
|
|
1793
|
+
] }) : isEmpty && emptyHint ? /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2366
1794
|
" ",
|
|
2367
|
-
sel(id) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: label }) : /* @__PURE__ */ jsx10(Text9, { bold: true, children: label }),
|
|
2368
|
-
count > 0 ? /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2369
|
-
" (",
|
|
2370
|
-
count,
|
|
2371
|
-
")"
|
|
2372
|
-
] }) : null
|
|
2373
|
-
] }),
|
|
2374
|
-
isEmpty && emptyHint && /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2375
|
-
" ",
|
|
2376
1795
|
emptyHint
|
|
2377
|
-
] })
|
|
1796
|
+
] }) : null
|
|
2378
1797
|
] });
|
|
2379
1798
|
}
|
|
2380
1799
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", paddingX: 1, children: [
|
|
2381
1800
|
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2382
1801
|
/* @__PURE__ */ jsx10(Text9, { bold: true, children: "Ledger" }),
|
|
2383
|
-
" ",
|
|
2384
1802
|
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
1803
|
+
" ",
|
|
2385
1804
|
totalEntries,
|
|
2386
1805
|
" entries"
|
|
2387
1806
|
] })
|
|
2388
1807
|
] }),
|
|
2389
|
-
/* @__PURE__ */
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
"
|
|
2398
|
-
" "
|
|
2399
|
-
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2400
|
-
" ",
|
|
2401
|
-
outcomeColor ? /* @__PURE__ */ jsx10(Text9, { color: outcomeColor, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2402
|
-
" ",
|
|
2403
|
-
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: dec }) : /* @__PURE__ */ jsx10(Text9, { children: dec }),
|
|
2404
|
-
" ",
|
|
2405
|
-
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: timeAgo2(n.data.timestamp) }),
|
|
2406
|
-
outcomeColor ? /* @__PURE__ */ jsxs9(Text9, { color: outcomeColor, children: [
|
|
1808
|
+
/* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginTop: 1, children: [
|
|
1809
|
+
renderHeader("decisions", "Decisions", decisionNodes.length, "-- use trie tell or chat"),
|
|
1810
|
+
expandedNodes.has("decisions") && decisionNodes.slice(0, 10).map((n) => {
|
|
1811
|
+
const nodeId = `decision-${n.id}`;
|
|
1812
|
+
const dec = n.data.decision.length > 55 ? n.data.decision.slice(0, 52) + "..." : n.data.decision;
|
|
1813
|
+
const outcomeColor = n.data.outcome === "good" ? "green" : n.data.outcome === "bad" ? "red" : void 0;
|
|
1814
|
+
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
1815
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
1816
|
+
" ",
|
|
1817
|
+
outcomeColor ? /* @__PURE__ */ jsx10(Text9, { color: outcomeColor, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2407
1818
|
" ",
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
1819
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: dec }) : /* @__PURE__ */ jsx10(Text9, { children: dec }),
|
|
1820
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
1821
|
+
" ",
|
|
1822
|
+
timeAgo2(n.data.timestamp)
|
|
1823
|
+
] }),
|
|
1824
|
+
outcomeColor ? /* @__PURE__ */ jsxs9(Text9, { color: outcomeColor, children: [
|
|
1825
|
+
" ",
|
|
1826
|
+
n.data.outcome
|
|
1827
|
+
] }) : null
|
|
1828
|
+
] }, n.id);
|
|
1829
|
+
})
|
|
1830
|
+
] }),
|
|
1831
|
+
renderHeader("incidents", "Incidents", incidentNodes.length, "-- use trie tell"),
|
|
2413
1832
|
expandedNodes.has("incidents") && incidentNodes.slice(0, 10).map((n) => {
|
|
2414
1833
|
const nodeId = `incident-${n.id}`;
|
|
2415
1834
|
const sevColor = n.data.severity === "critical" ? "red" : n.data.severity === "major" ? "yellow" : void 0;
|
|
2416
1835
|
const desc = n.data.description.length > 55 ? n.data.description.slice(0, 52) + "..." : n.data.description;
|
|
2417
1836
|
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2418
|
-
sel(nodeId) ? /* @__PURE__ */
|
|
2419
|
-
|
|
2420
|
-
" "
|
|
2421
|
-
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2422
|
-
" ",
|
|
1837
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
1838
|
+
" ",
|
|
2423
1839
|
sevColor ? /* @__PURE__ */ jsx10(Text9, { color: sevColor, children: "\u25CF" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2424
1840
|
" ",
|
|
2425
1841
|
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx10(Text9, { children: desc }),
|
|
2426
|
-
|
|
2427
|
-
|
|
1842
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
1843
|
+
" ",
|
|
1844
|
+
timeAgo2(n.data.timestamp)
|
|
1845
|
+
] }),
|
|
2428
1846
|
" ",
|
|
2429
1847
|
n.data.resolved ? /* @__PURE__ */ jsx10(Text9, { color: "green", children: "resolved" }) : /* @__PURE__ */ jsx10(Text9, { color: "yellow", children: "open" })
|
|
2430
1848
|
] }, n.id);
|
|
2431
1849
|
}),
|
|
2432
|
-
renderHeader("patterns", "Learned Patterns", patternNodes.length, "
|
|
1850
|
+
renderHeader("patterns", "Learned Patterns", patternNodes.length, "-- Trie learns as you work"),
|
|
2433
1851
|
expandedNodes.has("patterns") && patternNodes.slice(0, 10).map((n) => {
|
|
2434
1852
|
const nodeId = `pattern-${n.id}`;
|
|
2435
1853
|
const conf = Math.round(n.data.confidence * 100);
|
|
2436
1854
|
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
2437
1855
|
const desc = n.data.description.length > 50 ? n.data.description.slice(0, 47) + "..." : n.data.description;
|
|
2438
1856
|
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2439
|
-
sel(nodeId) ? /* @__PURE__ */
|
|
2440
|
-
|
|
2441
|
-
" "
|
|
2442
|
-
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2443
|
-
" ",
|
|
1857
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
1858
|
+
" ",
|
|
2444
1859
|
n.data.isAntiPattern ? /* @__PURE__ */ jsx10(Text9, { color: "red", children: "!" }) : /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2445
1860
|
" ",
|
|
2446
1861
|
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx10(Text9, { children: desc }),
|
|
@@ -2451,8 +1866,7 @@ function MemoryTreeView() {
|
|
|
2451
1866
|
] }) : /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2452
1867
|
conf,
|
|
2453
1868
|
"%"
|
|
2454
|
-
] })
|
|
2455
|
-
n.data.isAntiPattern && /* @__PURE__ */ jsx10(Text9, { color: "red", children: " anti-pattern" })
|
|
1869
|
+
] })
|
|
2456
1870
|
] }, n.id);
|
|
2457
1871
|
}),
|
|
2458
1872
|
renderHeader("cross-project", "Cross-Project", globalPatterns.length),
|
|
@@ -2460,16 +1874,13 @@ function MemoryTreeView() {
|
|
|
2460
1874
|
const patternId = `global-${pattern.id}`;
|
|
2461
1875
|
const desc = pattern.pattern.length > 45 ? pattern.pattern.slice(0, 42) + "..." : pattern.pattern;
|
|
2462
1876
|
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2463
|
-
sel(patternId) ? /* @__PURE__ */
|
|
2464
|
-
|
|
2465
|
-
" "
|
|
2466
|
-
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2467
|
-
" ",
|
|
1877
|
+
sel(patternId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
1878
|
+
" ",
|
|
2468
1879
|
/* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "\u25CB" }),
|
|
2469
1880
|
" ",
|
|
2470
1881
|
sel(patternId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx10(Text9, { children: desc }),
|
|
2471
|
-
" ",
|
|
2472
1882
|
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
1883
|
+
" ",
|
|
2473
1884
|
pattern.projects.length,
|
|
2474
1885
|
" projects \xB7 ",
|
|
2475
1886
|
pattern.occurrences,
|
|
@@ -2477,31 +1888,24 @@ function MemoryTreeView() {
|
|
|
2477
1888
|
] })
|
|
2478
1889
|
] }, pattern.id);
|
|
2479
1890
|
}),
|
|
2480
|
-
hotspots.length > 0 && /* @__PURE__ */ jsxs9(
|
|
1891
|
+
hotspots.length > 0 && /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
2481
1892
|
renderHeader("hotspots", "Risk Hotspots", hotspots.length),
|
|
2482
1893
|
expandedNodes.has("hotspots") && hotspots.slice(0, 10).map((n) => {
|
|
2483
1894
|
const nodeId = `file-${n.id}`;
|
|
2484
1895
|
const path2 = n.data.path.split("/").slice(-2).join("/");
|
|
2485
1896
|
const isCritical = n.data.riskLevel === "critical";
|
|
2486
1897
|
return /* @__PURE__ */ jsxs9(Text9, { children: [
|
|
2487
|
-
sel(nodeId) ? /* @__PURE__ */
|
|
2488
|
-
|
|
2489
|
-
" "
|
|
2490
|
-
] }) : /* @__PURE__ */ jsx10(Text9, { children: " " }),
|
|
2491
|
-
" ",
|
|
1898
|
+
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: "> " }) : " ",
|
|
1899
|
+
" ",
|
|
2492
1900
|
/* @__PURE__ */ jsx10(Text9, { color: isCritical ? "red" : "yellow", children: "\u25CF" }),
|
|
2493
1901
|
" ",
|
|
2494
1902
|
sel(nodeId) ? /* @__PURE__ */ jsx10(Text9, { bold: true, color: "green", children: path2 }) : /* @__PURE__ */ jsx10(Text9, { children: path2 }),
|
|
2495
1903
|
" ",
|
|
2496
1904
|
/* @__PURE__ */ jsx10(Text9, { color: isCritical ? "red" : "yellow", children: n.data.riskLevel }),
|
|
2497
|
-
" ",
|
|
2498
1905
|
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
1906
|
+
" ",
|
|
2499
1907
|
n.data.changeCount,
|
|
2500
1908
|
" changes"
|
|
2501
|
-
] }),
|
|
2502
|
-
n.data.whyRisky && /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
2503
|
-
" ",
|
|
2504
|
-
n.data.whyRisky
|
|
2505
1909
|
] })
|
|
2506
1910
|
] }, n.id);
|
|
2507
1911
|
})
|
|
@@ -2515,43 +1919,37 @@ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
|
2515
1919
|
function RawLogView() {
|
|
2516
1920
|
const { state, dispatch } = useDashboard();
|
|
2517
1921
|
const { rawLog, rawLogPage } = state;
|
|
2518
|
-
const pageSize = Math.max(10, (process.stdout.rows || 40) -
|
|
1922
|
+
const pageSize = Math.max(10, (process.stdout.rows || 40) - 10);
|
|
2519
1923
|
const totalPages = Math.max(1, Math.ceil(rawLog.length / pageSize));
|
|
2520
1924
|
useInput6((input, _key) => {
|
|
2521
|
-
if (input === "n") {
|
|
2522
|
-
|
|
2523
|
-
} else if (input === "p") {
|
|
2524
|
-
dispatch({ type: "SET_RAW_LOG_PAGE", page: Math.max(0, rawLogPage - 1) });
|
|
2525
|
-
}
|
|
1925
|
+
if (input === "n") dispatch({ type: "SET_RAW_LOG_PAGE", page: Math.min(totalPages - 1, rawLogPage + 1) });
|
|
1926
|
+
else if (input === "p") dispatch({ type: "SET_RAW_LOG_PAGE", page: Math.max(0, rawLogPage - 1) });
|
|
2526
1927
|
});
|
|
2527
1928
|
const startIdx = rawLogPage * pageSize;
|
|
2528
1929
|
const logs = rawLog.slice(startIdx, startIdx + pageSize);
|
|
2529
1930
|
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", paddingX: 1, children: [
|
|
2530
1931
|
/* @__PURE__ */ jsxs10(Text10, { children: [
|
|
2531
1932
|
/* @__PURE__ */ jsx11(Text10, { bold: true, children: "Log" }),
|
|
2532
|
-
" ",
|
|
2533
1933
|
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
2534
|
-
"
|
|
1934
|
+
" ",
|
|
1935
|
+
rawLog.length,
|
|
1936
|
+
" entries \xB7 page ",
|
|
2535
1937
|
rawLogPage + 1,
|
|
2536
1938
|
"/",
|
|
2537
1939
|
totalPages
|
|
2538
|
-
] })
|
|
2539
|
-
" ",
|
|
2540
|
-
/* @__PURE__ */ jsx11(Text10, { bold: true, children: rawLog.length }),
|
|
2541
|
-
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " entries" })
|
|
1940
|
+
] })
|
|
2542
1941
|
] }),
|
|
2543
|
-
/* @__PURE__ */ jsx11(Text10, { children: " " }),
|
|
2544
|
-
rawLog.length === 0 ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " No log entries yet." }) : /* @__PURE__ */ jsx11(Box10, { flexDirection: "column", children: logs.map((entry, i) => {
|
|
1942
|
+
rawLog.length === 0 ? /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: " No log entries yet" }) : logs.map((entry, i) => {
|
|
2545
1943
|
const dot = entry.level === "error" ? /* @__PURE__ */ jsx11(Text10, { color: "red", children: "\u25CF" }) : entry.level === "warn" ? /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "\u25CF" }) : entry.level === "info" ? /* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u25CF" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" });
|
|
2546
1944
|
return /* @__PURE__ */ jsxs10(Text10, { children: [
|
|
1945
|
+
" ",
|
|
1946
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: entry.time }),
|
|
2547
1947
|
" ",
|
|
2548
1948
|
dot,
|
|
2549
1949
|
" ",
|
|
2550
|
-
entry.message.slice(0, 70)
|
|
2551
|
-
" ",
|
|
2552
|
-
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: entry.time })
|
|
1950
|
+
entry.message.slice(0, 70)
|
|
2553
1951
|
] }, i);
|
|
2554
|
-
})
|
|
1952
|
+
})
|
|
2555
1953
|
] });
|
|
2556
1954
|
}
|
|
2557
1955
|
|
|
@@ -3313,7 +2711,7 @@ var TrieCheckTool = class {
|
|
|
3313
2711
|
|
|
3314
2712
|
// src/tools/explain.ts
|
|
3315
2713
|
import { readFile } from "fs/promises";
|
|
3316
|
-
import { existsSync } from "fs";
|
|
2714
|
+
import { existsSync as existsSync2 } from "fs";
|
|
3317
2715
|
import { extname, relative, resolve, isAbsolute } from "path";
|
|
3318
2716
|
|
|
3319
2717
|
// src/ai/prompts.ts
|
|
@@ -4242,7 +3640,7 @@ var TrieExplainTool = class {
|
|
|
4242
3640
|
let language;
|
|
4243
3641
|
const workDir = getWorkingDirectory(void 0, true);
|
|
4244
3642
|
const resolvedPath = isAbsolute(target) ? target : resolve(workDir, target);
|
|
4245
|
-
if (
|
|
3643
|
+
if (existsSync2(resolvedPath)) {
|
|
4246
3644
|
code = await readFile(resolvedPath, "utf-8");
|
|
4247
3645
|
filePath = relative(workDir, resolvedPath);
|
|
4248
3646
|
language = this.detectLanguage(resolvedPath);
|
|
@@ -4351,7 +3749,7 @@ ${"\u2500".repeat(60)}
|
|
|
4351
3749
|
else if (/moderate|warning/i.test(issue)) severity = "moderate";
|
|
4352
3750
|
else severity = "low";
|
|
4353
3751
|
let codeContext = "";
|
|
4354
|
-
if (file &&
|
|
3752
|
+
if (file && existsSync2(file)) {
|
|
4355
3753
|
const content = await readFile(file, "utf-8");
|
|
4356
3754
|
const lines = content.split("\n");
|
|
4357
3755
|
const start = Math.max(0, line - 5);
|
|
@@ -4464,7 +3862,7 @@ ${"\u2501".repeat(60)}
|
|
|
4464
3862
|
output += `${"\u2501".repeat(60)}
|
|
4465
3863
|
|
|
4466
3864
|
`;
|
|
4467
|
-
if (
|
|
3865
|
+
if (existsSync2(resolvedPath)) {
|
|
4468
3866
|
const code = await readFile(resolvedPath, "utf-8");
|
|
4469
3867
|
const filePath = relative(workDir, resolvedPath);
|
|
4470
3868
|
const riskIndicators = this.detectRiskIndicators(code);
|
|
@@ -5394,74 +4792,40 @@ ${contextBlock}`;
|
|
|
5394
4792
|
});
|
|
5395
4793
|
if (!isAIAvailable()) {
|
|
5396
4794
|
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
5397
|
-
/* @__PURE__ */
|
|
5398
|
-
|
|
5399
|
-
" ",
|
|
5400
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Ask Trie anything" })
|
|
5401
|
-
] }),
|
|
5402
|
-
/* @__PURE__ */ jsx12(Text11, { children: " " }),
|
|
5403
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " AI is not available." }),
|
|
5404
|
-
/* @__PURE__ */ jsxs11(Text11, { children: [
|
|
5405
|
-
" ",
|
|
5406
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Press" }),
|
|
5407
|
-
" ",
|
|
5408
|
-
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "s" }),
|
|
5409
|
-
" ",
|
|
5410
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "to open settings and add your Anthropic API key," })
|
|
5411
|
-
] }),
|
|
5412
|
-
/* @__PURE__ */ jsxs11(Text11, { children: [
|
|
5413
|
-
" ",
|
|
5414
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "or set" }),
|
|
5415
|
-
" ",
|
|
5416
|
-
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "ANTHROPIC_API_KEY" }),
|
|
5417
|
-
" ",
|
|
5418
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "in your environment." })
|
|
5419
|
-
] })
|
|
4795
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "Chat" }),
|
|
4796
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " AI is not available. Press s to open settings and add your Anthropic API key." })
|
|
5420
4797
|
] });
|
|
5421
4798
|
}
|
|
5422
4799
|
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
5423
|
-
/* @__PURE__ */
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Ask Trie anything" })
|
|
5427
|
-
] }),
|
|
5428
|
-
/* @__PURE__ */ jsx12(Text11, { children: " " }),
|
|
5429
|
-
messages.length === 0 && !loading && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
5430
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " Ask about your codebase, decisions, patterns, or risks." }),
|
|
5431
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: ' Trie can also take actions \u2014 try "check src/auth" or "record an incident".' }),
|
|
5432
|
-
/* @__PURE__ */ jsx12(Text11, { children: " " })
|
|
5433
|
-
] }),
|
|
5434
|
-
messages.map((msg, idx) => /* @__PURE__ */ jsx12(Box11, { flexDirection: "column", marginBottom: 1, children: msg.role === "user" ? /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
4800
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "Chat" }),
|
|
4801
|
+
messages.length === 0 && !loading && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " Ask about your codebase, decisions, patterns, or risks." }),
|
|
4802
|
+
messages.map((msg, idx) => /* @__PURE__ */ jsx12(Box11, { flexDirection: "column", marginTop: idx === 0 ? 1 : 0, marginBottom: 1, children: msg.role === "user" ? /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
5435
4803
|
" ",
|
|
5436
4804
|
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "green", children: "You:" }),
|
|
5437
4805
|
" ",
|
|
5438
4806
|
msg.content
|
|
5439
4807
|
] }) : /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
5440
|
-
msg.toolCalls && msg.toolCalls.length > 0 &&
|
|
4808
|
+
msg.toolCalls && msg.toolCalls.length > 0 && msg.toolCalls.map((tc, ti) => /* @__PURE__ */ jsxs11(Text11, { dimColor: true, children: [
|
|
5441
4809
|
" ",
|
|
5442
4810
|
/* @__PURE__ */ jsxs11(Text11, { color: "yellow", children: [
|
|
5443
|
-
"[
|
|
4811
|
+
"[",
|
|
5444
4812
|
tc.name,
|
|
5445
4813
|
"]"
|
|
5446
4814
|
] }),
|
|
5447
4815
|
" ",
|
|
5448
4816
|
formatToolInput(tc.input)
|
|
5449
|
-
] }, ti))
|
|
4817
|
+
] }, ti)),
|
|
5450
4818
|
msg.content.split("\n").map((line, li) => /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
5451
|
-
li === 0 ?
|
|
4819
|
+
li === 0 ? " Trie: " : " ",
|
|
5452
4820
|
line
|
|
5453
4821
|
] }, li))
|
|
5454
4822
|
] }) }, idx)),
|
|
5455
|
-
loading && /* @__PURE__ */
|
|
5456
|
-
" ",
|
|
5457
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Thinking..." })
|
|
5458
|
-
] }),
|
|
4823
|
+
loading && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " Thinking..." }),
|
|
5459
4824
|
/* @__PURE__ */ jsx12(Box11, { flexGrow: 1 }),
|
|
5460
|
-
/* @__PURE__ */ jsx12(Box11, { borderStyle: "
|
|
4825
|
+
/* @__PURE__ */ jsx12(Box11, { borderStyle: "single", borderColor: "green", paddingX: 1, children: /* @__PURE__ */ jsxs11(Text11, { children: [
|
|
5461
4826
|
inputBuffer || /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "Ask a question..." }),
|
|
5462
4827
|
/* @__PURE__ */ jsx12(Text11, { bold: true, color: "green", children: "|" })
|
|
5463
|
-
] }) })
|
|
5464
|
-
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: " enter send esc clear" })
|
|
4828
|
+
] }) })
|
|
5465
4829
|
] });
|
|
5466
4830
|
}
|
|
5467
4831
|
function formatToolInput(input) {
|
|
@@ -5480,14 +4844,14 @@ var MAIN_VIEWS = ["overview", "memory", "goals", "hypotheses", "agent", "chat"];
|
|
|
5480
4844
|
function DashboardApp({ onReady }) {
|
|
5481
4845
|
const { state, dispatch } = useDashboard();
|
|
5482
4846
|
const { exit } = useApp();
|
|
5483
|
-
const [showConfig, setShowConfig] =
|
|
4847
|
+
const [showConfig, setShowConfig] = useState2(false);
|
|
5484
4848
|
const dispatchRef = useRef2(dispatch);
|
|
5485
4849
|
dispatchRef.current = dispatch;
|
|
5486
4850
|
const stateRef = useRef2(state);
|
|
5487
4851
|
stateRef.current = state;
|
|
5488
|
-
const configPath =
|
|
4852
|
+
const configPath = join2(getTrieDirectory(getWorkingDirectory(void 0, true)), "agent.json");
|
|
5489
4853
|
const loadConfig = useCallback6(async () => {
|
|
5490
|
-
if (!
|
|
4854
|
+
if (!existsSync3(configPath)) return;
|
|
5491
4855
|
try {
|
|
5492
4856
|
const raw = await readFile2(configPath, "utf-8");
|
|
5493
4857
|
const parsed = JSON.parse(raw);
|
|
@@ -5497,8 +4861,13 @@ function DashboardApp({ onReady }) {
|
|
|
5497
4861
|
}, [configPath]);
|
|
5498
4862
|
const persistConfig = useCallback6(async () => {
|
|
5499
4863
|
try {
|
|
5500
|
-
|
|
4864
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
4865
|
+
await mkdir(getTrieDirectory(workDir), { recursive: true });
|
|
5501
4866
|
await writeFile(configPath, JSON.stringify(stateRef.current.agentConfig, null, 2), "utf-8");
|
|
4867
|
+
const { saveAutonomyConfig, loadAutonomyConfig } = await import("./autonomy-config-JXB7WCZ2.js");
|
|
4868
|
+
const autonomy = await loadAutonomyConfig(workDir);
|
|
4869
|
+
autonomy.aiWatcher = stateRef.current.agentConfig.aiWatcher;
|
|
4870
|
+
await saveAutonomyConfig(workDir, autonomy);
|
|
5502
4871
|
} catch {
|
|
5503
4872
|
}
|
|
5504
4873
|
}, [configPath]);
|
|
@@ -5560,7 +4929,7 @@ function DashboardApp({ onReady }) {
|
|
|
5560
4929
|
} catch {
|
|
5561
4930
|
}
|
|
5562
4931
|
}, []);
|
|
5563
|
-
|
|
4932
|
+
useEffect3(() => {
|
|
5564
4933
|
void loadConfig();
|
|
5565
4934
|
void refreshGoals();
|
|
5566
4935
|
void refreshHypotheses();
|
|
@@ -5579,6 +4948,20 @@ function DashboardApp({ onReady }) {
|
|
|
5579
4948
|
if (nudge.file !== void 0) action.file = nudge.file;
|
|
5580
4949
|
if (nudge.autoHideMs !== void 0) action.autoHideMs = nudge.autoHideMs;
|
|
5581
4950
|
dispatchRef.current(action);
|
|
4951
|
+
if (nudge.severity === "critical" || nudge.severity === "warning") {
|
|
4952
|
+
const insight = {
|
|
4953
|
+
id: `nudge-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
4954
|
+
type: "warning",
|
|
4955
|
+
category: "quality",
|
|
4956
|
+
message: nudge.message,
|
|
4957
|
+
priority: nudge.severity === "critical" ? 9 : 6,
|
|
4958
|
+
timestamp: Date.now(),
|
|
4959
|
+
suggestedAction: nudge.file ? `Review ${nudge.file}` : void 0,
|
|
4960
|
+
relatedIssues: [],
|
|
4961
|
+
dismissed: false
|
|
4962
|
+
};
|
|
4963
|
+
dispatchRef.current({ type: "ADD_INSIGHTS", insights: [insight] });
|
|
4964
|
+
}
|
|
5582
4965
|
}
|
|
5583
4966
|
});
|
|
5584
4967
|
const handleUpdate = (update) => {
|
|
@@ -5601,7 +4984,7 @@ function DashboardApp({ onReady }) {
|
|
|
5601
4984
|
outputManager.setMode("console");
|
|
5602
4985
|
};
|
|
5603
4986
|
}, [loadConfig, onReady, processInsights, refreshGoals, refreshHypotheses]);
|
|
5604
|
-
|
|
4987
|
+
useEffect3(() => {
|
|
5605
4988
|
const interval = setInterval(() => {
|
|
5606
4989
|
dispatchRef.current({ type: "AUTO_DISMISS_NOTIFICATIONS" });
|
|
5607
4990
|
}, 5e3);
|
|
@@ -5711,7 +5094,7 @@ var InteractiveDashboard = class {
|
|
|
5711
5094
|
getConfigFn = null;
|
|
5712
5095
|
async start() {
|
|
5713
5096
|
this.app = render(
|
|
5714
|
-
|
|
5097
|
+
React9.createElement(App, {
|
|
5715
5098
|
onReady: (handler, getConfig) => {
|
|
5716
5099
|
this.updateHandler = handler;
|
|
5717
5100
|
this.getConfigFn = getConfig;
|
|
@@ -5745,7 +5128,6 @@ export {
|
|
|
5745
5128
|
getSystemPrompt,
|
|
5746
5129
|
TrieExplainTool,
|
|
5747
5130
|
StreamingManager,
|
|
5748
|
-
getOutputManager,
|
|
5749
5131
|
ExtractionPipeline,
|
|
5750
5132
|
TrieTellTool,
|
|
5751
5133
|
TrieFeedbackTool,
|
|
@@ -5757,4 +5139,4 @@ export {
|
|
|
5757
5139
|
handleCheckpointTool,
|
|
5758
5140
|
InteractiveDashboard
|
|
5759
5141
|
};
|
|
5760
|
-
//# sourceMappingURL=chunk-
|
|
5142
|
+
//# sourceMappingURL=chunk-ZYKEILVK.js.map
|