@skyhook-io/radar-app 1.9.5 → 1.9.7

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.
@@ -649,11 +649,17 @@ function ConsentCardShell({
649
649
  settingsLabel,
650
650
  approveLabel = "Approve & investigate",
651
651
  warning = false,
652
+ error,
652
653
  onOpenSettings,
653
654
  onApprove,
654
655
  onCancel,
655
656
  }: DiagnoseConsentCopy & {
656
657
  warning?: boolean;
658
+ // Why the last approval failed, straight from the server. The card stays up on
659
+ // failure so retrying works in place, which means this is the ONLY chance to
660
+ // say why — a host that records consent above the individual refuses the
661
+ // wrong person here, and only its message knows who to ask.
662
+ error?: string | null;
657
663
  onOpenSettings?: () => void;
658
664
  onApprove: () => void;
659
665
  onCancel: () => void;
@@ -698,6 +704,19 @@ function ConsentCardShell({
698
704
  {resolvedSettingsLabel}
699
705
  </button>
700
706
  )}
707
+ {/* Red, not amber: the full-local card is itself amber, so an amber box on
708
+ it reads as another paragraph of body copy. role="alert" because nothing
709
+ else moves on failure — focus stays on Approve, so without it a screen
710
+ reader says nothing and the user re-presses a button that cannot succeed. */}
711
+ {error && (
712
+ <div
713
+ role="alert"
714
+ className="mt-3 flex items-start gap-2 rounded-md border border-red-500/30 bg-red-500/10 p-2 text-xs text-theme-text-primary"
715
+ >
716
+ <AlertTriangle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-red-400" />
717
+ <span>{error}</span>
718
+ </div>
719
+ )}
701
720
  <div className="mt-4 flex gap-2">
702
721
  <button
703
722
  onClick={onCancel}
@@ -731,6 +750,7 @@ export function ConsentCard({
731
750
  agent,
732
751
  profile,
733
752
  copy,
753
+ error,
734
754
  onOpenSettings,
735
755
  onApprove,
736
756
  onCancel,
@@ -739,11 +759,12 @@ export function ConsentCard({
739
759
  agent?: string;
740
760
  profile: ExecutionProfile;
741
761
  copy?: DiagnoseConsentCopy;
762
+ error?: string | null;
742
763
  onOpenSettings?: () => void;
743
764
  onApprove: () => void;
744
765
  onCancel: () => void;
745
766
  }) {
746
- const chrome = { onOpenSettings, onApprove, onCancel };
767
+ const chrome = { onOpenSettings, onApprove, onCancel, error };
747
768
 
748
769
  // Tier 1: a host (e.g. radar-hub-web) supplied its own copy — use it verbatim.
749
770
  if (copy) return <ConsentCardShell {...copy} {...chrome} />;
@@ -390,9 +390,14 @@ function ProblemsPanel({
390
390
  <div className="flex items-center gap-1.5">
391
391
  <span className="text-[10px] text-theme-text-tertiary bg-theme-elevated px-1 py-0.5 rounded">{issue.kind}</span>
392
392
  <span className="text-xs text-theme-text-primary truncate font-medium">{issue.name}</span>
393
- {(age || timing) && (
393
+ {(age || timing || issue.onset_unknown) && (
394
394
  <span className="ml-auto flex shrink-0 items-center gap-1">
395
395
  {age && <span className="text-[10px] text-theme-text-tertiary tabular-nums">{age}</span>}
396
+ {issue.onset_unknown && (
397
+ <Tooltip content="Radar can confirm this issue is active, but current Kubernetes state does not reveal when it began." delay={100}>
398
+ <span className="text-[10px] text-theme-text-tertiary">Onset unknown</span>
399
+ </Tooltip>
400
+ )}
396
401
  {timing && (
397
402
  <Tooltip content={timing.tooltip} delay={100}>
398
403
  <span className="badge-sm text-[10px] text-theme-text-secondary">{timing.chip}</span>
@@ -109,14 +109,16 @@ export const MCP_TOOL_CATALOG: MCPToolInfo[] = [
109
109
  },
110
110
  {
111
111
  name: 'diagnose',
112
- desc: 'One-call root-cause bundle. Workloads get spec + resourceContext + current AND previous logs across pods + warning events + startup blockers; GitOps reconcilers, including Flux HelmRelease, get status summary + parsed related issues.',
112
+ desc: 'One-call root-cause bundle. Workloads get spec + resourceContext + current AND previous logs across pods + warning events + startup blockers; GitOps reconcilers, including Flux HelmRelease, get status summary + parsed related issues; network entry kinds (Service / Ingress / HTTPRoute / GRPCRoute / Gateway) get a path-shaped trace naming the first broken hop, with an optional one-shot reachability test.',
113
113
  params: [
114
- { arg: 'kind', required: true, desc: 'pod, deployment, statefulset, daemonset, application, kustomization, or Flux HelmRelease' },
114
+ { arg: 'kind', required: true, desc: 'pod, deployment, statefulset, daemonset, application, kustomization, Flux HelmRelease, service, ingress, httproute, grpcroute, or gateway' },
115
115
  { arg: 'namespace', required: true, desc: 'resource namespace' },
116
116
  { arg: 'name', required: true, desc: 'resource name' },
117
- { arg: 'container', desc: 'specific container (defaults to all)' },
118
- { arg: 'tail_lines', desc: 'lines per pod/stream (default 100)' },
119
- { arg: 'since', desc: 'only logs newer than this duration' },
117
+ { arg: 'probe', desc: 'network kinds only: add active DNS/TCP/TLS/HTTP probes against the declared path (0-3s wall time)' },
118
+ { arg: 'in_cluster', desc: 'network kinds: run the probe from inside the cluster via short-lived self-destructing pods (real dataplane) - confirms a route the apiserver proxy could only reach indirectly. Creates up to 5 short-lived probe pods (one per dialed target) under your RBAC' },
119
+ { arg: 'container', desc: 'workload kinds: specific container (defaults to all)' },
120
+ { arg: 'tail_lines', desc: 'workload kinds: lines per pod/stream (default 100)' },
121
+ { arg: 'since', desc: 'workload kinds: only logs newer than this duration' },
120
122
  ],
121
123
  },
122
124
  {