selftune 0.2.21 → 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 +15 -8
- 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/cline/hook.ts +167 -0
- package/cli/selftune/adapters/cline/install.ts +197 -0
- package/cli/selftune/adapters/codex/hook.ts +296 -0
- package/cli/selftune/adapters/codex/install.ts +289 -0
- package/cli/selftune/adapters/opencode/hook.ts +222 -0
- package/cli/selftune/adapters/opencode/install.ts +543 -0
- 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/auto-activate.ts +43 -37
- package/cli/selftune/hooks/skill-eval.ts +2 -1
- package/cli/selftune/hooks-shared/git-metadata.ts +149 -0
- package/cli/selftune/hooks-shared/hook-output.ts +105 -0
- package/cli/selftune/hooks-shared/normalize.ts +196 -0
- package/cli/selftune/hooks-shared/session-state.ts +76 -0
- package/cli/selftune/hooks-shared/skill-paths.ts +50 -0
- package/cli/selftune/hooks-shared/stdin-dispatch.ts +59 -0
- package/cli/selftune/hooks-shared/types.ts +91 -0
- package/cli/selftune/index.ts +76 -6
- 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/llm-call.ts +99 -34
- 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 +26 -2
- package/skill/Workflows/Ingest.md +60 -2
- package/skill/Workflows/Initialize.md +54 -9
- package/skill/Workflows/PlatformHooks.md +109 -0
- 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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as React from "react";
|
|
1
2
|
import {
|
|
2
3
|
closestCenter,
|
|
3
4
|
DndContext,
|
|
@@ -33,27 +34,7 @@ import {
|
|
|
33
34
|
type SortingState,
|
|
34
35
|
type VisibilityState,
|
|
35
36
|
} from "@tanstack/react-table";
|
|
36
|
-
import {
|
|
37
|
-
GripVerticalIcon,
|
|
38
|
-
Columns3Icon,
|
|
39
|
-
ChevronDownIcon,
|
|
40
|
-
ChevronsLeftIcon,
|
|
41
|
-
ChevronLeftIcon,
|
|
42
|
-
ChevronRightIcon,
|
|
43
|
-
ChevronsRightIcon,
|
|
44
|
-
ClockIcon,
|
|
45
|
-
LayersIcon,
|
|
46
|
-
FilterIcon,
|
|
47
|
-
CheckCircleIcon,
|
|
48
|
-
AlertTriangleIcon,
|
|
49
|
-
XCircleIcon,
|
|
50
|
-
CircleDotIcon,
|
|
51
|
-
HelpCircleIcon,
|
|
52
|
-
} from "lucide-react";
|
|
53
|
-
import * as React from "react";
|
|
54
37
|
|
|
55
|
-
import { STATUS_CONFIG } from "../lib/constants";
|
|
56
|
-
import { formatRate, timeAgo } from "../lib/format";
|
|
57
38
|
import { Badge } from "../primitives/badge";
|
|
58
39
|
import { Button } from "../primitives/button";
|
|
59
40
|
import { Checkbox } from "../primitives/checkbox";
|
|
@@ -76,7 +57,26 @@ import {
|
|
|
76
57
|
} from "../primitives/select";
|
|
77
58
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../primitives/table";
|
|
78
59
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../primitives/tabs";
|
|
60
|
+
import { STATUS_CONFIG } from "../lib/constants";
|
|
79
61
|
import type { SkillCard, SkillHealthStatus } from "../types";
|
|
62
|
+
import { formatRate, timeAgo } from "../lib/format";
|
|
63
|
+
import {
|
|
64
|
+
GripVerticalIcon,
|
|
65
|
+
Columns3Icon,
|
|
66
|
+
ChevronDownIcon,
|
|
67
|
+
ChevronsLeftIcon,
|
|
68
|
+
ChevronLeftIcon,
|
|
69
|
+
ChevronRightIcon,
|
|
70
|
+
ChevronsRightIcon,
|
|
71
|
+
ClockIcon,
|
|
72
|
+
LayersIcon,
|
|
73
|
+
FilterIcon,
|
|
74
|
+
CheckCircleIcon,
|
|
75
|
+
AlertTriangleIcon,
|
|
76
|
+
XCircleIcon,
|
|
77
|
+
CircleDotIcon,
|
|
78
|
+
HelpCircleIcon,
|
|
79
|
+
} from "lucide-react";
|
|
80
80
|
|
|
81
81
|
// ---------- Drag handle ----------
|
|
82
82
|
|
|
@@ -152,15 +152,27 @@ function createColumns(
|
|
|
152
152
|
enableHiding: false,
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
|
-
accessorKey: "
|
|
156
|
-
header: "
|
|
155
|
+
accessorKey: "platforms",
|
|
156
|
+
header: "Platforms",
|
|
157
157
|
cell: ({ row }) => {
|
|
158
|
-
const
|
|
159
|
-
if (!
|
|
158
|
+
const platforms = row.original.platforms;
|
|
159
|
+
if (!platforms || platforms.length === 0) {
|
|
160
|
+
const scope = row.original.scope;
|
|
161
|
+
if (!scope) return <span className="text-xs text-muted-foreground">--</span>;
|
|
162
|
+
return (
|
|
163
|
+
<Badge variant="secondary" className="text-[10px]">
|
|
164
|
+
{scope}
|
|
165
|
+
</Badge>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
160
168
|
return (
|
|
161
|
-
<
|
|
162
|
-
{
|
|
163
|
-
|
|
169
|
+
<div className="flex flex-wrap gap-1">
|
|
170
|
+
{platforms.map((p) => (
|
|
171
|
+
<Badge key={p} variant="secondary" className="text-[10px]">
|
|
172
|
+
{p}
|
|
173
|
+
</Badge>
|
|
174
|
+
))}
|
|
175
|
+
</div>
|
|
164
176
|
);
|
|
165
177
|
},
|
|
166
178
|
},
|
|
@@ -349,7 +361,7 @@ export function SkillHealthGrid({
|
|
|
349
361
|
} else if (activeView === "recent") {
|
|
350
362
|
filtered = cards
|
|
351
363
|
.filter((c) => c.lastSeen !== null)
|
|
352
|
-
.sort((a
|
|
364
|
+
.sort((a, b) => {
|
|
353
365
|
const aTime = a.lastSeen ? new Date(a.lastSeen).getTime() : 0;
|
|
354
366
|
const bTime = b.lastSeen ? new Date(b.lastSeen).getTime() : 0;
|
|
355
367
|
return bTime - aTime;
|
|
@@ -380,7 +392,7 @@ export function SkillHealthGrid({
|
|
|
380
392
|
columnFilters,
|
|
381
393
|
pagination,
|
|
382
394
|
},
|
|
383
|
-
getRowId: (row) => row.name,
|
|
395
|
+
getRowId: (row) => row.id ?? row.name,
|
|
384
396
|
enableRowSelection: true,
|
|
385
397
|
onRowSelectionChange: setRowSelection,
|
|
386
398
|
onSortingChange: setSorting,
|
|
@@ -395,10 +407,8 @@ export function SkillHealthGrid({
|
|
|
395
407
|
getFacetedUniqueValues: getFacetedUniqueValues(),
|
|
396
408
|
});
|
|
397
409
|
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
[table.getRowModel().rows],
|
|
401
|
-
);
|
|
410
|
+
const rows = table.getRowModel().rows;
|
|
411
|
+
const dataIds = React.useMemo<UniqueIdentifier[]>(() => rows.map((r) => r.id), [rows]);
|
|
402
412
|
|
|
403
413
|
const isSorted = sorting.length > 0;
|
|
404
414
|
|
|
@@ -407,7 +417,7 @@ export function SkillHealthGrid({
|
|
|
407
417
|
const { active, over } = event;
|
|
408
418
|
if (active && over && active.id !== over.id) {
|
|
409
419
|
setData((prev) => {
|
|
410
|
-
const ids = prev.map((d) => d.name);
|
|
420
|
+
const ids = prev.map((d) => d.id ?? d.name);
|
|
411
421
|
const oldIndex = ids.indexOf(active.id as string);
|
|
412
422
|
const newIndex = ids.indexOf(over.id as string);
|
|
413
423
|
if (oldIndex === -1 || newIndex === -1) return prev;
|
|
@@ -537,8 +547,8 @@ export function SkillHealthGrid({
|
|
|
537
547
|
checked={column.getIsVisible()}
|
|
538
548
|
onCheckedChange={(value) => column.toggleVisibility(!!value)}
|
|
539
549
|
>
|
|
540
|
-
{column.id === "
|
|
541
|
-
? "
|
|
550
|
+
{column.id === "platforms"
|
|
551
|
+
? "Platforms"
|
|
542
552
|
: column.id === "passRate"
|
|
543
553
|
? "Pass Rate"
|
|
544
554
|
: column.id === "uniqueSessions"
|
|
@@ -559,7 +569,7 @@ export function SkillHealthGrid({
|
|
|
559
569
|
value={activeView}
|
|
560
570
|
className="relative flex flex-col gap-4 overflow-auto px-4 lg:px-6"
|
|
561
571
|
>
|
|
562
|
-
<div className="overflow-hidden rounded-lg border">
|
|
572
|
+
<div className="overflow-hidden rounded-lg border border-border/15">
|
|
563
573
|
<DndContext
|
|
564
574
|
collisionDetection={closestCenter}
|
|
565
575
|
modifiers={[restrictToVerticalAxis]}
|
|
@@ -12,7 +12,7 @@ function Card({
|
|
|
12
12
|
data-slot="card"
|
|
13
13
|
data-size={size}
|
|
14
14
|
className={cn(
|
|
15
|
-
"group/card flex flex-col gap-4 overflow-hidden rounded-
|
|
15
|
+
"group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-muted py-4 text-sm text-card-foreground border border-border/15 shadow-none has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
|
|
16
16
|
className,
|
|
17
17
|
)}
|
|
18
18
|
{...props}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
|
2
|
-
import { CheckIcon } from "lucide-react";
|
|
3
2
|
|
|
4
3
|
import { cn } from "../lib/utils";
|
|
4
|
+
import { CheckIcon } from "lucide-react";
|
|
5
5
|
|
|
6
6
|
function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
|
|
7
7
|
return (
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
2
|
-
import { ChevronRightIcon, CheckIcon } from "lucide-react";
|
|
3
1
|
import * as React from "react";
|
|
2
|
+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
4
3
|
|
|
5
4
|
import { cn } from "../lib/utils";
|
|
5
|
+
import { ChevronRightIcon, CheckIcon } from "lucide-react";
|
|
6
6
|
|
|
7
7
|
function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
|
|
8
8
|
return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Select as SelectPrimitive } from "@base-ui/react/select";
|
|
2
|
-
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
|
|
3
1
|
import * as React from "react";
|
|
2
|
+
import { Select as SelectPrimitive } from "@base-ui/react/select";
|
|
4
3
|
|
|
5
4
|
import { cn } from "../lib/utils";
|
|
5
|
+
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
|
|
6
6
|
|
|
7
7
|
const Select = SelectPrimitive.Root;
|
|
8
8
|
|
package/packages/ui/src/types.ts
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
export type SkillHealthStatus = "HEALTHY" | "WARNING" | "CRITICAL" | "UNGRADED" | "UNKNOWN";
|
|
4
4
|
|
|
5
5
|
export interface SkillCard {
|
|
6
|
+
id?: string;
|
|
6
7
|
name: string;
|
|
7
8
|
scope: string | null;
|
|
9
|
+
platforms: string[];
|
|
8
10
|
passRate: number | null;
|
|
9
11
|
checks: number;
|
|
10
12
|
status: SkillHealthStatus;
|
|
@@ -13,6 +15,32 @@ export interface SkillCard {
|
|
|
13
15
|
lastSeen: string | null;
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
// -- Job execution types (re-declared for package independence) ---------------
|
|
19
|
+
|
|
20
|
+
export interface JobExecution {
|
|
21
|
+
id: string;
|
|
22
|
+
jobName: string;
|
|
23
|
+
status: "success" | "error";
|
|
24
|
+
startedAt: string;
|
|
25
|
+
durationMs: number;
|
|
26
|
+
metrics: Record<string, unknown>;
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface JobScheduleEntry {
|
|
31
|
+
name: string;
|
|
32
|
+
schedule: string;
|
|
33
|
+
cronExpression: string;
|
|
34
|
+
lastRunAt: string | null;
|
|
35
|
+
lastRunStatus: "success" | "error" | null;
|
|
36
|
+
lastRunDurationMs: number | null;
|
|
37
|
+
nextRunAt: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface JobScheduleState {
|
|
41
|
+
jobs: JobScheduleEntry[];
|
|
42
|
+
}
|
|
43
|
+
|
|
16
44
|
// -- Dashboard contract types (re-declared for package independence) ----------
|
|
17
45
|
|
|
18
46
|
export interface EvalSnapshot {
|
|
@@ -31,10 +59,6 @@ export interface EvolutionEntry {
|
|
|
31
59
|
action: string;
|
|
32
60
|
details: string;
|
|
33
61
|
eval_snapshot?: EvalSnapshot | null;
|
|
34
|
-
validation_mode?: "structural_guard" | "host_replay" | "llm_judge" | null;
|
|
35
|
-
validation_agent?: string | null;
|
|
36
|
-
validation_fixture_id?: string | null;
|
|
37
|
-
validation_evidence_ref?: string | null;
|
|
38
62
|
}
|
|
39
63
|
|
|
40
64
|
export interface UnmatchedQuery {
|
|
@@ -90,3 +114,147 @@ export interface OrchestrateRunReport {
|
|
|
90
114
|
skipped: number;
|
|
91
115
|
skill_actions: OrchestrateRunSkillAction[];
|
|
92
116
|
}
|
|
117
|
+
|
|
118
|
+
// -- Overview panel types (shared between local & cloud dashboards) ----------
|
|
119
|
+
|
|
120
|
+
export type AutonomyStatusLevel = "healthy" | "watching" | "needs_review" | "blocked";
|
|
121
|
+
|
|
122
|
+
export interface AutonomyStatus {
|
|
123
|
+
level: AutonomyStatusLevel;
|
|
124
|
+
summary: string;
|
|
125
|
+
skills_observed: number;
|
|
126
|
+
attention_required: number;
|
|
127
|
+
pending_reviews: number;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type TrustBucket = "at_risk" | "improving" | "uncertain" | "stable";
|
|
131
|
+
|
|
132
|
+
export interface TrustWatchlistEntry {
|
|
133
|
+
skill_name: string;
|
|
134
|
+
bucket: TrustBucket;
|
|
135
|
+
pass_rate: number | null;
|
|
136
|
+
reason: string;
|
|
137
|
+
last_seen: string | null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export type AttentionSeverity = "critical" | "warning" | "info";
|
|
141
|
+
|
|
142
|
+
export interface AttentionItem {
|
|
143
|
+
skill_name: string;
|
|
144
|
+
category: string;
|
|
145
|
+
severity: AttentionSeverity;
|
|
146
|
+
reason: string;
|
|
147
|
+
recommended_action: string;
|
|
148
|
+
timestamp: string | null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type DecisionKind =
|
|
152
|
+
| "proposal_created"
|
|
153
|
+
| "proposal_rejected"
|
|
154
|
+
| "validation_failed"
|
|
155
|
+
| "proposal_deployed"
|
|
156
|
+
| "rollback_triggered"
|
|
157
|
+
| "regression_found";
|
|
158
|
+
|
|
159
|
+
export interface AutonomousDecision {
|
|
160
|
+
skill_name: string;
|
|
161
|
+
kind: DecisionKind;
|
|
162
|
+
summary: string;
|
|
163
|
+
timestamp: string;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// -- Trust / skill report types (shared between local & cloud dashboards) ----
|
|
167
|
+
|
|
168
|
+
export type TrustState =
|
|
169
|
+
| "low_sample"
|
|
170
|
+
| "observed"
|
|
171
|
+
| "watch"
|
|
172
|
+
| "validated"
|
|
173
|
+
| "deployed"
|
|
174
|
+
| "rolled_back";
|
|
175
|
+
|
|
176
|
+
export type ObservationKind =
|
|
177
|
+
| "canonical"
|
|
178
|
+
| "repaired_trigger"
|
|
179
|
+
| "repaired_contextual_miss"
|
|
180
|
+
| "legacy_materialized";
|
|
181
|
+
|
|
182
|
+
export type HistoricalContext = "previously_missed";
|
|
183
|
+
|
|
184
|
+
export interface ExampleRow {
|
|
185
|
+
timestamp: string | null;
|
|
186
|
+
session_id: string;
|
|
187
|
+
query_text: string;
|
|
188
|
+
triggered: boolean;
|
|
189
|
+
confidence: number | null;
|
|
190
|
+
invocation_mode: string | null;
|
|
191
|
+
prompt_kind: string | null;
|
|
192
|
+
source: string | null;
|
|
193
|
+
platform: string | null;
|
|
194
|
+
workspace_path: string | null;
|
|
195
|
+
query_origin: "inline_query" | "matched_prompt" | "missing";
|
|
196
|
+
is_system_like: boolean;
|
|
197
|
+
observation_kind: ObservationKind;
|
|
198
|
+
historical_context?: HistoricalContext | null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface TrustFields {
|
|
202
|
+
trust: {
|
|
203
|
+
state: TrustState;
|
|
204
|
+
summary: string;
|
|
205
|
+
};
|
|
206
|
+
coverage: {
|
|
207
|
+
checks: number;
|
|
208
|
+
sessions: number;
|
|
209
|
+
workspaces: number;
|
|
210
|
+
first_seen: string | null;
|
|
211
|
+
last_seen: string | null;
|
|
212
|
+
};
|
|
213
|
+
evidence_quality: {
|
|
214
|
+
prompt_link_rate: number;
|
|
215
|
+
inline_query_rate: number;
|
|
216
|
+
user_prompt_rate: number;
|
|
217
|
+
meta_prompt_rate: number;
|
|
218
|
+
internal_prompt_rate: number;
|
|
219
|
+
no_prompt_rate: number;
|
|
220
|
+
system_like_rate: number;
|
|
221
|
+
invocation_mode_coverage: number;
|
|
222
|
+
confidence_coverage: number;
|
|
223
|
+
source_coverage: number;
|
|
224
|
+
scope_coverage: number;
|
|
225
|
+
};
|
|
226
|
+
routing_quality: {
|
|
227
|
+
missed_triggers: number;
|
|
228
|
+
miss_rate: number;
|
|
229
|
+
avg_confidence: number | null;
|
|
230
|
+
confidence_coverage: number;
|
|
231
|
+
low_confidence_rate: number | null;
|
|
232
|
+
};
|
|
233
|
+
evolution_state: {
|
|
234
|
+
has_evidence: boolean;
|
|
235
|
+
has_pending_proposals: boolean;
|
|
236
|
+
latest_action: string | null;
|
|
237
|
+
latest_timestamp: string | null;
|
|
238
|
+
evidence_rows: number;
|
|
239
|
+
evolution_rows: number;
|
|
240
|
+
};
|
|
241
|
+
data_hygiene: {
|
|
242
|
+
naming_variants: string[];
|
|
243
|
+
source_breakdown: Array<{ source: string; count: number }>;
|
|
244
|
+
prompt_kind_breakdown: Array<{ kind: string; count: number }>;
|
|
245
|
+
observation_breakdown: Array<{ kind: ObservationKind; count: number }>;
|
|
246
|
+
raw_checks: number;
|
|
247
|
+
operational_checks: number;
|
|
248
|
+
internal_prompt_rows: number;
|
|
249
|
+
internal_prompt_rate: number;
|
|
250
|
+
legacy_rows: number;
|
|
251
|
+
legacy_rate: number;
|
|
252
|
+
repaired_rows: number;
|
|
253
|
+
repaired_rate: number;
|
|
254
|
+
};
|
|
255
|
+
examples: {
|
|
256
|
+
good: ExampleRow[];
|
|
257
|
+
missed: ExampleRow[];
|
|
258
|
+
noisy: ExampleRow[];
|
|
259
|
+
};
|
|
260
|
+
}
|
package/skill/SKILL.md
CHANGED
|
@@ -73,6 +73,7 @@ selftune ingest claude [--since DATE] [--dry-run] [--force] [--verbose]
|
|
|
73
73
|
selftune ingest codex # (experimental)
|
|
74
74
|
selftune ingest opencode # (experimental)
|
|
75
75
|
selftune ingest openclaw [--agents-dir PATH] [--since DATE] [--dry-run] [--force] [--verbose] # (experimental)
|
|
76
|
+
selftune ingest pi [--sessions-dir PATH] [--since DATE] [--dry-run] [--force] [--verbose] # (experimental)
|
|
76
77
|
selftune ingest wrap-codex -- <codex args> # (experimental)
|
|
77
78
|
|
|
78
79
|
# Grade group
|
|
@@ -109,7 +110,7 @@ selftune export [TABLE...] [--output/-o DIR] [--since DATE]
|
|
|
109
110
|
|
|
110
111
|
# Autonomous loop
|
|
111
112
|
selftune orchestrate [--dry-run] [--review-required] [--auto-approve] [--skill NAME] [--max-skills N] [--recent-window HOURS] [--sync-force] [--max-auto-grade N] [--loop] [--loop-interval SECS]
|
|
112
|
-
selftune sync [--since DATE] [--dry-run] [--force] [--no-claude] [--no-codex] [--no-opencode] [--no-openclaw] [--no-repair] [--json]
|
|
113
|
+
selftune sync [--since DATE] [--dry-run] [--force] [--no-claude] [--no-codex] [--no-opencode] [--no-openclaw] [--no-pi] [--no-repair] [--json]
|
|
113
114
|
|
|
114
115
|
# Discovery + badges
|
|
115
116
|
selftune workflows [--skill NAME] [--skill-path PATH] [--min-occurrences N] [--window N] [--json] [save --skill NAME --skill-path PATH]
|
|
@@ -125,6 +126,25 @@ selftune uninstall [--dry-run] [--keep-logs] [--npm-uninstall]
|
|
|
125
126
|
# Hook dispatch (for debugging/manual invocation)
|
|
126
127
|
selftune hook <name> # prompt-log | session-stop | skill-eval | auto-activate | skill-change-guard | evolution-guard
|
|
127
128
|
|
|
129
|
+
# Platform hooks (non-Claude-Code agents)
|
|
130
|
+
selftune codex hook
|
|
131
|
+
selftune codex install [--dry-run] [--uninstall]
|
|
132
|
+
selftune opencode hook
|
|
133
|
+
selftune opencode install [--dry-run] [--uninstall]
|
|
134
|
+
selftune cline hook
|
|
135
|
+
selftune cline install [--dry-run] [--uninstall]
|
|
136
|
+
selftune pi hook
|
|
137
|
+
selftune pi install [--dry-run] [--uninstall]
|
|
138
|
+
|
|
139
|
+
# Registry (team skill distribution)
|
|
140
|
+
selftune registry push [name] [--version=<semver>] [--summary=<text>]
|
|
141
|
+
selftune registry install <name> [--global]
|
|
142
|
+
selftune registry sync
|
|
143
|
+
selftune registry status
|
|
144
|
+
selftune registry rollback <name> [--to=<version>] [--reason=<text>]
|
|
145
|
+
selftune registry history <name>
|
|
146
|
+
selftune registry list
|
|
147
|
+
|
|
128
148
|
# Alpha enrollment (device-code flow — browser opens automatically)
|
|
129
149
|
selftune init --alpha --alpha-email <email>
|
|
130
150
|
selftune alpha upload [--dry-run]
|
|
@@ -143,7 +163,7 @@ selftune status # shows c
|
|
|
143
163
|
| evolve rollback, undo, restore, revert evolution, go back, undo last change | Rollback | Workflows/Rollback.md |
|
|
144
164
|
| watch, monitor, regression, post-deploy, keep an eye on | Watch | Workflows/Watch.md |
|
|
145
165
|
| doctor, health, hooks, broken, diagnose, not working, something wrong | Doctor | Workflows/Doctor.md |
|
|
146
|
-
| ingest, import, codex logs, opencode, openclaw, wrap codex
|
|
166
|
+
| ingest, import, codex logs, opencode, openclaw, pi, wrap codex | Ingest | Workflows/Ingest.md |
|
|
147
167
|
| replay, backfill, claude transcripts, historical sessions | Replay | Workflows/Replay.md |
|
|
148
168
|
| contributions, sharing preferences, opt in creator sharing, opt out creator sharing, approve contributions, revoke contributions, preview contributions, upload contributions, relay queue, contribution upload, contribution preview | Contributions | Workflows/Contributions.md |
|
|
149
169
|
| creator contributions, bundle contribution config, selftune.contribute.json, enable creator contribution, disable creator contribution, bulk enable creator contribution, enable all creator contributions, creator prefix config, --all, --prefix | CreatorContributions | Workflows/CreatorContributions.md |
|
|
@@ -169,6 +189,8 @@ selftune status # shows c
|
|
|
169
189
|
| repair, rebuild usage, fix skill usage, trustworthy usage, repair-skill-usage | RepairSkillUsage | Workflows/RepairSkillUsage.md |
|
|
170
190
|
| export canonical, canonical export, canonical telemetry, push payload | ExportCanonical | Workflows/ExportCanonical.md |
|
|
171
191
|
| hook, run hook, invoke hook, manual hook, debug hook | Hook | Workflows/Hook.md |
|
|
192
|
+
| codex hooks, codex install, codex setup, opencode hooks, opencode install, opencode setup, cline hooks, cline install, cline setup, pi hooks, pi install, pi setup, multi-platform, platform hooks, non-claude hooks, multiple agents, multi-agent | PlatformHooks | Workflows/PlatformHooks.md |
|
|
193
|
+
| registry, distribute, push skill, install skill, sync skills, team skills, version control skills, rollback skill | Registry | Workflows/Registry.md |
|
|
172
194
|
| export, dump, jsonl, export sqlite, debug export | Export | _(direct command — no workflow file)_ |
|
|
173
195
|
| status, health summary, skill health, how are skills, skills doing, run selftune | Status | _(direct command — no workflow file)_ |
|
|
174
196
|
| last, last session, recent session, what happened, what changed | Last | _(direct command — no workflow file)_ |
|
|
@@ -357,10 +379,12 @@ accomplish a task _using_ a skill, route to that skill instead.
|
|
|
357
379
|
| `Workflows/CreatorContributions.md` | Manage bundled `selftune.contribute.json` configs | When preparing a skill package for creator contributions |
|
|
358
380
|
| `Workflows/ExportCanonical.md` | Export canonical telemetry for downstream use | When exporting data for external consumption |
|
|
359
381
|
| `Workflows/Hook.md` | Manual hook invocation for debugging | When debugging or testing hooks manually |
|
|
382
|
+
| `Workflows/PlatformHooks.md` | Non-Claude-Code platform hook install/config | When setting up Codex, OpenCode, Cline, or Pi hooks |
|
|
360
383
|
| `references/logs.md` | Log file formats (telemetry, usage, queries, audit) | When parsing or debugging log files |
|
|
361
384
|
| `references/grading-methodology.md` | 3-tier grading model, evidence standards | When grading sessions or interpreting grades |
|
|
362
385
|
| `references/invocation-taxonomy.md` | 4 invocation types, coverage analysis | When analyzing trigger coverage |
|
|
363
386
|
| `references/interactive-config.md` | Pre-flight config pattern, model tiers | Before running mutating workflows |
|
|
364
387
|
| `references/setup-patterns.md` | Platform-specific setup patterns | During complex setup scenarios |
|
|
388
|
+
| `Workflows/Registry.md` | Registry — team skill distribution commands | When routing to registry workflow |
|
|
365
389
|
| `settings_snippet.json` | Claude Code hook configuration template | During initialization |
|
|
366
390
|
| `assets/*.json` | Config templates (activation rules, settings) | During initialization |
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> **Note:** Claude Code is the fully supported platform. Codex, OpenCode, and OpenClaw adapters are experimental and may have gaps.
|
|
4
4
|
|
|
5
5
|
Import sessions from agent platforms into the shared selftune log format.
|
|
6
|
-
Covers
|
|
7
|
-
`ingest openclaw`, and `ingest wrap-codex`.
|
|
6
|
+
Covers six sub-commands: `ingest claude`, `ingest codex`, `ingest opencode`,
|
|
7
|
+
`ingest openclaw`, `ingest pi`, and `ingest wrap-codex`.
|
|
8
8
|
|
|
9
9
|
## When to Use Each
|
|
10
10
|
|
|
@@ -14,6 +14,7 @@ Covers five sub-commands: `ingest claude`, `ingest codex`, `ingest opencode`,
|
|
|
14
14
|
| `ingest codex` | Codex | Batch | Import existing Codex rollout logs |
|
|
15
15
|
| `ingest opencode` | OpenCode | Batch | Import existing OpenCode sessions |
|
|
16
16
|
| `ingest openclaw` | OpenClaw | Batch | Import existing OpenClaw agent sessions |
|
|
17
|
+
| `ingest pi` | Pi | Batch | Import existing Pi agent sessions |
|
|
17
18
|
| `ingest wrap-codex` | Codex | Real-time | Wrap `codex exec` to capture telemetry live |
|
|
18
19
|
|
|
19
20
|
---
|
|
@@ -200,6 +201,55 @@ Writes to:
|
|
|
200
201
|
|
|
201
202
|
---
|
|
202
203
|
|
|
204
|
+
## ingest pi
|
|
205
|
+
|
|
206
|
+
Batch ingest Pi agent session histories into the shared JSONL schema.
|
|
207
|
+
|
|
208
|
+
### Default Command
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
selftune ingest pi
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Options
|
|
215
|
+
|
|
216
|
+
| Flag | Description |
|
|
217
|
+
| ----------------------- | ------------------------------------------------------------------ |
|
|
218
|
+
| `--sessions-dir <path>` | Override default `~/.pi/agent/sessions/` directory |
|
|
219
|
+
| `--since <date>` | Only ingest sessions modified after this date (e.g., `2026-01-01`) |
|
|
220
|
+
| `--dry-run` | Show what would be ingested without writing to logs |
|
|
221
|
+
| `--force` | Re-ingest all sessions, ignoring the marker file |
|
|
222
|
+
| `--verbose` / `-v` | Show per-session progress during ingestion |
|
|
223
|
+
|
|
224
|
+
### Source
|
|
225
|
+
|
|
226
|
+
Reads from `~/.pi/agent/sessions/`. Each session file contains Pi agent
|
|
227
|
+
conversation history in JSONL format.
|
|
228
|
+
|
|
229
|
+
### Output
|
|
230
|
+
|
|
231
|
+
Writes to:
|
|
232
|
+
|
|
233
|
+
- `~/.claude/all_queries_log.jsonl` -- extracted user queries
|
|
234
|
+
- `~/.claude/session_telemetry_log.jsonl` -- per-session metrics with `source: "pi"`
|
|
235
|
+
- `~/.claude/skill_usage_log.jsonl` -- skill triggers with `source: "pi"`
|
|
236
|
+
|
|
237
|
+
### Steps
|
|
238
|
+
|
|
239
|
+
1. Run `selftune ingest pi --dry-run` to preview what would be ingested
|
|
240
|
+
2. Run `selftune ingest pi` to ingest all sessions
|
|
241
|
+
3. Run `selftune doctor` to confirm logs are healthy
|
|
242
|
+
4. Run `selftune eval generate --list-skills` to see if the ingested sessions appear
|
|
243
|
+
|
|
244
|
+
### Notes
|
|
245
|
+
|
|
246
|
+
- Idempotent: uses a marker file to track which sessions have already been ingested.
|
|
247
|
+
Safe to run repeatedly. Use `--force` to re-ingest everything.
|
|
248
|
+
- Skill detection heuristic: identifies skills by checking for `SKILL.md` file reads in
|
|
249
|
+
tool calls and by matching known skill names in assistant text content.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
203
253
|
## ingest wrap-codex
|
|
204
254
|
|
|
205
255
|
Wrap `codex exec` with real-time telemetry capture. Drop-in replacement
|
|
@@ -269,6 +319,14 @@ through hooks.
|
|
|
269
319
|
|
|
270
320
|
> Run `selftune ingest openclaw --since 2026-02-01` with an appropriate date.
|
|
271
321
|
|
|
322
|
+
**"Ingest Pi sessions"**
|
|
323
|
+
|
|
324
|
+
> Run `selftune ingest pi`. Reads from `~/.pi/agent/sessions/` automatically.
|
|
325
|
+
|
|
326
|
+
**"Import only recent Pi sessions"**
|
|
327
|
+
|
|
328
|
+
> Run `selftune ingest pi --since 2026-02-01` with an appropriate date.
|
|
329
|
+
|
|
272
330
|
**"Run codex through selftune"**
|
|
273
331
|
|
|
274
332
|
> Use `selftune ingest wrap-codex -- <codex args>` instead of `codex exec <args>` directly.
|
|
@@ -6,7 +6,8 @@ Bootstrap selftune for first-time use or after changing environments.
|
|
|
6
6
|
|
|
7
7
|
- The user asks to set up selftune, configure selftune, or initialize selftune
|
|
8
8
|
- The agent detects `~/.selftune/config.json` does not exist
|
|
9
|
-
- The user has switched agent platforms (Claude Code, Codex, OpenCode)
|
|
9
|
+
- The user has switched agent platforms (Claude Code, Codex, OpenCode, Pi)
|
|
10
|
+
- The user wants to add hooks for additional platforms (multi-agent setup)
|
|
10
11
|
|
|
11
12
|
## Default Command
|
|
12
13
|
|
|
@@ -20,7 +21,7 @@ selftune init --no-alpha [--force]
|
|
|
20
21
|
|
|
21
22
|
| Flag | Description | Default |
|
|
22
23
|
| ------------------------- | ------------------------------------------------------------------------- | ------------- |
|
|
23
|
-
| `--agent <type>` | Agent platform: `claude_code`, `codex`, `opencode`, `openclaw`
|
|
24
|
+
| `--agent <type>` | Agent platform: `claude_code`, `codex`, `opencode`, `openclaw`, `pi` | Auto-detected |
|
|
24
25
|
| `--cli-path <path>` | Override auto-detected CLI entry-point path | Auto-detected |
|
|
25
26
|
| `--force` | Reinitialize even if config already exists | Off |
|
|
26
27
|
| `--no-sync` | Skip historical transcript backfill during init | Sync on |
|
|
@@ -136,15 +137,52 @@ Code subagent calls stay up to date.
|
|
|
136
137
|
| `PostToolUse` (Bash) | `hooks/commit-track.ts` | Track git commits for session traceability | Fast-path: skips non-git Bash commands |
|
|
137
138
|
| `Stop` | `hooks/session-stop.ts` | Capture session telemetry | Runs async (non-blocking), 60s timeout |
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
### 4b. Multi-Platform Hooks
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
After Claude Code hooks are installed, check whether the user has **other** agent
|
|
143
|
+
CLIs available. Run these checks:
|
|
143
144
|
|
|
144
|
-
|
|
145
|
+
```bash
|
|
146
|
+
which codex 2>/dev/null && echo "codex available"
|
|
147
|
+
which opencode 2>/dev/null && echo "opencode available"
|
|
148
|
+
ls ~/Documents/Cline/Hooks/ 2>/dev/null && echo "cline available"
|
|
149
|
+
ls ~/.pi/agent/ 2>/dev/null && echo "pi available"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
If **any** additional platforms are detected, use `AskUserQuestion` listing only
|
|
153
|
+
the platforms that were actually found:
|
|
154
|
+
|
|
155
|
+
> I detected these agent platforms in addition to your primary one:
|
|
156
|
+
> - [list only detected platforms, e.g. "Codex", "OpenCode"]
|
|
157
|
+
>
|
|
158
|
+
> Would you like to install selftune hooks for any of them? This enables
|
|
159
|
+
> real-time skill tracking across all your agents.
|
|
160
|
+
|
|
161
|
+
Options:
|
|
162
|
+
- `Yes — install hooks for all detected platforms`
|
|
163
|
+
- `Let me pick — show me the list` (then present only the detected platforms)
|
|
164
|
+
- `No — skip for now` (they can always run `selftune <platform> install` later)
|
|
165
|
+
|
|
166
|
+
For each platform the user selects, run the install command:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
selftune codex install # writes hooks.json entries
|
|
170
|
+
selftune opencode install # writes shell shim + config entries
|
|
171
|
+
selftune cline install # creates hook scripts
|
|
172
|
+
selftune pi install # creates extension hook scripts
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Use `--dry-run` first if the user wants to preview. See `Workflows/PlatformHooks.md`
|
|
176
|
+
for platform-specific details.
|
|
177
|
+
|
|
178
|
+
**Batch ingest** fallback for platforms without real-time hooks or to backfill history:
|
|
145
179
|
|
|
146
|
-
|
|
147
|
-
|
|
180
|
+
```bash
|
|
181
|
+
selftune ingest codex # import Codex rollout sessions
|
|
182
|
+
selftune ingest opencode # import OpenCode sessions from SQLite
|
|
183
|
+
selftune ingest openclaw # import OpenClaw sessions
|
|
184
|
+
selftune ingest pi # import Pi sessions
|
|
185
|
+
```
|
|
148
186
|
|
|
149
187
|
### 5. Initialize Memory Directory
|
|
150
188
|
|
|
@@ -186,7 +224,7 @@ reported issues before proceeding.
|
|
|
186
224
|
|
|
187
225
|
Init automatically runs `selftune sync` to backfill existing session
|
|
188
226
|
transcripts into the SQLite database. This replays Claude Code transcripts,
|
|
189
|
-
Codex rollouts, OpenCode sessions, and
|
|
227
|
+
Codex rollouts, OpenCode sessions, OpenClaw sessions, and Pi sessions so the eval set
|
|
190
228
|
and evolution pipeline have data to work with immediately.
|
|
191
229
|
|
|
192
230
|
The sync step is fail-open — if it encounters errors, init continues.
|
|
@@ -387,6 +425,13 @@ retrying with `selftune init --alpha --alpha-email <email> --force`.
|
|
|
387
425
|
> and optional display name in chat, then run `selftune init --alpha --alpha-email ...`.
|
|
388
426
|
> The browser opens automatically for approval. No manual key management needed.
|
|
389
427
|
|
|
428
|
+
**User uses multiple agents (Claude Code + Codex, etc.)**
|
|
429
|
+
|
|
430
|
+
> Run `selftune init` for the primary agent, then offer to install hooks for
|
|
431
|
+
> additional detected platforms. Run `selftune codex install`, `selftune opencode install`,
|
|
432
|
+
> `selftune cline install`, or `selftune pi install` as needed. All platforms
|
|
433
|
+
> write to the same shared log schema — no extra config required.
|
|
434
|
+
|
|
390
435
|
**Hooks not capturing data**
|
|
391
436
|
|
|
392
437
|
> Run `selftune doctor` to check hook installation. Parse the JSON output
|