@skyhook-io/radar-app 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/package.json +33 -25
- package/src/App.tsx +1449 -382
- package/src/RadarApp.tsx +132 -19
- package/src/api/apiResources.ts +1 -1
- package/src/api/client.argoResourceSync.test.ts +69 -0
- package/src/api/client.delta.test.ts +89 -0
- package/src/api/client.deltaSync.test.ts +216 -0
- package/src/api/client.metrics.test.ts +106 -0
- package/src/api/client.rightsizing.test.ts +32 -0
- package/src/api/client.ts +2730 -271
- package/src/api/client.yaml.test.ts +45 -0
- package/src/api/diagnose.ts +289 -0
- package/src/api/quotas.ts +16 -0
- package/src/api/rbac.ts +57 -0
- package/src/api/timelineSource.test.ts +217 -0
- package/src/api/timelineSource.ts +582 -0
- package/src/components/ConnectionErrorView.tsx +186 -70
- package/src/components/ContextSwitcher.tsx +63 -18
- package/src/components/DebugOverlay.tsx +5 -3
- package/src/components/NamespaceSwitcher.tsx +41 -0
- package/src/components/UserMenu.tsx +69 -21
- package/src/components/applications/ApplicationsView.tsx +936 -0
- package/src/components/audit/AuditSettingsDialog.tsx +79 -17
- package/src/components/audit/AuditView.tsx +65 -62
- package/src/components/compare/CompareViewRoute.tsx +124 -0
- package/src/components/compare/useCompareCandidates.ts +27 -0
- package/src/components/compare/useCompareLauncher.tsx +79 -0
- package/src/components/cost/ApplicationCostTab.test.ts +204 -0
- package/src/components/cost/ApplicationCostTab.tsx +571 -0
- package/src/components/cost/CostTrendChart.tsx +106 -75
- package/src/components/cost/CostView.test.ts +12 -0
- package/src/components/cost/CostView.tsx +507 -223
- package/src/components/cost/CostViewTabs.test.tsx +21 -0
- package/src/components/cost/CostViewTabs.tsx +40 -0
- package/src/components/cost/CurrentAllocationUse.test.ts +21 -0
- package/src/components/cost/CurrentAllocationUse.tsx +126 -0
- package/src/components/cost/WorkloadCostTab.test.ts +153 -0
- package/src/components/cost/WorkloadCostTab.tsx +372 -0
- package/src/components/cost/cloud-console.test.ts +39 -0
- package/src/components/cost/cloud-console.ts +81 -0
- package/src/components/cost/errors.ts +8 -0
- package/src/components/cost/format.test.ts +27 -0
- package/src/components/cost/format.ts +46 -0
- package/src/components/cost/kinds.ts +5 -0
- package/src/components/curl/ServiceCurlButton.tsx +445 -0
- package/src/components/diagnose/AISettings.tsx +147 -0
- package/src/components/diagnose/DiagnoseContext.tsx +495 -0
- package/src/components/diagnose/DiagnoseSurface.tsx +394 -0
- package/src/components/diagnose/Home.tsx +163 -0
- package/src/components/diagnose/InvestigationView.tsx +622 -0
- package/src/components/diagnose/LocalDiagnoseAction.tsx +162 -0
- package/src/components/diagnose/launch.ts +65 -0
- package/src/components/diagnose/parts.tsx +1756 -0
- package/src/components/dock/BottomDock.tsx +2 -3
- package/src/components/dock/DockContext.tsx +1 -0
- package/src/components/dock/TerminalTab.tsx +1 -1
- package/src/components/dock/WorkloadLogsTab.tsx +21 -5
- package/src/components/dock/index.ts +1 -1
- package/src/components/execution/BatchExecutionView.test.ts +170 -0
- package/src/components/execution/BatchExecutionView.tsx +1329 -0
- package/src/components/execution/batch-run-actions.test.ts +48 -0
- package/src/components/execution/batch-run-actions.ts +24 -0
- package/src/components/execution/batch-timeline.test.ts +57 -0
- package/src/components/execution/batch-timeline.ts +46 -0
- package/src/components/execution/execution-definition.test.ts +208 -0
- package/src/components/execution/execution-definition.ts +245 -0
- package/src/components/gitops/ArgoResourceDiffLoader.tsx +23 -0
- package/src/components/gitops/GitOpsView.tsx +1042 -0
- package/src/components/gitops/RevisionMetaChip.tsx +63 -0
- package/src/components/helm/ChartBrowser.tsx +87 -31
- package/src/components/helm/HelmCompareRoute.tsx +1341 -0
- package/src/components/helm/HelmReleaseDrawer.test.ts +17 -0
- package/src/components/helm/HelmReleaseDrawer.tsx +1073 -102
- package/src/components/helm/HelmView.tsx +237 -96
- package/src/components/helm/InstallWizard.tsx +94 -38
- package/src/components/helm/ManifestDiffViewer.tsx +8 -27
- package/src/components/helm/OwnedResources.tsx +34 -59
- package/src/components/helm/RevisionHistory.tsx +52 -3
- package/src/components/helm/RoleGatedPanel.tsx +3 -3
- package/src/components/helm/TrackChartSourceDialog.tsx +185 -0
- package/src/components/helm/ValuesDiffPreview.tsx +17 -7
- package/src/components/helm/ValuesViewer.tsx +49 -53
- package/src/components/helm/helm-utils.ts +4 -0
- package/src/components/home/ActivitySummary.tsx +4 -1
- package/src/components/home/ClusterHealthCard.tsx +56 -42
- package/src/components/home/CostCard.tsx +21 -36
- package/src/components/home/GitOpsControllersCard.tsx +110 -0
- package/src/components/home/HelmSummary.tsx +3 -1
- package/src/components/home/HomeView.tsx +339 -105
- package/src/components/home/MCPSetupDialog.tsx +29 -87
- package/src/components/home/TrafficSummary.tsx +2 -2
- package/src/components/home/mcpToolCatalog.ts +333 -0
- package/src/components/issues/IssuesPane.tsx +151 -0
- package/src/components/logs/LogsViewer.tsx +4 -1
- package/src/components/logs/ScheduledWorkloadLogsViewer.tsx +135 -0
- package/src/components/logs/WorkloadLogsViewer.tsx +4 -1
- package/src/components/nav/PrimaryNavRail.tsx +285 -0
- package/src/components/portforward/PortForwardButton.tsx +118 -47
- package/src/components/portforward/PortForwardManager.tsx +253 -131
- package/src/components/resource/HPACharts.tsx +237 -0
- package/src/components/resource/PVCUsageBar.tsx +59 -0
- package/src/components/resource/PrometheusCharts.tsx +160 -584
- package/src/components/resource/PrometheusChartsGrid.tsx +270 -0
- package/src/components/resource/RestartChart.tsx +133 -0
- package/src/components/resource/RightsizingStrip.test.ts +109 -0
- package/src/components/resource/RightsizingStrip.tsx +363 -0
- package/src/components/resource-drawer/ResourceDrawer.tsx +3 -1
- package/src/components/resources/CompositeRenderer.tsx +101 -0
- package/src/components/resources/ImageFilesystemModal.tsx +19 -12
- package/src/components/resources/PodFilesystemModal.tsx +6 -5
- package/src/components/resources/ResourceDetailDrawer.tsx +13 -3
- package/src/components/resources/ResourcesView.tsx +194 -17
- package/src/components/resources/renderers/CronWorkflowRenderer.tsx +1 -0
- package/src/components/resources/renderers/HPARenderer.tsx +20 -1
- package/src/components/resources/renderers/NamespaceRenderer.tsx +31 -0
- package/src/components/resources/renderers/NodeRenderer.tsx +10 -4
- package/src/components/resources/renderers/PVCRenderer.tsx +19 -1
- package/src/components/resources/renderers/PodRenderer.tsx +30 -6
- package/src/components/resources/renderers/RoleBindingRenderer.tsx +45 -1
- package/src/components/resources/renderers/RoleRenderer.tsx +27 -1
- package/src/components/resources/renderers/ServiceAccountRenderer.tsx +28 -1
- package/src/components/resources/renderers/ServiceRenderer.tsx +81 -8
- package/src/components/resources/renderers/WorkloadRenderer.tsx +51 -4
- package/src/components/resources/renderers/index.ts +2 -0
- package/src/components/resources/resource-utils.ts +2 -1
- package/src/components/rightsizing/RightsizingScanView.tsx +938 -0
- package/src/components/rightsizing/copy.test.ts +56 -0
- package/src/components/rightsizing/model.test.ts +227 -0
- package/src/components/rightsizing/model.ts +158 -0
- package/src/components/rightsizing/presentation.test.ts +104 -0
- package/src/components/rightsizing/presentation.ts +94 -0
- package/src/components/settings/MyPermissionsDialog.tsx +241 -0
- package/src/components/settings/SettingsDialog.tsx +1505 -165
- package/src/components/shared/CreateResourceDialog.tsx +9 -2
- package/src/components/shared/LargeClusterNamespacePicker.tsx +3 -3
- package/src/components/timeline/LocalTimelineScrubber.tsx +212 -0
- package/src/components/timeline/RetainedTimelineScrubber.tsx +311 -0
- package/src/components/timeline/TimelineList.tsx +86 -13
- package/src/components/timeline/TimelineSwimlanes.tsx +9 -1299
- package/src/components/timeline/TimelineView.tsx +873 -24
- package/src/components/timeline/TimelineView.urlparams.test.ts +335 -0
- package/src/components/traffic/TrafficFilterSidebar.tsx +10 -45
- package/src/components/traffic/TrafficFlowList.tsx +29 -15
- package/src/components/traffic/TrafficGraph.tsx +42 -24
- package/src/components/traffic/TrafficView.tsx +32 -19
- package/src/components/ui/CommandPalette.tsx +8 -215
- package/src/components/ui/DiagnosticsOverlay.tsx +219 -9
- package/src/components/ui/Markdown.tsx +3 -3
- package/src/components/ui/Omnibar.tsx +602 -0
- package/src/components/ui/RadarOmnibar.tsx +52 -0
- package/src/components/ui/SearchSyntaxHelp.tsx +89 -0
- package/src/components/ui/ShortcutHelpOverlay.tsx +3 -2
- package/src/components/ui/UpdateNotification.tsx +48 -36
- package/src/components/ui/command-items.ts +178 -0
- package/src/components/workload/WorkloadView.tsx +1342 -158
- package/src/context/ConnectionContext.tsx +146 -21
- package/src/context/DiagnoseCustomization.tsx +93 -0
- package/src/context/NavCustomization.tsx +75 -0
- package/src/context/TimelineSource.tsx +50 -0
- package/src/contexts/CapabilitiesContext.tsx +32 -8
- package/src/filter/FilterLocationBridge.tsx +30 -0
- package/src/hooks/useClusterLoadState.ts +73 -0
- package/src/hooks/useDocumentTitle.ts +25 -0
- package/src/hooks/useEventSource.ts +6 -0
- package/src/hooks/useKeyboardShortcuts.tsx +1 -0
- package/src/hooks/useMediaQuery.ts +21 -0
- package/src/hooks/useNavRailPinned.ts +46 -0
- package/src/hooks/useRecentResources.ts +49 -0
- package/src/index.css +162 -1
- package/src/index.ts +73 -1
- package/src/main.tsx +7 -5
- package/src/types/clusterLoadState.ts +33 -0
- package/src/types.ts +2 -0
- package/src/utils/auditBadges.ts +53 -0
- package/src/utils/navigation.ts +64 -1
- package/src/components/ui/NamespaceSelector.tsx +0 -436
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { Loader2, Sparkles } from "lucide-react";
|
|
2
|
+
import { useDiagnose, useDiagnoseLayout, runTargetKey } from "./DiagnoseContext";
|
|
3
|
+
import { Tooltip } from "../ui/Tooltip";
|
|
4
|
+
import type { RenderDiagnoseAction } from "../../context/DiagnoseCustomization";
|
|
5
|
+
|
|
6
|
+
// The per-resource AI entry point. It no longer owns a panel — it just dispatches
|
|
7
|
+
// to the single app-level AI surface (DiagnoseContext), opening a new investigation
|
|
8
|
+
// for this resource. Self-hides when no agent CLI is present. Hosts can override
|
|
9
|
+
// this slot with their own action.
|
|
10
|
+
//
|
|
11
|
+
// Adaptive by health: on a resource with a live problem it reads as a prominent
|
|
12
|
+
// "Diagnose" (find the root cause); when the resource is fine or health is unknown
|
|
13
|
+
// it shrinks to a quiet colored-icon affordance ("ask my agent about this") — so it
|
|
14
|
+
// never implies "something is wrong here" on a healthy resource. The tooltip leads
|
|
15
|
+
// with the BYO framing (the user's OWN agent, locally) — unless the agent is
|
|
16
|
+
// hosted, where those claims would be false.
|
|
17
|
+
function DiagnoseResourceButton({
|
|
18
|
+
kind,
|
|
19
|
+
namespace,
|
|
20
|
+
name,
|
|
21
|
+
health,
|
|
22
|
+
}: {
|
|
23
|
+
kind: string;
|
|
24
|
+
namespace: string;
|
|
25
|
+
name: string;
|
|
26
|
+
health?: "problem" | "healthy" | "unknown";
|
|
27
|
+
}) {
|
|
28
|
+
const d = useDiagnose();
|
|
29
|
+
const { runningKeys } = useDiagnoseLayout();
|
|
30
|
+
if (!d.available) return null;
|
|
31
|
+
const problem = health === "problem";
|
|
32
|
+
const running = runningKeys.has(runTargetKey(kind, namespace, name));
|
|
33
|
+
const tooltip = running
|
|
34
|
+
? `${d.agentLabel} is investigating this resource — click to watch it live.`
|
|
35
|
+
: d.hosted
|
|
36
|
+
? problem
|
|
37
|
+
? `Diagnose with ${d.agentLabel} — reads this resource's spec, events & logs to find the root cause.`
|
|
38
|
+
: `Ask ${d.agentLabel} about this resource — reads its spec, events & logs.`
|
|
39
|
+
: problem
|
|
40
|
+
? `Diagnose with your own ${d.agentLabel} — runs locally, reads this resource's spec, events & logs to find the root cause.`
|
|
41
|
+
: `Ask your own ${d.agentLabel} about this resource — runs locally, reads its spec, events & logs.`;
|
|
42
|
+
// While an investigation is live, the button advertises it (and clicking focuses
|
|
43
|
+
// the existing run rather than starting a new one — openInvestigation dedups).
|
|
44
|
+
const showLabel = problem || running;
|
|
45
|
+
return (
|
|
46
|
+
<Tooltip content={tooltip} position="bottom">
|
|
47
|
+
<button
|
|
48
|
+
onClick={() => d.openInvestigation({ kind, namespace, name })}
|
|
49
|
+
aria-label={
|
|
50
|
+
running
|
|
51
|
+
? "Investigation running — click to view"
|
|
52
|
+
: problem
|
|
53
|
+
? "Diagnose with AI"
|
|
54
|
+
: "Ask AI about this resource"
|
|
55
|
+
}
|
|
56
|
+
className={
|
|
57
|
+
showLabel
|
|
58
|
+
? "inline-flex items-center gap-1.5 rounded-lg border border-accent/40 bg-accent/5 px-2.5 py-1.5 text-sm font-medium text-accent hover:bg-accent/10"
|
|
59
|
+
: "inline-flex items-center rounded-lg border border-theme-border p-1.5 text-theme-text-secondary hover:bg-theme-hover hover:text-theme-text-primary"
|
|
60
|
+
}
|
|
61
|
+
>
|
|
62
|
+
{running ? (
|
|
63
|
+
<Loader2 className="h-3.5 w-3.5 animate-spin text-accent" />
|
|
64
|
+
) : (
|
|
65
|
+
<Sparkles className="h-3.5 w-3.5 text-accent" />
|
|
66
|
+
)}
|
|
67
|
+
{running ? "Investigating…" : problem && "Diagnose"}
|
|
68
|
+
</button>
|
|
69
|
+
</Tooltip>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const defaultDiagnoseAction: RenderDiagnoseAction = ({
|
|
74
|
+
kind,
|
|
75
|
+
namespace,
|
|
76
|
+
name,
|
|
77
|
+
health,
|
|
78
|
+
}) => (
|
|
79
|
+
<DiagnoseResourceButton
|
|
80
|
+
kind={kind}
|
|
81
|
+
namespace={namespace}
|
|
82
|
+
name={name}
|
|
83
|
+
health={health}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// Compact per-issue "Diagnose" action for the Issues queue — launches an
|
|
88
|
+
// investigation for the issue's subject from where the problem is surfaced.
|
|
89
|
+
// stopPropagation so it doesn't toggle the issue row it lives in.
|
|
90
|
+
export function IssueDiagnoseButton({
|
|
91
|
+
kind,
|
|
92
|
+
namespace,
|
|
93
|
+
name,
|
|
94
|
+
}: {
|
|
95
|
+
kind: string;
|
|
96
|
+
namespace: string;
|
|
97
|
+
name: string;
|
|
98
|
+
}) {
|
|
99
|
+
const d = useDiagnose();
|
|
100
|
+
if (!d.available) return null;
|
|
101
|
+
return (
|
|
102
|
+
<Tooltip
|
|
103
|
+
content={
|
|
104
|
+
d.hosted
|
|
105
|
+
? `Sends this resource's context to ${d.agentLabel} to find the root cause`
|
|
106
|
+
: `Runs ${d.agentLabel} on your machine and sends it this resource's context to find the root cause`
|
|
107
|
+
}
|
|
108
|
+
position="left"
|
|
109
|
+
>
|
|
110
|
+
<button
|
|
111
|
+
onClick={(e) => {
|
|
112
|
+
e.stopPropagation();
|
|
113
|
+
d.openInvestigation({ kind, namespace, name });
|
|
114
|
+
}}
|
|
115
|
+
className="flex shrink-0 items-center gap-1 rounded-md border border-theme-border px-2 py-1 text-xs text-theme-text-secondary hover:bg-theme-hover hover:text-theme-text-primary"
|
|
116
|
+
>
|
|
117
|
+
<Sparkles className="h-3 w-3 text-accent" />
|
|
118
|
+
Diagnose
|
|
119
|
+
</button>
|
|
120
|
+
</Tooltip>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Global top-bar entry into the AI surface (opens its Home / recent
|
|
125
|
+
// investigations). Self-hides when no agent CLI is present.
|
|
126
|
+
export function GlobalDiagnoseButton() {
|
|
127
|
+
const d = useDiagnose();
|
|
128
|
+
const { runningKeys } = useDiagnoseLayout();
|
|
129
|
+
if (!d.available) return null;
|
|
130
|
+
const runningCount = runningKeys.size;
|
|
131
|
+
const agentSuffix = d.hosted
|
|
132
|
+
? `powered by ${d.agentLabel}`
|
|
133
|
+
: `runs your own ${d.agentLabel} locally`;
|
|
134
|
+
return (
|
|
135
|
+
<Tooltip
|
|
136
|
+
content={
|
|
137
|
+
runningCount > 0
|
|
138
|
+
? `${runningCount} investigation${runningCount > 1 ? "s" : ""} running — ${agentSuffix}`
|
|
139
|
+
: `AI investigations — ${agentSuffix}`
|
|
140
|
+
}
|
|
141
|
+
position="bottom"
|
|
142
|
+
>
|
|
143
|
+
<button
|
|
144
|
+
onClick={d.openHome}
|
|
145
|
+
className="relative rounded-md bg-theme-elevated p-1.5 text-theme-text-secondary transition-colors hover:bg-theme-hover hover:text-theme-text-primary"
|
|
146
|
+
aria-label={
|
|
147
|
+
runningCount > 0
|
|
148
|
+
? `AI investigations (${runningCount} running)`
|
|
149
|
+
: "AI investigations"
|
|
150
|
+
}
|
|
151
|
+
>
|
|
152
|
+
<Sparkles className="h-4 w-4 text-accent" />
|
|
153
|
+
{runningCount > 0 && (
|
|
154
|
+
<span className="absolute right-0.5 top-0.5 flex h-2 w-2">
|
|
155
|
+
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-accent opacity-75" />
|
|
156
|
+
<span className="relative inline-flex h-2 w-2 rounded-full bg-accent" />
|
|
157
|
+
</span>
|
|
158
|
+
)}
|
|
159
|
+
</button>
|
|
160
|
+
</Tooltip>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Builds the shell command that hands an investigation off to the user's own
|
|
2
|
+
// interactive agent CLI, pointed at Radar's MCP. This is the "escape hatch" to the
|
|
3
|
+
// full agent (their config, their other MCPs, interactive approvals) — distinct
|
|
4
|
+
// from the contained in-panel engine. The launched agent gets the full /mcp mount
|
|
5
|
+
// (read+write); its own per-tool approval prompts gate any changes.
|
|
6
|
+
import { type RunSummary } from "../../api/diagnose";
|
|
7
|
+
|
|
8
|
+
// sq POSIX-single-quotes a string so it's a safe single shell argument regardless
|
|
9
|
+
// of content. Findings carry backticks, quotes, and newlines — inside single
|
|
10
|
+
// quotes the shell treats everything literally; embedded single quotes become
|
|
11
|
+
// the standard '\'' sequence. Never build the command without this.
|
|
12
|
+
function sq(s: string): string {
|
|
13
|
+
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function launchAgentLabel(run: RunSummary): string {
|
|
17
|
+
if (run.agent === "codex") return "Codex";
|
|
18
|
+
if (run.agent === "cursor-agent") return "Cursor";
|
|
19
|
+
return "Claude Code";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// openInTerminal asks App (which owns the DockProvider) to open Radar's local
|
|
23
|
+
// terminal running `command`. The AI surface is portaled above the DockProvider,
|
|
24
|
+
// so it can't use the dock hook directly — it dispatches this event instead.
|
|
25
|
+
export function openInTerminal(command: string, title: string) {
|
|
26
|
+
window.dispatchEvent(
|
|
27
|
+
new CustomEvent("radar:open-local-terminal", {
|
|
28
|
+
detail: { command, title },
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// buildLaunchCommand resumes the investigation's ACTUAL agent session interactively
|
|
34
|
+
// (not a re-seeded prompt), so the full transcript — every tool call, finding, and
|
|
35
|
+
// the agent's reasoning — carries over. Returns null when there's no resumable
|
|
36
|
+
// session yet (first turn still running) or the run is stale (different cluster).
|
|
37
|
+
// The MCP server is re-attached on resume (it's configured per-launch, not stored
|
|
38
|
+
// in the session).
|
|
39
|
+
export function buildLaunchCommand(
|
|
40
|
+
run: RunSummary,
|
|
41
|
+
mcpUrl: string,
|
|
42
|
+
): string | null {
|
|
43
|
+
if (!run.sessionId || run.status === "stale") return null;
|
|
44
|
+
|
|
45
|
+
if (run.agent === "cursor-agent") {
|
|
46
|
+
// Cursor's --resume is workspace-scoped, and Radar runs each investigation in a
|
|
47
|
+
// throwaway per-run workspace the user doesn't have — no command can reattach
|
|
48
|
+
// both that session and Radar's MCP in the user's own terminal. So there's no
|
|
49
|
+
// hand-off for Cursor; the in-panel investigation is self-contained.
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (run.agent === "codex") {
|
|
53
|
+
// Codex threads are stored globally by id (cwd-independent); -c re-attaches MCP.
|
|
54
|
+
return `codex resume ${sq(run.sessionId)} -c ${sq(`mcp_servers.radar.url="${mcpUrl}"`)}`;
|
|
55
|
+
}
|
|
56
|
+
// Claude Code: --resume is cwd-scoped, and Radar runs its headless sessions from
|
|
57
|
+
// the home dir (see claudeAgent). The Radar terminal starts there too, but a user
|
|
58
|
+
// pasting this into their own terminal is usually in a project dir — so prefix
|
|
59
|
+
// `cd ~` to resolve the session wherever it's run (harmless in the home-dir case).
|
|
60
|
+
// --mcp-config MERGES radar alongside the user's own servers.
|
|
61
|
+
const cfg = JSON.stringify({
|
|
62
|
+
mcpServers: { radar: { type: "http", url: mcpUrl } },
|
|
63
|
+
});
|
|
64
|
+
return `cd ~ && claude --resume ${sq(run.sessionId)} --mcp-config ${sq(cfg)}`;
|
|
65
|
+
}
|