detectkit 0.26.0__tar.gz → 0.26.1__tar.gz
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.
- {detectkit-0.26.0/detectkit.egg-info → detectkit-0.26.1}/PKG-INFO +1 -1
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/__init__.py +1 -1
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/html_labeler.py +21 -6
- {detectkit-0.26.0 → detectkit-0.26.1/detectkit.egg-info}/PKG-INFO +1 -1
- {detectkit-0.26.0 → detectkit-0.26.1}/LICENSE +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/MANIFEST.in +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/README.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/base.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/branding.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/email.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/factory.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/mattermost.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/slack.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/telegram.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/channels/webhook.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/_base.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/_cooldown.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/_decision.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/_dispatch.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/_recovery.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/_types.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/alerting/orchestrator/orchestrator.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/_base.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/_types.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/autotuner.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/config_emitter.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/crossval.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/detector_select.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/distribution.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/grid_search.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/label_server.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/labels.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/result.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/scoring.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/seasonality_search.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/settings.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/autotune/window_select.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/_output.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/CLAUDE.section.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/alerting.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/autotune.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/cli.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/detectors.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/metrics.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/overview.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/rules/project.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-autotune/SKILL.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-feedback/SKILL.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-new-metric/SKILL.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-setup-project/SKILL.md +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/autotune.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/clean.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/init.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/init_claude.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/run.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/test_alert.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/commands/unlock.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/main.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/config/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/config/metric_config.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/config/profile.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/config/project_config.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/config/validator.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/core/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/core/interval.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/core/models.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/_sql_manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/clickhouse_manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_alert_states.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_autotune_runs.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_base.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_datapoints.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_detections.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_maintenance.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_metrics.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_schema.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/_tasks.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/internal_tables/manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/mysql_manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/postgres_manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/database/tables.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/base.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/factory.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/seasonality.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/statistical/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/statistical/_windowed.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/statistical/iqr.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/statistical/mad.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/statistical/manual_bounds.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/detectors/statistical/zscore.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/loaders/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/loaders/metric_loader.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/loaders/query_template.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/error_dispatch.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/_alert_step.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/_base.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/_detect_step.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/_load_step.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/_types.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/orchestration/task_manager/manager.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/utils/__init__.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/utils/datetime_utils.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/utils/env_interpolation.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/utils/json_utils.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit/utils/stats.py +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit.egg-info/SOURCES.txt +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit.egg-info/dependency_links.txt +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit.egg-info/entry_points.txt +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit.egg-info/requires.txt +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/detectkit.egg-info/top_level.txt +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/pyproject.toml +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/requirements.txt +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/setup.cfg +0 -0
- {detectkit-0.26.0 → detectkit-0.26.1}/setup.py +0 -0
|
@@ -4,7 +4,7 @@ detectk - Anomaly Detection for Time-Series Metrics
|
|
|
4
4
|
A Python library for data analysts and engineers to monitor metrics with automatic anomaly detection.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
__version__ = "0.26.
|
|
7
|
+
__version__ = "0.26.1"
|
|
8
8
|
|
|
9
9
|
from detectkit.core.interval import Interval
|
|
10
10
|
from detectkit.core.models import ColumnDefinition, TableModel
|
|
@@ -121,6 +121,9 @@ _TEMPLATE = """<!doctype html>
|
|
|
121
121
|
.thbar input.num { width: 84px; font-family: var(--mono); }
|
|
122
122
|
.thbar input:focus, .thbar select:focus { outline: none; border-color: var(--nodata); }
|
|
123
123
|
.thbar button { padding: 7px 13px; }
|
|
124
|
+
.thbar .thscope { color: var(--faint); font-size: 12px; white-space: nowrap; }
|
|
125
|
+
.thbar .thscope.hint { font-style: italic; }
|
|
126
|
+
.thbar .thscope b { color: var(--nodata); font-weight: 600; font-style: normal; }
|
|
124
127
|
canvas#c { width: 100%; height: clamp(300px, 44vh, 500px); display:block; touch-action: none;
|
|
125
128
|
background: var(--term-surface); border: 1px solid var(--term-border); border-radius: 10px; cursor: crosshair; }
|
|
126
129
|
.zoombar { display:flex; align-items:center; gap:8px; margin: 10px 0 6px; }
|
|
@@ -177,6 +180,7 @@ _TEMPLATE = """<!doctype html>
|
|
|
177
180
|
<label>bridge gaps ≤
|
|
178
181
|
<input id="thgap" class="num" type="number" min="0" step="1" value="0" /> intervals
|
|
179
182
|
</label>
|
|
183
|
+
<span id="thscope" class="thscope"></span>
|
|
180
184
|
<button id="thwin" class="ghost" style="display:none" title="capture across the whole current view again">↺ whole view</button>
|
|
181
185
|
<button id="thadd" class="primary" disabled>Add 0 spans</button>
|
|
182
186
|
<button id="thdone" class="ghost">Done</button>
|
|
@@ -330,7 +334,7 @@ function thRuns() { const val=thEff(); if (val===null) return [];
|
|
|
330
334
|
if (s!==null) runs.push([s,e]);
|
|
331
335
|
return runs; }
|
|
332
336
|
function thCount() { const n=thRuns().length;
|
|
333
|
-
thaddEl.textContent = 'Add '+n+' span'+(n===1?'':'s'); thaddEl.disabled = n===0; }
|
|
337
|
+
thaddEl.textContent = 'Add '+n+' span'+(n===1?'':'s'); thaddEl.disabled = n===0; updateThWin(); }
|
|
334
338
|
// Add a captured span, merging it into any overlapping incidents (a single span
|
|
335
339
|
// can bridge several) into one band that keeps the first one's label.
|
|
336
340
|
function addCaptured(a,b) {
|
|
@@ -414,10 +418,13 @@ function draw() {
|
|
|
414
418
|
// Readout while picking a threshold: the line value, side, and how many spans
|
|
415
419
|
// would be captured.
|
|
416
420
|
function drawThLabel() {
|
|
417
|
-
const val=thEff()
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
+
const val=thEff(), win=capRange(), narrow = !!(thDragWin || capWin);
|
|
422
|
+
let text;
|
|
423
|
+
if (val===null) { // no line yet — prompt how to use the mode
|
|
424
|
+
text = 'drag the chart to pick a period · hover or type a value to set the line';
|
|
425
|
+
} else { const n=thRuns().length;
|
|
426
|
+
text='line '+fmtVal(val)+' · '+thdirEl.value+' · '+n+' span'+(n===1?'':'s')
|
|
427
|
+
+ (narrow ? (' · '+fmtDur(win[1]-win[0])+' window') : ''); }
|
|
421
428
|
ctx.font=(11*dpr)+'px ui-monospace, monospace';
|
|
422
429
|
const tw=ctx.measureText(text).width, bw=tw+14*dpr, bh=22*dpr, bx=M.l*dpr+6*dpr, by=M.t*dpr+2;
|
|
423
430
|
ctx.fillStyle='rgba(27,25,22,0.96)'; ctx.strokeStyle='#f0ad4e'; ctx.lineWidth=1*dpr;
|
|
@@ -615,7 +622,15 @@ const thbtnEl=document.getElementById('thbtn'), thbarEl=document.getElementById(
|
|
|
615
622
|
const thvalEl=document.getElementById('thval'), thdirEl=document.getElementById('thdir');
|
|
616
623
|
const thgapEl=document.getElementById('thgap'), thaddEl=document.getElementById('thadd');
|
|
617
624
|
const thdoneEl=document.getElementById('thdone'), thwinEl=document.getElementById('thwin');
|
|
618
|
-
|
|
625
|
+
const thscopeEl=document.getElementById('thscope');
|
|
626
|
+
// Always-visible scope readout so the time-window control is discoverable
|
|
627
|
+
// (the ✕/↺ reset only appears once a window exists).
|
|
628
|
+
function updateThWin() {
|
|
629
|
+
thwinEl.style.display = capWin ? '' : 'none';
|
|
630
|
+
if (!thscopeEl) return;
|
|
631
|
+
const w = thDragWin || capWin;
|
|
632
|
+
if (w) { const r=capRange(); thscopeEl.innerHTML = 'period: <b>'+fmtDur(r[1]-r[0])+'</b>'; thscopeEl.className='thscope'; }
|
|
633
|
+
else { thscopeEl.textContent = 'period: current view — drag the chart to limit it'; thscopeEl.className='thscope hint'; } }
|
|
619
634
|
thwinEl.onclick = () => { capWin=null; updateThWin(); thCount(); draw(); };
|
|
620
635
|
thbtnEl.onclick = () => toggleTh();
|
|
621
636
|
thdoneEl.onclick = () => toggleTh(false);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-autotune/SKILL.md
RENAMED
|
File without changes
|
{detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-feedback/SKILL.md
RENAMED
|
File without changes
|
{detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-new-metric/SKILL.md
RENAMED
|
File without changes
|
{detectkit-0.26.0 → detectkit-0.26.1}/detectkit/cli/assets/claude/skills/dtk-setup-project/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|