@skyhook-io/radar-app 1.13.3 → 1.13.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/src/App.tsx +68 -23
- package/src/RadarApp.tsx +17 -1
- package/src/api/client.ts +28 -10
- package/src/api/diagnose.ts +61 -15
- package/src/components/ConnectionErrorView.test.tsx +30 -0
- package/src/components/ConnectionErrorView.tsx +31 -19
- package/src/components/diagnose/AgentCase.tsx +131 -0
- package/src/components/diagnose/DiagnoseContext.test.ts +95 -0
- package/src/components/diagnose/DiagnoseContext.tsx +402 -77
- package/src/components/diagnose/DiagnoseSurface.test.tsx +53 -54
- package/src/components/diagnose/DiagnoseSurface.tsx +198 -286
- package/src/components/diagnose/Home.test.tsx +23 -1
- package/src/components/diagnose/Home.tsx +49 -3
- package/src/components/diagnose/InvestigationEvidencePane.test.tsx +1446 -5
- package/src/components/diagnose/InvestigationEvidencePane.tsx +1373 -126
- package/src/components/diagnose/InvestigationView.tsx +227 -5
- package/src/components/diagnose/LocalDiagnoseAction.tsx +2 -3
- package/src/components/diagnose/diagnoseEvidenceTypes.ts +22 -1
- package/src/components/diagnose/investigationCase.test.tsx +1568 -0
- package/src/components/diagnose/investigationCase.ts +439 -0
- package/src/components/diagnose/investigationEvidence.test.ts +3525 -17
- package/src/components/diagnose/investigationEvidence.ts +2246 -166
- package/src/components/diagnose/investigationEvidenceKinds.ts +218 -0
- package/src/components/diagnose/investigationEvidencePresentation.test.ts +31 -0
- package/src/components/diagnose/investigationEvidencePresentation.ts +1 -0
- package/src/components/diagnose/investigationMetrics.test.ts +712 -0
- package/src/components/diagnose/investigationMetrics.ts +393 -0
- package/src/components/diagnose/investigationSourceFocus.ts +6 -0
- package/src/components/diagnose/investigationState.test.ts +322 -0
- package/src/components/diagnose/investigationState.ts +147 -25
- package/src/components/diagnose/parts.test.tsx +537 -1
- package/src/components/diagnose/parts.tsx +486 -42
- package/src/components/resource/HPACharts.render.test.tsx +77 -0
- package/src/components/resource/HPACharts.tsx +32 -25
- package/src/components/resource/PrometheusChartsGrid.tsx +181 -79
- package/src/components/resources/PodFilePreview.test.tsx +131 -0
- package/src/components/resources/PodFilePreview.tsx +394 -0
- package/src/components/resources/PodFilesystemModal.tsx +157 -67
- package/src/components/resources/ResourcesView.tsx +27 -2
- package/src/context/DiagnoseCustomization.test.tsx +26 -0
- package/src/context/DiagnoseCustomization.tsx +14 -2
- package/src/index.ts +8 -5
- package/src/utils/shell-safe.test.ts +25 -1
- package/src/utils/shell-safe.ts +16 -0
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
DIAGNOSE_SURFACE_FRAME_CLASS,
|
|
4
|
-
MAXIMIZED_COMPACT_HISTORY_VISIBILITY_CLASS,
|
|
5
|
-
MAXIMIZED_HOME_DETAIL_VISIBILITY_CLASS,
|
|
6
|
-
MAXIMIZED_HOME_RUN_HEADER_VISIBILITY_CLASS,
|
|
7
4
|
INVESTIGATION_HISTORY_MIN_WIDTH,
|
|
8
5
|
MAXIMIZED_RUN_META_VISIBILITY_CLASS,
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
canRerunInvestigation,
|
|
7
|
+
investigationHistoryIsPersistent,
|
|
11
8
|
investigationHeaderPresentation,
|
|
12
9
|
openInvestigationEvidenceResource,
|
|
10
|
+
unavailableInvestigationMessage,
|
|
13
11
|
} from "./DiagnoseSurface";
|
|
14
12
|
import {
|
|
15
13
|
canContinueInvestigation,
|
|
@@ -18,7 +16,7 @@ import {
|
|
|
18
16
|
} from "./investigationState";
|
|
19
17
|
import type { RunSummary } from "../../api/diagnose";
|
|
20
18
|
|
|
21
|
-
// The
|
|
19
|
+
// The re-run button dispatches an agent and spends the user's own
|
|
22
20
|
// tokens, so every one of these clauses is load-bearing rather than cosmetic.
|
|
23
21
|
// Each case below is a way it misfired before the gate existed.
|
|
24
22
|
function run(status: RunSummary["status"]): RunSummary {
|
|
@@ -35,41 +33,40 @@ function run(status: RunSummary["status"]): RunSummary {
|
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
describe("
|
|
36
|
+
describe("canRerunInvestigation", () => {
|
|
39
37
|
it("offers a new investigation on a finished run", () => {
|
|
40
|
-
expect(
|
|
38
|
+
expect(canRerunInvestigation("investigation", run("done"), false)).toBe(
|
|
41
39
|
true,
|
|
42
40
|
);
|
|
43
41
|
});
|
|
44
42
|
|
|
45
43
|
it("stays hidden on the investigations list", () => {
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
expect(canStartNewInvestigation("home", run("done"), false)).toBe(false);
|
|
44
|
+
// Home is a fresh-entry surface and must never expose a token-spending
|
|
45
|
+
// re-run action, even if a stale caller hands the header a run.
|
|
46
|
+
expect(canRerunInvestigation("home", run("done"), false)).toBe(false);
|
|
50
47
|
});
|
|
51
48
|
|
|
52
49
|
it("stays hidden while a turn is in flight", () => {
|
|
53
50
|
// A start would be handed back the live run, so the button does nothing.
|
|
54
51
|
expect(
|
|
55
|
-
|
|
52
|
+
canRerunInvestigation("investigation", run("running"), false),
|
|
56
53
|
).toBe(false);
|
|
57
54
|
});
|
|
58
55
|
|
|
59
56
|
it("stays hidden on a stale run", () => {
|
|
60
57
|
// A closed session must not start a new investigation against a resource
|
|
61
58
|
// that may not exist in the active cluster.
|
|
62
|
-
expect(
|
|
59
|
+
expect(canRerunInvestigation("investigation", run("stale"), false)).toBe(
|
|
63
60
|
false,
|
|
64
61
|
);
|
|
65
62
|
});
|
|
66
63
|
|
|
67
64
|
it("blocks fresh starts while a human turn stops, but allows a separate human run from an automatic one", () => {
|
|
68
65
|
expect(
|
|
69
|
-
|
|
66
|
+
canRerunInvestigation("investigation", run("stopping"), false),
|
|
70
67
|
).toBe(false);
|
|
71
68
|
expect(
|
|
72
|
-
|
|
69
|
+
canRerunInvestigation(
|
|
73
70
|
"investigation",
|
|
74
71
|
{ ...run("running"), trigger: "background" },
|
|
75
72
|
false,
|
|
@@ -78,27 +75,39 @@ describe("canStartNewInvestigation", () => {
|
|
|
78
75
|
});
|
|
79
76
|
|
|
80
77
|
it("stays hidden while consent is pending", () => {
|
|
81
|
-
expect(
|
|
78
|
+
expect(canRerunInvestigation("investigation", run("done"), true)).toBe(
|
|
82
79
|
false,
|
|
83
80
|
);
|
|
84
81
|
});
|
|
85
82
|
|
|
86
83
|
it("stays hidden with no focused run", () => {
|
|
87
|
-
expect(
|
|
84
|
+
expect(canRerunInvestigation("investigation", null, false)).toBe(false);
|
|
88
85
|
});
|
|
89
86
|
|
|
90
87
|
it("offers one on an errored or stopped run", () => {
|
|
91
88
|
// Those are the runs a person most wants to start over from.
|
|
92
|
-
expect(
|
|
89
|
+
expect(canRerunInvestigation("investigation", run("error"), false)).toBe(
|
|
93
90
|
true,
|
|
94
91
|
);
|
|
95
92
|
expect(
|
|
96
|
-
|
|
93
|
+
canRerunInvestigation("investigation", run("stopped"), false),
|
|
97
94
|
).toBe(true);
|
|
98
95
|
});
|
|
99
96
|
});
|
|
100
97
|
|
|
101
98
|
describe("investigation history navigation", () => {
|
|
99
|
+
it("keeps hosted recovery language out of standalone Radar", () => {
|
|
100
|
+
expect(unavailableInvestigationMessage(false)).toBe(
|
|
101
|
+
"This investigation is unavailable. It may have been removed, or its saved history may have been cleared.",
|
|
102
|
+
);
|
|
103
|
+
expect(unavailableInvestigationMessage(false)).not.toMatch(
|
|
104
|
+
/account|organization|creator|access/,
|
|
105
|
+
);
|
|
106
|
+
expect(unavailableInvestigationMessage(true)).toMatch(
|
|
107
|
+
/account and organization/,
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
102
111
|
it("restores the docked surface before opening an evidence resource", () => {
|
|
103
112
|
const events: string[] = [];
|
|
104
113
|
const onOpenResource = vi.fn(() => events.push("open"));
|
|
@@ -117,12 +126,13 @@ describe("investigation history navigation", () => {
|
|
|
117
126
|
setMaximized,
|
|
118
127
|
closeDiagnose,
|
|
119
128
|
false,
|
|
129
|
+
"run-1",
|
|
120
130
|
);
|
|
121
131
|
|
|
122
132
|
expect(events).toEqual(["dock", "open"]);
|
|
123
133
|
expect(setMaximized).toHaveBeenCalledWith(false);
|
|
124
134
|
expect(closeDiagnose).not.toHaveBeenCalled();
|
|
125
|
-
expect(onOpenResource).toHaveBeenCalledWith(ref);
|
|
135
|
+
expect(onOpenResource).toHaveBeenCalledWith(ref, "run-1");
|
|
126
136
|
});
|
|
127
137
|
|
|
128
138
|
it("closes an overlay before opening an evidence resource", () => {
|
|
@@ -147,7 +157,7 @@ describe("investigation history navigation", () => {
|
|
|
147
157
|
expect(events).toEqual(["close", "open"]);
|
|
148
158
|
expect(setMaximized).not.toHaveBeenCalled();
|
|
149
159
|
expect(closeDiagnose).toHaveBeenCalledOnce();
|
|
150
|
-
expect(onOpenResource).toHaveBeenCalledWith(ref);
|
|
160
|
+
expect(onOpenResource).toHaveBeenCalledWith(ref, null);
|
|
151
161
|
});
|
|
152
162
|
|
|
153
163
|
it("keeps document overflow out of the bounded Diagnose frame", () => {
|
|
@@ -159,20 +169,28 @@ describe("investigation history navigation", () => {
|
|
|
159
169
|
|
|
160
170
|
it("reserves the history rail for wider investigation surfaces", () => {
|
|
161
171
|
expect(INVESTIGATION_HISTORY_MIN_WIDTH).toBe(1750);
|
|
162
|
-
expect(MAXIMIZED_COMPACT_HISTORY_VISIBILITY_CLASS).toBe(
|
|
163
|
-
"@min-[1750px]/diagnose-surface:hidden",
|
|
164
|
-
);
|
|
165
|
-
expect(MAXIMIZED_HOME_DETAIL_VISIBILITY_CLASS).toBe(
|
|
166
|
-
"hidden @min-[1750px]/diagnose-surface:flex",
|
|
167
|
-
);
|
|
168
|
-
expect(MAXIMIZED_HOME_RUN_HEADER_VISIBILITY_CLASS).toBe(
|
|
169
|
-
"hidden @min-[1750px]/diagnose-surface:block",
|
|
170
|
-
);
|
|
171
172
|
expect(MAXIMIZED_RUN_META_VISIBILITY_CLASS).toBe(
|
|
172
173
|
"hidden @min-[1750px]/diagnose-surface:flex",
|
|
173
174
|
);
|
|
174
175
|
});
|
|
175
176
|
|
|
177
|
+
it("keeps history visible on Home even when the workspace is compact", () => {
|
|
178
|
+
expect(
|
|
179
|
+
investigationHistoryIsPersistent({
|
|
180
|
+
maximized: true,
|
|
181
|
+
view: "home",
|
|
182
|
+
surfaceWidth: 700,
|
|
183
|
+
}),
|
|
184
|
+
).toBe(true);
|
|
185
|
+
expect(
|
|
186
|
+
investigationHistoryIsPersistent({
|
|
187
|
+
maximized: true,
|
|
188
|
+
view: "investigation",
|
|
189
|
+
surfaceWidth: 700,
|
|
190
|
+
}),
|
|
191
|
+
).toBe(false);
|
|
192
|
+
});
|
|
193
|
+
|
|
176
194
|
it("keeps docked Home generic and removes actions for its retained run", () => {
|
|
177
195
|
expect(
|
|
178
196
|
investigationHeaderPresentation({
|
|
@@ -187,7 +205,7 @@ describe("investigation history navigation", () => {
|
|
|
187
205
|
});
|
|
188
206
|
});
|
|
189
207
|
|
|
190
|
-
it("
|
|
208
|
+
it("keeps Home generic even if a stale caller supplies retained detail", () => {
|
|
191
209
|
expect(
|
|
192
210
|
investigationHeaderPresentation({
|
|
193
211
|
view: "home",
|
|
@@ -195,9 +213,9 @@ describe("investigation history navigation", () => {
|
|
|
195
213
|
hasVisibleRunDetail: true,
|
|
196
214
|
}),
|
|
197
215
|
).toEqual({
|
|
198
|
-
genericIdentityClass:
|
|
199
|
-
detailIdentityClass:
|
|
200
|
-
runActionsClass:
|
|
216
|
+
genericIdentityClass: "",
|
|
217
|
+
detailIdentityClass: null,
|
|
218
|
+
runActionsClass: null,
|
|
201
219
|
});
|
|
202
220
|
});
|
|
203
221
|
|
|
@@ -318,25 +336,6 @@ describe("canContinueInvestigation", () => {
|
|
|
318
336
|
});
|
|
319
337
|
});
|
|
320
338
|
|
|
321
|
-
describe("canCopyRunLink", () => {
|
|
322
|
-
it("does not expose collaboration UI for an OSS run", () => {
|
|
323
|
-
expect(canCopyRunLink(run("done"))).toBe(false);
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
it("exposes the copy action only for a canonical hosted URL", () => {
|
|
327
|
-
expect(
|
|
328
|
-
canCopyRunLink({
|
|
329
|
-
...run("done"),
|
|
330
|
-
radarUrl: "/c/cluster-1?org=org-1&ai-run=r1",
|
|
331
|
-
}),
|
|
332
|
-
).toBe(true);
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
it("treats an empty hosted URL as unavailable", () => {
|
|
336
|
-
expect(canCopyRunLink({ ...run("done"), radarUrl: "" })).toBe(false);
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
339
|
describe("canInvestigateFurther", () => {
|
|
341
340
|
it("offers a context-preserving next step on a completed automatic investigation", () => {
|
|
342
341
|
expect(
|