selftune 0.2.22 → 0.2.23
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 +4 -2
- package/apps/local-dashboard/dist/assets/index-CwOtTrUS.css +1 -0
- package/apps/local-dashboard/dist/assets/index-f1HQpbeH.js +59 -0
- package/apps/local-dashboard/dist/assets/vendor-ui-jVSaIZey.js +12 -0
- package/apps/local-dashboard/dist/index.html +3 -3
- package/cli/selftune/adapters/pi/hook.ts +273 -0
- package/cli/selftune/adapters/pi/install.ts +207 -0
- package/cli/selftune/constants.ts +10 -1
- package/cli/selftune/dashboard-contract.ts +14 -0
- package/cli/selftune/evolution/engines/judge-engine.ts +96 -0
- package/cli/selftune/evolution/engines/replay-engine.ts +158 -0
- package/cli/selftune/evolution/evidence.ts +2 -6
- package/cli/selftune/evolution/evolve-body.ts +73 -20
- package/cli/selftune/evolution/validate-body.ts +78 -42
- package/cli/selftune/evolution/validate-routing.ts +45 -104
- package/cli/selftune/hooks/skill-eval.ts +2 -1
- package/cli/selftune/hooks-shared/types.ts +1 -0
- package/cli/selftune/index.ts +23 -5
- package/cli/selftune/ingestors/pi-ingest.ts +726 -0
- package/cli/selftune/init.ts +11 -1
- package/cli/selftune/localdb/direct-write.ts +85 -0
- package/cli/selftune/localdb/materialize.ts +6 -7
- package/cli/selftune/localdb/queries.ts +126 -0
- package/cli/selftune/localdb/schema.ts +38 -0
- package/cli/selftune/observability.ts +8 -1
- package/cli/selftune/orchestrate.ts +43 -0
- package/cli/selftune/registry/client.ts +74 -0
- package/cli/selftune/registry/history.ts +54 -0
- package/cli/selftune/registry/index.ts +90 -0
- package/cli/selftune/registry/install.ts +141 -0
- package/cli/selftune/registry/list.ts +44 -0
- package/cli/selftune/registry/push.ts +171 -0
- package/cli/selftune/registry/rollback.ts +49 -0
- package/cli/selftune/registry/status.ts +62 -0
- package/cli/selftune/registry/sync.ts +125 -0
- package/cli/selftune/repair/skill-usage.ts +4 -1
- package/cli/selftune/status.ts +31 -0
- package/cli/selftune/sync.ts +127 -23
- package/cli/selftune/types.ts +2 -1
- package/cli/selftune/utils/jsonl.ts +1 -30
- package/cli/selftune/utils/skill-discovery.ts +22 -0
- package/node_modules/@selftune/telemetry-contract/fixtures/evidence-only-push.ts +1 -1
- package/node_modules/@selftune/telemetry-contract/fixtures/golden.test.ts +0 -1
- package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +1 -1
- package/node_modules/@selftune/telemetry-contract/package.json +1 -1
- package/node_modules/@selftune/telemetry-contract/src/index.ts +1 -0
- package/node_modules/@selftune/telemetry-contract/src/schemas.ts +22 -4
- package/node_modules/@selftune/telemetry-contract/src/types.ts +1 -12
- package/node_modules/@selftune/telemetry-contract/tests/compatibility.test.ts +0 -1
- package/package.json +1 -1
- package/packages/telemetry-contract/fixtures/evidence-only-push.ts +1 -1
- package/packages/telemetry-contract/fixtures/golden.test.ts +0 -1
- package/packages/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +1 -1
- package/packages/telemetry-contract/package.json +1 -1
- package/packages/telemetry-contract/src/index.ts +1 -0
- package/packages/telemetry-contract/src/schemas.ts +22 -4
- package/packages/telemetry-contract/src/types.ts +1 -12
- package/packages/telemetry-contract/tests/compatibility.test.ts +0 -1
- package/packages/ui/AGENTS.md +16 -0
- package/packages/ui/README.md +1 -1
- package/packages/ui/package.json +1 -1
- package/packages/ui/src/components/ActivityTimeline.tsx +152 -168
- package/packages/ui/src/components/AnalyticsCharts.tsx +344 -0
- package/packages/ui/src/components/EvidenceViewer.tsx +153 -443
- package/packages/ui/src/components/EvolutionTimeline.tsx +34 -87
- package/packages/ui/src/components/InfoTip.tsx +1 -2
- package/packages/ui/src/components/InvocationsPanel.tsx +413 -0
- package/packages/ui/src/components/JobHistoryTimeline.tsx +156 -0
- package/packages/ui/src/components/OrchestrateRunsPanel.tsx +18 -36
- package/packages/ui/src/components/OverviewPanels.tsx +652 -0
- package/packages/ui/src/components/PipelineStatusBar.tsx +65 -0
- package/packages/ui/src/components/SkillReportGuide.tsx +215 -0
- package/packages/ui/src/components/SkillReportPanels.tsx +919 -0
- package/packages/ui/src/components/SkillsLibrary.tsx +437 -0
- package/packages/ui/src/components/index.ts +56 -1
- package/packages/ui/src/components/section-cards.tsx +18 -35
- package/packages/ui/src/components/skill-health-grid.tsx +47 -37
- package/packages/ui/src/lib/constants.tsx +0 -1
- package/packages/ui/src/primitives/card.tsx +1 -1
- package/packages/ui/src/primitives/checkbox.tsx +1 -1
- package/packages/ui/src/primitives/dropdown-menu.tsx +2 -2
- package/packages/ui/src/primitives/select.tsx +2 -2
- package/packages/ui/src/types.ts +172 -4
- package/skill/SKILL.md +18 -4
- package/skill/Workflows/Ingest.md +60 -2
- package/skill/Workflows/Initialize.md +8 -5
- package/skill/Workflows/PlatformHooks.md +19 -3
- package/skill/Workflows/Registry.md +99 -0
- package/skill/Workflows/Sync.md +3 -1
- package/apps/local-dashboard/dist/assets/index-D8O-RG1I.js +0 -60
- package/apps/local-dashboard/dist/assets/index-_EcLywDg.css +0 -1
- package/apps/local-dashboard/dist/assets/vendor-ui-CGEmUayx.js +0 -12
- package/cli/selftune/utils/html.ts +0 -27
- package/packages/ui/src/components/RecentActivityFeed.tsx +0 -117
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Card, CardContent, CardHeader, CardTitle } from "../primitives/card";
|
|
3
|
+
import { Badge } from "../primitives/badge";
|
|
4
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../primitives/collapsible";
|
|
5
|
+
import { timeAgo } from "../lib/format";
|
|
6
|
+
import { ActivityIcon, ChevronDownIcon } from "lucide-react";
|
|
7
|
+
import type { JobExecution } from "../types";
|
|
8
|
+
|
|
9
|
+
const JOB_NAMES = [
|
|
10
|
+
"aggregation",
|
|
11
|
+
"alert-checker",
|
|
12
|
+
"badge-cache",
|
|
13
|
+
"retention-cleanup",
|
|
14
|
+
"orchestrate",
|
|
15
|
+
"sync",
|
|
16
|
+
"status",
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export interface JobHistoryFilters {
|
|
20
|
+
job: string;
|
|
21
|
+
status: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function formatDuration(ms: number): string {
|
|
25
|
+
if (ms < 1000) return `${ms}ms`;
|
|
26
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function JobHistoryTimeline({
|
|
30
|
+
executions,
|
|
31
|
+
filters,
|
|
32
|
+
onFilterChange,
|
|
33
|
+
}: {
|
|
34
|
+
executions: JobExecution[];
|
|
35
|
+
filters?: JobHistoryFilters;
|
|
36
|
+
onFilterChange?: (filters: JobHistoryFilters) => void;
|
|
37
|
+
}) {
|
|
38
|
+
const currentJob = filters?.job ?? "";
|
|
39
|
+
const currentStatus = filters?.status ?? "";
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Card>
|
|
43
|
+
<CardHeader>
|
|
44
|
+
<CardTitle className="flex items-center gap-2 text-sm">
|
|
45
|
+
<ActivityIcon className="size-4" />
|
|
46
|
+
Execution History
|
|
47
|
+
</CardTitle>
|
|
48
|
+
</CardHeader>
|
|
49
|
+
<CardContent className="space-y-4">
|
|
50
|
+
{/* Filter bar */}
|
|
51
|
+
{onFilterChange && (
|
|
52
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
53
|
+
<select
|
|
54
|
+
value={currentJob}
|
|
55
|
+
onChange={(e) => onFilterChange({ job: e.target.value, status: currentStatus })}
|
|
56
|
+
className="h-7 rounded-md border border-input bg-transparent px-2 text-xs text-foreground outline-none focus:border-ring"
|
|
57
|
+
>
|
|
58
|
+
<option value="">All jobs</option>
|
|
59
|
+
{JOB_NAMES.map((name) => (
|
|
60
|
+
<option key={name} value={name}>
|
|
61
|
+
{name}
|
|
62
|
+
</option>
|
|
63
|
+
))}
|
|
64
|
+
</select>
|
|
65
|
+
<select
|
|
66
|
+
value={currentStatus}
|
|
67
|
+
onChange={(e) => onFilterChange({ job: currentJob, status: e.target.value })}
|
|
68
|
+
className="h-7 rounded-md border border-input bg-transparent px-2 text-xs text-foreground outline-none focus:border-ring"
|
|
69
|
+
>
|
|
70
|
+
<option value="">All statuses</option>
|
|
71
|
+
<option value="success">Success</option>
|
|
72
|
+
<option value="error">Error</option>
|
|
73
|
+
</select>
|
|
74
|
+
</div>
|
|
75
|
+
)}
|
|
76
|
+
|
|
77
|
+
{/* Timeline */}
|
|
78
|
+
{executions.length === 0 ? (
|
|
79
|
+
<p className="py-8 text-center text-sm text-muted-foreground">No executions yet</p>
|
|
80
|
+
) : (
|
|
81
|
+
<div className="space-y-2">
|
|
82
|
+
{executions.map((exec) => (
|
|
83
|
+
<ExecutionRow key={exec.id} execution={exec} />
|
|
84
|
+
))}
|
|
85
|
+
</div>
|
|
86
|
+
)}
|
|
87
|
+
</CardContent>
|
|
88
|
+
</Card>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function ExecutionRow({ execution }: { execution: JobExecution }) {
|
|
93
|
+
const [open, setOpen] = useState(false);
|
|
94
|
+
const isError = execution.status === "error";
|
|
95
|
+
const hasDetails = execution.error || Object.keys(execution.metrics).length > 0;
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<Collapsible open={open} onOpenChange={setOpen}>
|
|
99
|
+
<div
|
|
100
|
+
className={`rounded-md border p-2 ${
|
|
101
|
+
isError ? "border-red-500/30 bg-red-950/10" : "border-border"
|
|
102
|
+
}`}
|
|
103
|
+
>
|
|
104
|
+
<CollapsibleTrigger
|
|
105
|
+
disabled={!hasDetails}
|
|
106
|
+
className="flex w-full items-center gap-3 text-left disabled:cursor-default"
|
|
107
|
+
>
|
|
108
|
+
<span
|
|
109
|
+
className={`mt-0.5 size-2 shrink-0 rounded-full ${
|
|
110
|
+
isError ? "bg-red-500" : "bg-emerald-500"
|
|
111
|
+
}`}
|
|
112
|
+
/>
|
|
113
|
+
<Badge variant={isError ? "destructive" : "secondary"} className="text-[10px]">
|
|
114
|
+
{execution.jobName}
|
|
115
|
+
</Badge>
|
|
116
|
+
<span className="text-xs text-muted-foreground font-mono">
|
|
117
|
+
{timeAgo(execution.startedAt)}
|
|
118
|
+
</span>
|
|
119
|
+
<span className="text-xs text-muted-foreground/60 font-mono">
|
|
120
|
+
took {formatDuration(execution.durationMs)}
|
|
121
|
+
</span>
|
|
122
|
+
{typeof execution.metrics.total_llm_calls === "number" &&
|
|
123
|
+
execution.metrics.total_llm_calls > 0 && (
|
|
124
|
+
<span className="text-xs text-muted-foreground/60 font-mono">
|
|
125
|
+
{execution.metrics.total_llm_calls} LLM calls
|
|
126
|
+
</span>
|
|
127
|
+
)}
|
|
128
|
+
{hasDetails && (
|
|
129
|
+
<ChevronDownIcon
|
|
130
|
+
className={`ml-auto size-3.5 text-muted-foreground transition-transform ${
|
|
131
|
+
open ? "rotate-180" : ""
|
|
132
|
+
}`}
|
|
133
|
+
/>
|
|
134
|
+
)}
|
|
135
|
+
</CollapsibleTrigger>
|
|
136
|
+
|
|
137
|
+
{hasDetails && (
|
|
138
|
+
<CollapsibleContent className="mt-2 border-t border-border pt-2">
|
|
139
|
+
{execution.error && (
|
|
140
|
+
<p className="text-xs text-red-400 font-mono mb-1">{execution.error}</p>
|
|
141
|
+
)}
|
|
142
|
+
{Object.keys(execution.metrics).length > 0 && (
|
|
143
|
+
<div className="flex flex-wrap gap-x-4 gap-y-1">
|
|
144
|
+
{Object.entries(execution.metrics).map(([key, value]) => (
|
|
145
|
+
<span key={key} className="text-[11px] text-muted-foreground font-mono">
|
|
146
|
+
{key}: {String(value)}
|
|
147
|
+
</span>
|
|
148
|
+
))}
|
|
149
|
+
</div>
|
|
150
|
+
)}
|
|
151
|
+
</CollapsibleContent>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
</Collapsible>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { BotIcon, ChevronRightIcon, EyeIcon, SkipForwardIcon, ZapIcon } from "lucide-react";
|
|
2
1
|
import { useState } from "react";
|
|
3
|
-
|
|
4
|
-
import { timeAgo } from "../lib/format";
|
|
5
2
|
import { Badge } from "../primitives/badge";
|
|
6
3
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../primitives/card";
|
|
7
4
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../primitives/collapsible";
|
|
8
5
|
import type { OrchestrateRunReport, OrchestrateRunSkillAction } from "../types";
|
|
6
|
+
import { timeAgo } from "../lib/format";
|
|
7
|
+
import { BotIcon, ChevronRightIcon, EyeIcon, SkipForwardIcon, ZapIcon } from "lucide-react";
|
|
9
8
|
|
|
10
9
|
const ACTION_ICON: Record<string, React.ReactNode> = {
|
|
11
|
-
evolve: <ZapIcon className="size-3 text-
|
|
10
|
+
evolve: <ZapIcon className="size-3 text-amber-500" />,
|
|
12
11
|
watch: <EyeIcon className="size-3 text-blue-500" />,
|
|
13
12
|
skip: <SkipForwardIcon className="size-3 text-muted-foreground" />,
|
|
14
13
|
};
|
|
@@ -66,15 +65,17 @@ function RunCard({ run }: { run: OrchestrateRunReport }) {
|
|
|
66
65
|
<div
|
|
67
66
|
className={`mt-1.5 size-2 shrink-0 rounded-full ${
|
|
68
67
|
run.deployed > 0
|
|
69
|
-
? "bg-
|
|
68
|
+
? "bg-emerald-500"
|
|
70
69
|
: run.evolved > 0
|
|
71
|
-
? "bg-
|
|
70
|
+
? "bg-amber-400"
|
|
72
71
|
: "bg-muted-foreground/40"
|
|
73
72
|
}`}
|
|
74
73
|
/>
|
|
75
74
|
<div className="flex-1 min-w-0">
|
|
76
75
|
<div className="flex items-center gap-2">
|
|
77
|
-
<span className="text-
|
|
76
|
+
<span className="text-xs font-mono text-muted-foreground">
|
|
77
|
+
{timeAgo(run.timestamp)}
|
|
78
|
+
</span>
|
|
78
79
|
{run.dry_run && (
|
|
79
80
|
<Badge variant="outline" className="text-[10px] h-4 px-1.5">
|
|
80
81
|
dry-run
|
|
@@ -88,7 +89,7 @@ function RunCard({ run }: { run: OrchestrateRunReport }) {
|
|
|
88
89
|
</div>
|
|
89
90
|
<div className="flex items-center gap-3 mt-1 text-xs text-muted-foreground">
|
|
90
91
|
{run.deployed > 0 && (
|
|
91
|
-
<span className="text-
|
|
92
|
+
<span className="text-emerald-600 font-medium">{run.deployed} deployed</span>
|
|
92
93
|
)}
|
|
93
94
|
{run.evolved > 0 && <span>{run.evolved} evolved</span>}
|
|
94
95
|
{run.watched > 0 && <span>{run.watched} watched</span>}
|
|
@@ -102,7 +103,7 @@ function RunCard({ run }: { run: OrchestrateRunReport }) {
|
|
|
102
103
|
</div>
|
|
103
104
|
</CollapsibleTrigger>
|
|
104
105
|
<CollapsibleContent>
|
|
105
|
-
<div className="ml-5 pl-3 border-l border-border
|
|
106
|
+
<div className="ml-5 pl-3 border-l border-border space-y-0.5 pb-2">
|
|
106
107
|
{nonSkipActions.map((action, i) => (
|
|
107
108
|
<SkillActionRow key={`${action.skill}-${i}`} action={action} />
|
|
108
109
|
))}
|
|
@@ -124,32 +125,7 @@ function RunCard({ run }: { run: OrchestrateRunReport }) {
|
|
|
124
125
|
);
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
export function OrchestrateRunsPanel({
|
|
128
|
-
runs,
|
|
129
|
-
embedded = false,
|
|
130
|
-
}: {
|
|
131
|
-
runs: OrchestrateRunReport[];
|
|
132
|
-
embedded?: boolean;
|
|
133
|
-
}) {
|
|
134
|
-
const totalDeployed = runs.reduce((sum, r) => sum + r.deployed, 0);
|
|
135
|
-
const content =
|
|
136
|
-
runs.length === 0 ? (
|
|
137
|
-
<p className="py-4 text-center text-sm text-muted-foreground">
|
|
138
|
-
No orchestrate runs yet. Run{" "}
|
|
139
|
-
<code className="rounded bg-muted px-1 py-0.5 text-xs">selftune orchestrate</code> to start.
|
|
140
|
-
</p>
|
|
141
|
-
) : (
|
|
142
|
-
<div className="space-y-0">
|
|
143
|
-
{runs.slice(0, 10).map((run) => (
|
|
144
|
-
<RunCard key={run.run_id} run={run} />
|
|
145
|
-
))}
|
|
146
|
-
</div>
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
if (embedded) {
|
|
150
|
-
return <div>{content}</div>;
|
|
151
|
-
}
|
|
152
|
-
|
|
128
|
+
export function OrchestrateRunsPanel({ runs }: { runs: OrchestrateRunReport[] }) {
|
|
153
129
|
if (runs.length === 0) {
|
|
154
130
|
return (
|
|
155
131
|
<Card>
|
|
@@ -170,6 +146,8 @@ export function OrchestrateRunsPanel({
|
|
|
170
146
|
);
|
|
171
147
|
}
|
|
172
148
|
|
|
149
|
+
const totalDeployed = runs.reduce((sum, r) => sum + r.deployed, 0);
|
|
150
|
+
|
|
173
151
|
return (
|
|
174
152
|
<Card>
|
|
175
153
|
<CardHeader>
|
|
@@ -182,7 +160,11 @@ export function OrchestrateRunsPanel({
|
|
|
182
160
|
{totalDeployed > 0 && <> · {totalDeployed} total deployments</>}
|
|
183
161
|
</CardDescription>
|
|
184
162
|
</CardHeader>
|
|
185
|
-
<CardContent>
|
|
163
|
+
<CardContent className="space-y-0">
|
|
164
|
+
{runs.slice(0, 10).map((run) => (
|
|
165
|
+
<RunCard key={run.run_id} run={run} />
|
|
166
|
+
))}
|
|
167
|
+
</CardContent>
|
|
186
168
|
</Card>
|
|
187
169
|
);
|
|
188
170
|
}
|