Merge ticket 052: allow clearing all params and re-extracting from ingested logs

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-06 09:44:09 +01:00
co-authored by Claude Sonnet 5
6 changed files with 293 additions and 82 deletions
+45 -2
View File
@@ -1,5 +1,5 @@
import { useMemo, useState } from 'react'
import { ApiError, declareParam, type ParamDeclaration } from '../lib/api'
import { ApiError, clearParams, declareParam, type ParamDeclaration } from '../lib/api'
import {
CollapseToggle,
handleSectionHeaderKeyDown,
@@ -48,6 +48,9 @@ export function Params({ params, onDeclared }: { params: ParamDeclaration[]; onD
// in place by name, so changing it here would silently create a second param and orphan the
// original (and anything referencing it by name) rather than renaming it.
const [editingName, setEditingName] = useState<string | null>(null)
const [clearing, setClearing] = useState(false)
const [clearResult, setClearResult] = useState<string | null>(null)
const [clearError, setClearError] = useState<string | null>(null)
const isBoolean = kind === 'boolean'
const isElapsedSinceLast = source === 'elapsed_since_last'
@@ -117,6 +120,33 @@ export function Params({ params, onDeclared }: { params: ParamDeclaration[]; onD
}
}
// Clears every declared param (manual and auto-derived) in one action, then immediately
// re-derives whatever the engine can still find in retained log text (ticket 052) — a single
// confirmed click rather than removing params one at a time. `logs_considered` in the response
// is surfaced in the status line so it's clear the re-extraction only covers logs the engine
// still holds, not ones already evicted by a max-logs cap.
async function handleClearAll() {
if (params.length === 0) return
if (!window.confirm(`Clear all ${params.length} declared param(s)? Params will immediately be re-derived from log lines still held in memory; lines already evicted by a log cap can't regain their params.`)) {
return
}
setClearing(true)
setClearError(null)
setClearResult(null)
try {
const result = await clearParams()
setClearResult(
`Cleared ${result.removed}, re-derived ${result.reextracted} from ${result.logs_considered} retained log line(s).`,
)
resetForm()
onDeclared()
} catch (err) {
setClearError(err instanceof ApiError ? err.message : 'Failed to clear params')
} finally {
setClearing(false)
}
}
return (
<div className="border-b border-border text-sm">
<div
@@ -262,7 +292,20 @@ export function Params({ params, onDeclared }: { params: ParamDeclaration[]; onD
</form>
<div className="min-w-0 flex-1">
<div className="mb-1 text-xs text-text-subtle">Declared params</div>
<div className="mb-1 flex items-center justify-between gap-2">
<span className="text-xs text-text-subtle">Declared params</span>
<button
type="button"
onClick={handleClearAll}
disabled={clearing || params.length === 0}
className="rounded border border-border-soft px-2 py-0.5 text-xs text-text-secondary hover:bg-surface-2 disabled:opacity-50"
title="Clear every declared param, then re-derive params from log lines still held in memory"
>
{clearing ? 'Clearing…' : 'Clear all'}
</button>
</div>
{clearResult && <div className="mb-1 text-xs text-text-subtle">{clearResult}</div>}
{clearError && <div className="mb-1 text-xs text-danger-text">{clearError}</div>}
<div className="flex flex-wrap gap-1">
{params.length === 0 && <span className="text-xs text-text-faint">No params declared yet.</span>}
{params.map((p) => (
+15
View File
@@ -292,6 +292,21 @@ export function declareParam(request: ParamDeclaration): Promise<ParamDeclaratio
return postJson('/api/params', request)
}
export interface ClearParamsResult {
/** How many param declarations (manual + auto-derived) were removed. */
removed: number
/** How many params were immediately re-derived from log text still retained by the engine. */
reextracted: number
/** How many retained log lines were re-scanned — lines already evicted by `max_logs` before the clear can't regain their params, so this can be smaller than the total lines ever ingested. */
logs_considered: number
}
// Clears every declared param (ticket 052) and re-derives whatever the engine's still-retained log
// text supports — see `ClearParamsResult`'s fields for what came back.
export function clearParams(): Promise<ClearParamsResult> {
return sendJson('/api/params', 'DELETE')
}
export function fetchMetricDeclarations(): Promise<MetricDeclaration[]> {
return getJson('/api/metrics')
}