selftune 0.2.22 → 0.2.24

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.
Files changed (270) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +95 -15
  3. package/apps/local-dashboard/dist/assets/index-DgY2KGP-.css +1 -0
  4. package/apps/local-dashboard/dist/assets/index-Dmx7LPVX.js +15 -0
  5. package/apps/local-dashboard/dist/assets/vendor-react-C5oyHiV1.js +11 -0
  6. package/apps/local-dashboard/dist/assets/{vendor-table-BIiI3YhS.js → vendor-table-Bc_bbKd8.js} +1 -1
  7. package/apps/local-dashboard/dist/assets/vendor-ui-B3BPIYy7.js +1 -0
  8. package/apps/local-dashboard/dist/index.html +5 -5
  9. package/cli/selftune/adapters/codex/install.ts +310 -78
  10. package/cli/selftune/adapters/opencode/install.ts +3 -4
  11. package/cli/selftune/adapters/pi/hook.ts +273 -0
  12. package/cli/selftune/adapters/pi/install.ts +207 -0
  13. package/cli/selftune/alpha-upload/build-payloads.ts +3 -3
  14. package/cli/selftune/alpha-upload/stage-canonical.ts +17 -11
  15. package/cli/selftune/auto-update.ts +200 -8
  16. package/cli/selftune/canonical-export.ts +55 -25
  17. package/cli/selftune/command-surface.ts +397 -0
  18. package/cli/selftune/constants.ts +10 -1
  19. package/cli/selftune/contribute/contribute.ts +64 -13
  20. package/cli/selftune/contribution-config.ts +57 -3
  21. package/cli/selftune/contribution-preferences.ts +117 -0
  22. package/cli/selftune/contribution-signals.ts +8 -4
  23. package/cli/selftune/contribution-staging.ts +13 -2
  24. package/cli/selftune/contributions.ts +55 -121
  25. package/cli/selftune/creator-contributions.ts +29 -10
  26. package/cli/selftune/cron/setup.ts +7 -3
  27. package/cli/selftune/dashboard-contract.ts +87 -0
  28. package/cli/selftune/dashboard-server.ts +168 -17
  29. package/cli/selftune/dashboard.ts +350 -17
  30. package/cli/selftune/eval/baseline.ts +21 -5
  31. package/cli/selftune/eval/execution-eval.ts +170 -0
  32. package/cli/selftune/eval/family-overlap.ts +2 -2
  33. package/cli/selftune/eval/hooks-to-evals.ts +228 -82
  34. package/cli/selftune/eval/import-skillsbench.ts +2 -2
  35. package/cli/selftune/eval/invocation-classifier.ts +56 -0
  36. package/cli/selftune/eval/synthetic-evals.ts +5 -3
  37. package/cli/selftune/eval/unit-test-cli.ts +7 -4
  38. package/cli/selftune/evolution/apply-proposal.ts +295 -0
  39. package/cli/selftune/evolution/engines/judge-engine.ts +96 -0
  40. package/cli/selftune/evolution/engines/replay-engine.ts +180 -0
  41. package/cli/selftune/evolution/evidence.ts +2 -6
  42. package/cli/selftune/evolution/evolve-body.ts +152 -38
  43. package/cli/selftune/evolution/evolve.ts +244 -52
  44. package/cli/selftune/evolution/rollback.ts +0 -1
  45. package/cli/selftune/evolution/validate-body.ts +111 -49
  46. package/cli/selftune/evolution/validate-host-replay.ts +510 -60
  47. package/cli/selftune/evolution/validate-proposal.ts +11 -150
  48. package/cli/selftune/evolution/validate-routing.ts +51 -108
  49. package/cli/selftune/evolution/validation-contract.ts +91 -0
  50. package/cli/selftune/grading/auto-grade.ts +11 -7
  51. package/cli/selftune/grading/grade-session.ts +10 -16
  52. package/cli/selftune/hooks/skill-eval.ts +2 -1
  53. package/cli/selftune/hooks-shared/types.ts +1 -0
  54. package/cli/selftune/index.ts +58 -15
  55. package/cli/selftune/ingestors/claude-replay.ts +15 -10
  56. package/cli/selftune/ingestors/codex-wrapper.ts +3 -3
  57. package/cli/selftune/ingestors/opencode-ingest.ts +2 -2
  58. package/cli/selftune/ingestors/pi-ingest.ts +727 -0
  59. package/cli/selftune/init.ts +38 -4
  60. package/cli/selftune/localdb/direct-write.ts +120 -1
  61. package/cli/selftune/localdb/materialize.ts +6 -7
  62. package/cli/selftune/localdb/queries/cron.ts +34 -0
  63. package/cli/selftune/localdb/queries/dashboard.ts +834 -0
  64. package/cli/selftune/localdb/queries/evolution.ts +158 -0
  65. package/cli/selftune/localdb/queries/execution.ts +133 -0
  66. package/cli/selftune/localdb/queries/json.ts +18 -0
  67. package/cli/selftune/localdb/queries/monitoring.ts +263 -0
  68. package/cli/selftune/localdb/queries/raw.ts +95 -0
  69. package/cli/selftune/localdb/queries/staging.ts +270 -0
  70. package/cli/selftune/localdb/queries/trust.ts +392 -0
  71. package/cli/selftune/localdb/queries.ts +60 -2162
  72. package/cli/selftune/localdb/schema.ts +59 -0
  73. package/cli/selftune/monitoring/watch.ts +96 -29
  74. package/cli/selftune/normalization.ts +3 -0
  75. package/cli/selftune/observability.ts +12 -3
  76. package/cli/selftune/orchestrate/cli.ts +161 -0
  77. package/cli/selftune/orchestrate/execute.ts +295 -0
  78. package/cli/selftune/orchestrate/finalize.ts +157 -0
  79. package/cli/selftune/orchestrate/locks.ts +40 -0
  80. package/cli/selftune/orchestrate/plan.ts +131 -0
  81. package/cli/selftune/orchestrate/post-run.ts +59 -0
  82. package/cli/selftune/orchestrate/prepare.ts +334 -0
  83. package/cli/selftune/orchestrate/report.ts +182 -0
  84. package/cli/selftune/orchestrate/runtime.ts +120 -0
  85. package/cli/selftune/orchestrate/signals.ts +48 -0
  86. package/cli/selftune/orchestrate.ts +162 -1142
  87. package/cli/selftune/registry/client.ts +74 -0
  88. package/cli/selftune/registry/history.ts +54 -0
  89. package/cli/selftune/registry/index.ts +90 -0
  90. package/cli/selftune/registry/install.ts +141 -0
  91. package/cli/selftune/registry/list.ts +44 -0
  92. package/cli/selftune/registry/push.ts +171 -0
  93. package/cli/selftune/registry/rollback.ts +49 -0
  94. package/cli/selftune/registry/status.ts +62 -0
  95. package/cli/selftune/registry/sync.ts +125 -0
  96. package/cli/selftune/repair/skill-usage.ts +9 -3
  97. package/cli/selftune/routes/overview.ts +5 -2
  98. package/cli/selftune/routes/skill-report.ts +15 -2
  99. package/cli/selftune/schedule.ts +5 -5
  100. package/cli/selftune/status.ts +70 -2
  101. package/cli/selftune/sync.ts +127 -23
  102. package/cli/selftune/testing-readiness.ts +597 -0
  103. package/cli/selftune/types.ts +46 -5
  104. package/cli/selftune/uninstall.ts +2 -1
  105. package/cli/selftune/utils/canonical-log.ts +1 -9
  106. package/cli/selftune/utils/cli-error.ts +9 -0
  107. package/cli/selftune/utils/jsonl.ts +1 -30
  108. package/cli/selftune/utils/llm-call.ts +126 -6
  109. package/cli/selftune/utils/skill-discovery.ts +24 -0
  110. package/cli/selftune/workflows/proposals.ts +184 -0
  111. package/cli/selftune/workflows/skill-scaffold.ts +241 -0
  112. package/cli/selftune/workflows/workflows.ts +100 -26
  113. package/node_modules/@selftune/telemetry-contract/fixtures/complete-push.ts +1 -1
  114. package/node_modules/@selftune/telemetry-contract/fixtures/evidence-only-push.ts +2 -2
  115. package/node_modules/@selftune/telemetry-contract/fixtures/golden.test.ts +0 -1
  116. package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
  117. package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +2 -2
  118. package/node_modules/@selftune/telemetry-contract/package.json +1 -1
  119. package/node_modules/@selftune/telemetry-contract/src/index.ts +1 -0
  120. package/node_modules/@selftune/telemetry-contract/src/schemas.ts +63 -5
  121. package/node_modules/@selftune/telemetry-contract/src/types.ts +97 -7
  122. package/node_modules/@selftune/telemetry-contract/tests/compatibility.test.ts +0 -1
  123. package/package.json +25 -9
  124. package/packages/dashboard-core/AGENTS.md +18 -0
  125. package/packages/dashboard-core/README.md +30 -0
  126. package/packages/dashboard-core/index.ts +3 -0
  127. package/packages/dashboard-core/package.json +39 -0
  128. package/packages/dashboard-core/src/chrome/DashboardChrome.tsx +74 -0
  129. package/packages/dashboard-core/src/chrome/DashboardHeader.tsx +200 -0
  130. package/packages/dashboard-core/src/chrome/DashboardSidebar.tsx +219 -0
  131. package/packages/dashboard-core/src/chrome/RuntimeBadge.tsx +46 -0
  132. package/packages/dashboard-core/src/chrome/index.ts +14 -0
  133. package/packages/dashboard-core/src/chrome/types.ts +81 -0
  134. package/packages/dashboard-core/src/chrome/utils.ts +23 -0
  135. package/packages/dashboard-core/src/gates/FeatureGate.tsx +11 -0
  136. package/packages/dashboard-core/src/gates/LockedRoute.tsx +29 -0
  137. package/packages/dashboard-core/src/gates/UpgradeCard.tsx +89 -0
  138. package/packages/dashboard-core/src/gates/index.ts +3 -0
  139. package/packages/dashboard-core/src/host/DashboardHostProvider.tsx +62 -0
  140. package/packages/dashboard-core/src/host/adapter.ts +47 -0
  141. package/packages/dashboard-core/src/host/capabilities.ts +55 -0
  142. package/packages/dashboard-core/src/host/index.ts +3 -0
  143. package/packages/dashboard-core/src/models/analytics.ts +39 -0
  144. package/packages/dashboard-core/src/models/index.ts +4 -0
  145. package/packages/dashboard-core/src/models/overview.ts +98 -0
  146. package/packages/dashboard-core/src/models/runtime.ts +7 -0
  147. package/packages/dashboard-core/src/models/skills.ts +34 -0
  148. package/packages/dashboard-core/src/routes/index.ts +2 -0
  149. package/packages/dashboard-core/src/routes/manifest.test.ts +70 -0
  150. package/packages/dashboard-core/src/routes/manifest.ts +451 -0
  151. package/packages/dashboard-core/src/routes/types.ts +39 -0
  152. package/packages/dashboard-core/src/screens/analytics/AnalyticsScreen.tsx +278 -0
  153. package/packages/dashboard-core/src/screens/analytics/index.ts +1 -0
  154. package/packages/dashboard-core/src/screens/index.ts +37 -0
  155. package/packages/dashboard-core/src/screens/overview/OverviewComparisonSurface.test.ts +101 -0
  156. package/packages/dashboard-core/src/screens/overview/OverviewComparisonSurface.tsx +393 -0
  157. package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.test.tsx +113 -0
  158. package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.tsx +72 -0
  159. package/packages/dashboard-core/src/screens/overview/OverviewCoreSurface.tsx +71 -0
  160. package/packages/dashboard-core/src/screens/overview/OverviewOnboardingBanner.tsx +90 -0
  161. package/packages/dashboard-core/src/screens/overview/OverviewRunSummary.tsx +40 -0
  162. package/packages/dashboard-core/src/screens/overview/index.ts +16 -0
  163. package/packages/dashboard-core/src/screens/overview/types.ts +13 -0
  164. package/packages/dashboard-core/src/screens/skill-report/SkillReportDailyBreakdownSection.tsx +99 -0
  165. package/packages/dashboard-core/src/screens/skill-report/SkillReportDataQualityTabContent.tsx +35 -0
  166. package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceRail.tsx +71 -0
  167. package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceSection.tsx +63 -0
  168. package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceTabContent.tsx +25 -0
  169. package/packages/dashboard-core/src/screens/skill-report/SkillReportInvocationsSection.tsx +24 -0
  170. package/packages/dashboard-core/src/screens/skill-report/SkillReportMissedQueriesSection.tsx +79 -0
  171. package/packages/dashboard-core/src/screens/skill-report/SkillReportScaffold.tsx +150 -0
  172. package/packages/dashboard-core/src/screens/skill-report/SkillReportSections.test.tsx +224 -0
  173. package/packages/dashboard-core/src/screens/skill-report/SkillReportTabs.test.tsx +76 -0
  174. package/packages/dashboard-core/src/screens/skill-report/SkillReportTabs.tsx +88 -0
  175. package/packages/dashboard-core/src/screens/skill-report/SkillReportTrendSection.tsx +33 -0
  176. package/packages/dashboard-core/src/screens/skill-report/SkillReportTrustBadge.tsx +67 -0
  177. package/packages/dashboard-core/src/screens/skill-report/index.ts +45 -0
  178. package/packages/dashboard-core/src/screens/skills/SkillsLibraryScreen.tsx +162 -0
  179. package/packages/dashboard-core/src/screens/skills/index.ts +6 -0
  180. package/packages/telemetry-contract/fixtures/complete-push.ts +1 -1
  181. package/packages/telemetry-contract/fixtures/evidence-only-push.ts +2 -2
  182. package/packages/telemetry-contract/fixtures/golden.test.ts +0 -1
  183. package/packages/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
  184. package/packages/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +2 -2
  185. package/packages/telemetry-contract/package.json +1 -1
  186. package/packages/telemetry-contract/src/index.ts +1 -0
  187. package/packages/telemetry-contract/src/schemas.ts +63 -5
  188. package/packages/telemetry-contract/src/types.ts +97 -7
  189. package/packages/telemetry-contract/tests/compatibility.test.ts +0 -1
  190. package/packages/ui/AGENTS.md +16 -0
  191. package/packages/ui/README.md +1 -1
  192. package/packages/ui/package.json +1 -1
  193. package/packages/ui/src/components/ActivityTimeline.tsx +152 -168
  194. package/packages/ui/src/components/AnalyticsCharts.tsx +344 -0
  195. package/packages/ui/src/components/EvidenceViewer.tsx +229 -464
  196. package/packages/ui/src/components/EvolutionTimeline.tsx +34 -87
  197. package/packages/ui/src/components/InfoTip.tsx +1 -2
  198. package/packages/ui/src/components/InvocationsPanel.tsx +413 -0
  199. package/packages/ui/src/components/JobHistoryTimeline.tsx +156 -0
  200. package/packages/ui/src/components/OrchestrateRunsPanel.tsx +18 -36
  201. package/packages/ui/src/components/OverviewPanels.tsx +693 -0
  202. package/packages/ui/src/components/PipelineStatusBar.tsx +65 -0
  203. package/packages/ui/src/components/SkillReportGuide.tsx +215 -0
  204. package/packages/ui/src/components/SkillReportPanels.tsx +919 -0
  205. package/packages/ui/src/components/SkillsLibrary.tsx +437 -0
  206. package/packages/ui/src/components/index.ts +56 -1
  207. package/packages/ui/src/components/section-cards.tsx +18 -35
  208. package/packages/ui/src/components/skill-health-grid.tsx +47 -37
  209. package/packages/ui/src/lib/constants.tsx +0 -1
  210. package/packages/ui/src/primitives/card.tsx +1 -1
  211. package/packages/ui/src/primitives/checkbox.tsx +1 -1
  212. package/packages/ui/src/primitives/dropdown-menu.tsx +2 -2
  213. package/packages/ui/src/primitives/select.tsx +2 -2
  214. package/packages/ui/src/primitives/tabs.tsx +7 -6
  215. package/packages/ui/src/types.ts +182 -4
  216. package/skill/SKILL.md +130 -318
  217. package/skill/agents/diagnosis-analyst.md +3 -3
  218. package/skill/agents/evolution-reviewer.md +3 -3
  219. package/skill/agents/integration-guide.md +3 -3
  220. package/skill/agents/pattern-analyst.md +2 -2
  221. package/skill/references/cli-quick-reference.md +89 -0
  222. package/skill/references/creator-playbook.md +131 -0
  223. package/skill/references/examples.md +48 -0
  224. package/skill/references/troubleshooting.md +47 -0
  225. package/skill/references/version-history.md +1 -1
  226. package/skill/selftune.contribute.json +11 -0
  227. package/skill/{Workflows → workflows}/Baseline.md +20 -1
  228. package/skill/{Workflows → workflows}/Contribute.md +23 -10
  229. package/skill/{Workflows → workflows}/Contributions.md +13 -5
  230. package/skill/workflows/CreateTestDeploy.md +170 -0
  231. package/skill/{Workflows → workflows}/CreatorContributions.md +18 -6
  232. package/skill/{Workflows → workflows}/Cron.md +1 -1
  233. package/skill/{Workflows → workflows}/Dashboard.md +20 -0
  234. package/skill/{Workflows → workflows}/Doctor.md +1 -1
  235. package/skill/{Workflows → workflows}/Evals.md +67 -2
  236. package/skill/{Workflows → workflows}/Evolve.md +119 -30
  237. package/skill/{Workflows → workflows}/EvolveBody.md +41 -1
  238. package/skill/{Workflows → workflows}/Grade.md +1 -1
  239. package/skill/{Workflows → workflows}/Ingest.md +60 -2
  240. package/skill/{Workflows → workflows}/Initialize.md +16 -9
  241. package/skill/{Workflows → workflows}/Orchestrate.md +13 -3
  242. package/skill/{Workflows → workflows}/PlatformHooks.md +19 -3
  243. package/skill/workflows/Registry.md +99 -0
  244. package/skill/{Workflows → workflows}/Schedule.md +3 -3
  245. package/skill/workflows/SignalsDashboard.md +87 -0
  246. package/skill/{Workflows → workflows}/Sync.md +3 -1
  247. package/skill/{Workflows → workflows}/UnitTest.md +19 -0
  248. package/skill/{Workflows → workflows}/Watch.md +42 -2
  249. package/skill/{Workflows → workflows}/Workflows.md +39 -2
  250. package/apps/local-dashboard/dist/assets/index-D8O-RG1I.js +0 -60
  251. package/apps/local-dashboard/dist/assets/index-_EcLywDg.css +0 -1
  252. package/apps/local-dashboard/dist/assets/vendor-react-CKkiCskZ.js +0 -11
  253. package/apps/local-dashboard/dist/assets/vendor-ui-CGEmUayx.js +0 -12
  254. package/cli/selftune/utils/html.ts +0 -27
  255. package/packages/ui/src/components/RecentActivityFeed.tsx +0 -117
  256. /package/skill/{Workflows → workflows}/AlphaUpload.md +0 -0
  257. /package/skill/{Workflows → workflows}/AutoActivation.md +0 -0
  258. /package/skill/{Workflows → workflows}/Badge.md +0 -0
  259. /package/skill/{Workflows → workflows}/Composability.md +0 -0
  260. /package/skill/{Workflows → workflows}/EvolutionMemory.md +0 -0
  261. /package/skill/{Workflows → workflows}/ExportCanonical.md +0 -0
  262. /package/skill/{Workflows → workflows}/Hook.md +0 -0
  263. /package/skill/{Workflows → workflows}/ImportSkillsBench.md +0 -0
  264. /package/skill/{Workflows → workflows}/Quickstart.md +0 -0
  265. /package/skill/{Workflows → workflows}/Recover.md +0 -0
  266. /package/skill/{Workflows → workflows}/RepairSkillUsage.md +0 -0
  267. /package/skill/{Workflows → workflows}/Replay.md +0 -0
  268. /package/skill/{Workflows → workflows}/Rollback.md +0 -0
  269. /package/skill/{Workflows → workflows}/Telemetry.md +0 -0
  270. /package/skill/{Workflows → workflows}/Uninstall.md +0 -0
@@ -0,0 +1,162 @@
1
+ "use client";
2
+
3
+ import type { ReactNode } from "react";
4
+ import { useMemo, useState } from "react";
5
+
6
+ import type { DerivedSkill, FilterTab } from "@selftune/ui/components";
7
+ import {
8
+ LibraryHealthCard,
9
+ PendingProposalsCard,
10
+ SkillCardItem,
11
+ SkillFilterTabs,
12
+ SkillGridEmpty,
13
+ SkillHeroCard,
14
+ SkillHeroEmpty,
15
+ SkillsLibraryError,
16
+ SkillsLibrarySkeleton,
17
+ } from "@selftune/ui/components";
18
+
19
+ export interface SkillsLibraryHero {
20
+ skillName: string;
21
+ skillScope?: string | null;
22
+ platforms?: string[];
23
+ passRate: number | null;
24
+ totalChecks: number;
25
+ uniqueSessions: number;
26
+ status: DerivedSkill["status"];
27
+ latestEvolutionTimestamp?: string | null;
28
+ }
29
+
30
+ export interface SkillsLibraryPendingProposal {
31
+ id: string;
32
+ skillName: string | null;
33
+ action: string;
34
+ }
35
+
36
+ export interface SkillsLibraryScreenProps {
37
+ skills: DerivedSkill[];
38
+ heroSkill?: SkillsLibraryHero | null;
39
+ aggregatePassRate: number | null;
40
+ gradedCount: number;
41
+ pendingProposals: SkillsLibraryPendingProposal[];
42
+ isLoading: boolean;
43
+ error?: string | null;
44
+ onRetry(): void;
45
+ renderHeroActions(skillName: string): ReactNode;
46
+ renderCardActions(skillName: string): ReactNode;
47
+ }
48
+
49
+ export function SkillsLibraryScreen({
50
+ skills,
51
+ heroSkill,
52
+ aggregatePassRate,
53
+ gradedCount,
54
+ pendingProposals,
55
+ isLoading,
56
+ error,
57
+ onRetry,
58
+ renderHeroActions,
59
+ renderCardActions,
60
+ }: SkillsLibraryScreenProps) {
61
+ const [filter, setFilter] = useState<FilterTab>("ALL");
62
+ const [sortDesc, setSortDesc] = useState(true);
63
+
64
+ const filteredSkills = useMemo(() => {
65
+ let result = skills;
66
+ if (filter !== "ALL") {
67
+ result = result.filter((skill) => skill.status === filter);
68
+ }
69
+ if (!sortDesc) {
70
+ return result;
71
+ }
72
+ return result.reduceRight<DerivedSkill[]>((acc, skill) => {
73
+ acc.push(skill);
74
+ return acc;
75
+ }, []);
76
+ }, [filter, skills, sortDesc]);
77
+
78
+ const counts = useMemo<Record<FilterTab, number>>(() => {
79
+ const nextCounts: Record<FilterTab, number> = {
80
+ ALL: skills.length,
81
+ HEALTHY: 0,
82
+ WARNING: 0,
83
+ CRITICAL: 0,
84
+ UNGRADED: 0,
85
+ };
86
+
87
+ for (const skill of skills) {
88
+ if (skill.status in nextCounts) {
89
+ nextCounts[skill.status as Exclude<FilterTab, "ALL">]++;
90
+ }
91
+ }
92
+
93
+ return nextCounts;
94
+ }, [skills]);
95
+
96
+ if (isLoading) {
97
+ return <SkillsLibrarySkeleton />;
98
+ }
99
+
100
+ if (error) {
101
+ return <SkillsLibraryError message={error} onRetry={onRetry} />;
102
+ }
103
+
104
+ return (
105
+ <div
106
+ data-parity-root="skills-library"
107
+ className="@container/main flex flex-1 animate-in fade-in flex-col gap-8 px-4 py-8 duration-500 lg:px-6"
108
+ >
109
+ <div>
110
+ <h1 className="font-headline text-4xl font-bold tracking-tight text-foreground">
111
+ Skills Library
112
+ </h1>
113
+ <p className="mt-2 max-w-2xl text-sm text-muted-foreground">
114
+ Monitor and manage your evolving skill definitions across all scopes.
115
+ </p>
116
+ </div>
117
+
118
+ <div className="grid grid-cols-12 gap-6">
119
+ {heroSkill ? (
120
+ <SkillHeroCard
121
+ skillName={heroSkill.skillName}
122
+ skillScope={heroSkill.skillScope ?? null}
123
+ platforms={heroSkill.platforms}
124
+ passRate={heroSkill.passRate}
125
+ totalChecks={heroSkill.totalChecks}
126
+ uniqueSessions={heroSkill.uniqueSessions}
127
+ status={heroSkill.status}
128
+ latestEvolutionTimestamp={heroSkill.latestEvolutionTimestamp ?? null}
129
+ renderActions={renderHeroActions}
130
+ />
131
+ ) : (
132
+ <SkillHeroEmpty />
133
+ )}
134
+
135
+ <div className="col-span-12 flex flex-col gap-6 lg:col-span-4">
136
+ <LibraryHealthCard aggregatePassRate={aggregatePassRate} gradedCount={gradedCount} />
137
+ <PendingProposalsCard proposals={pendingProposals} />
138
+ </div>
139
+ </div>
140
+
141
+ <div className="space-y-6">
142
+ <SkillFilterTabs
143
+ filter={filter}
144
+ onFilterChange={setFilter}
145
+ counts={counts}
146
+ sortDesc={sortDesc}
147
+ onSortToggle={() => setSortDesc((value) => !value)}
148
+ />
149
+
150
+ {filteredSkills.length > 0 ? (
151
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3">
152
+ {filteredSkills.map((skill) => (
153
+ <SkillCardItem key={skill.name} skill={skill} renderActions={renderCardActions} />
154
+ ))}
155
+ </div>
156
+ ) : (
157
+ <SkillGridEmpty />
158
+ )}
159
+ </div>
160
+ </div>
161
+ );
162
+ }
@@ -0,0 +1,6 @@
1
+ export {
2
+ SkillsLibraryScreen,
3
+ type SkillsLibraryHero,
4
+ type SkillsLibraryPendingProposal,
5
+ type SkillsLibraryScreenProps,
6
+ } from "./SkillsLibraryScreen";
@@ -1,4 +1,4 @@
1
- import type { PushPayloadV2 } from "../src/schemas.js";
1
+ import type { PushPayloadV2 } from "../src/types.js";
2
2
 
3
3
  /**
4
4
  * A valid PushPayloadV2 with at least one of every record type.
@@ -1,4 +1,4 @@
1
- import type { PushPayloadV2 } from "../src/schemas.js";
1
+ import type { PushPayloadV2 } from "../src/types.js";
2
2
 
3
3
  /**
4
4
  * A valid PushPayloadV2 with only evolution_evidence entries and
@@ -7,7 +7,7 @@ import type { PushPayloadV2 } from "../src/schemas.js";
7
7
  export const evidenceOnlyPush: PushPayloadV2 = {
8
8
  schema_version: "2.0",
9
9
  client_version: "0.9.0",
10
- push_id: "d4e5f6a7-b8c9-0123-defa-234567890123",
10
+ push_id: "d4e5f6a7-b8c9-8123-9efa-234567890123",
11
11
  normalizer_version: "0.2.1",
12
12
  canonical: {
13
13
  sessions: [],
@@ -1,7 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
-
5
4
  import { CANONICAL_SCHEMA_VERSION } from "../src/types.js";
6
5
  import { isCanonicalRecord } from "../src/validators.js";
7
6
 
@@ -1,4 +1,4 @@
1
- import type { PushPayloadV2 } from "../src/schemas.js";
1
+ import type { PushPayloadV2 } from "../src/types.js";
2
2
 
3
3
  /**
4
4
  * A valid PushPayloadV2 with zero sessions but non-empty evolution_evidence.
@@ -1,4 +1,4 @@
1
- import type { PushPayloadV2 } from "../src/schemas.js";
1
+ import type { PushPayloadV2 } from "../src/types.js";
2
2
 
3
3
  /**
4
4
  * A valid PushPayloadV2 with invocations and prompts that reference a
@@ -10,7 +10,7 @@ import type { PushPayloadV2 } from "../src/schemas.js";
10
10
  export const partialPushUnresolvedParents: PushPayloadV2 = {
11
11
  schema_version: "2.0",
12
12
  client_version: "0.9.0",
13
- push_id: "c3d4e5f6-a7b8-9012-cdef-123456789012",
13
+ push_id: "c3d4e5f6-a7b8-8012-8def-123456789012",
14
14
  normalizer_version: "0.2.1",
15
15
  canonical: {
16
16
  sessions: [],
@@ -13,9 +13,9 @@
13
13
  "type": "module",
14
14
  "exports": {
15
15
  ".": "./index.ts",
16
- "./schemas": "./src/schemas.ts",
17
16
  "./types": "./src/types.ts",
18
17
  "./validators": "./src/validators.ts",
18
+ "./schemas": "./src/schemas.ts",
19
19
  "./fixtures": "./fixtures/index.ts"
20
20
  },
21
21
  "dependencies": {
@@ -1,2 +1,3 @@
1
+ export * from "./schemas.js";
1
2
  export * from "./types.js";
2
3
  export * from "./validators.js";
@@ -1,5 +1,13 @@
1
- import { z } from "zod";
1
+ /**
2
+ * Zod validation schemas for all canonical telemetry record types
3
+ * and the PushPayloadV2 envelope.
4
+ *
5
+ * This is the single source of truth -- cloud consumers should import
6
+ * from @selftune/telemetry-contract/schemas instead of maintaining
7
+ * their own copies.
8
+ */
2
9
 
10
+ import { z } from "zod";
3
11
  import {
4
12
  CANONICAL_CAPTURE_MODES,
5
13
  CANONICAL_COMPLETION_STATUSES,
@@ -11,6 +19,8 @@ import {
11
19
  CANONICAL_SOURCE_SESSION_KINDS,
12
20
  } from "./types.js";
13
21
 
22
+ // ---------- Shared enum schemas ----------
23
+
14
24
  export const canonicalPlatformSchema = z.enum(CANONICAL_PLATFORMS);
15
25
  export const captureModeSchema = z.enum(CANONICAL_CAPTURE_MODES);
16
26
  export const sourceSessionKindSchema = z.enum(CANONICAL_SOURCE_SESSION_KINDS);
@@ -19,6 +29,8 @@ export const invocationModeSchema = z.enum(CANONICAL_INVOCATION_MODES);
19
29
  export const completionStatusSchema = z.enum(CANONICAL_COMPLETION_STATUSES);
20
30
  export const recordKindSchema = z.enum(CANONICAL_RECORD_KINDS);
21
31
 
32
+ // ---------- Shared structural schemas ----------
33
+
22
34
  export const rawSourceRefSchema = z.object({
23
35
  path: z.string().optional(),
24
36
  line: z.number().int().nonnegative().optional(),
@@ -42,6 +54,8 @@ export const canonicalSessionRecordBaseSchema = canonicalRecordBaseSchema.extend
42
54
  session_id: z.string().min(1),
43
55
  });
44
56
 
57
+ // ---------- Canonical record schemas ----------
58
+
45
59
  export const CanonicalSessionRecordSchema = canonicalSessionRecordBaseSchema.extend({
46
60
  record_kind: z.literal("session"),
47
61
  external_session_id: z.string().optional(),
@@ -126,10 +140,13 @@ export const CanonicalEvolutionEvidenceRecordSchema = z.object({
126
140
  evidence_id: z.string().min(1),
127
141
  skill_name: z.string().min(1),
128
142
  proposal_id: z.string().optional(),
143
+ timestamp: z.string().datetime().optional(),
144
+ skill_path: z.string().optional(),
129
145
  target: z.string().min(1),
130
146
  stage: z.string().min(1),
131
147
  rationale: z.string().optional(),
132
148
  confidence: z.number().min(0).max(1).optional(),
149
+ details: z.string().optional(),
133
150
  original_text: z.string().optional(),
134
151
  proposed_text: z.string().optional(),
135
152
  eval_set_json: z.unknown().optional(),
@@ -137,6 +154,39 @@ export const CanonicalEvolutionEvidenceRecordSchema = z.object({
137
154
  raw_source_ref: rawSourceRefSchema.optional(),
138
155
  });
139
156
 
157
+ export const CanonicalGradingResultRecordSchema = z.object({
158
+ grading_id: z.string().min(1),
159
+ session_id: z.string().min(1),
160
+ skill_name: z.string().min(1),
161
+ transcript_path: z.string().nullable().optional(),
162
+ graded_at: z.string().min(1),
163
+ pass_rate: z.number().min(0).max(1).nullable().optional(),
164
+ mean_score: z.number().min(0).max(1).nullable().optional(),
165
+ score_std_dev: z.number().nullable().optional(),
166
+ passed_count: z.number().int().nonnegative().nullable().optional(),
167
+ failed_count: z.number().int().nonnegative().nullable().optional(),
168
+ total_count: z.number().int().nonnegative().nullable().optional(),
169
+ expectations_json: z.string().nullable().optional(),
170
+ claims_json: z.string().nullable().optional(),
171
+ eval_feedback_json: z.string().nullable().optional(),
172
+ failure_feedback_json: z.string().nullable().optional(),
173
+ execution_metrics_json: z.string().nullable().optional(),
174
+ });
175
+
176
+ export const CanonicalImprovementSignalRecordSchema = z.object({
177
+ signal_id: z.string().min(1),
178
+ timestamp: z.string().min(1),
179
+ session_id: z.string().min(1),
180
+ query: z.string().min(1),
181
+ signal_type: z.string().min(1),
182
+ mentioned_skill: z.string().nullable().optional(),
183
+ consumed: z.boolean(),
184
+ consumed_at: z.string().nullable().optional(),
185
+ consumed_by_run: z.string().nullable().optional(),
186
+ });
187
+
188
+ // ---------- Orchestrate run schemas ----------
189
+
140
190
  export const OrchestrateRunSkillActionSchema = z.object({
141
191
  skill: z.string().min(1),
142
192
  action: z.enum(["evolve", "watch", "skip"]),
@@ -163,12 +213,12 @@ export const PushOrchestrateRunRecordSchema = z.object({
163
213
  skill_actions: z.array(OrchestrateRunSkillActionSchema),
164
214
  });
165
215
 
216
+ // ---------- Push V2 envelope ----------
217
+
166
218
  export const PushPayloadV2Schema = z.object({
167
219
  schema_version: z.literal("2.0"),
168
220
  client_version: z.string().min(1),
169
- // Queue-generated push IDs are typically UUIDs, but the wire contract only
170
- // requires a stable non-empty idempotency key.
171
- push_id: z.string().min(1),
221
+ push_id: z.string().uuid(),
172
222
  normalizer_version: z.string().min(1),
173
223
  canonical: z.object({
174
224
  sessions: z.array(CanonicalSessionRecordSchema).min(0),
@@ -178,10 +228,14 @@ export const PushPayloadV2Schema = z.object({
178
228
  normalization_runs: z.array(CanonicalNormalizationRunRecordSchema).min(0),
179
229
  evolution_evidence: z.array(CanonicalEvolutionEvidenceRecordSchema).optional(),
180
230
  orchestrate_runs: z.array(PushOrchestrateRunRecordSchema).optional(),
231
+ grading_results: z.array(CanonicalGradingResultRecordSchema).optional(),
232
+ improvement_signals: z.array(CanonicalImprovementSignalRecordSchema).optional(),
181
233
  }),
182
234
  });
183
235
 
184
- export type PushPayloadV2 = z.infer<typeof PushPayloadV2Schema>;
236
+ // ---------- Inferred types from Zod schemas ----------
237
+
238
+ export type ZodPushPayloadV2 = z.infer<typeof PushPayloadV2Schema>;
185
239
  export type ZodCanonicalSessionRecord = z.infer<typeof CanonicalSessionRecordSchema>;
186
240
  export type ZodCanonicalPromptRecord = z.infer<typeof CanonicalPromptRecordSchema>;
187
241
  export type ZodCanonicalSkillInvocationRecord = z.infer<
@@ -194,4 +248,8 @@ export type ZodCanonicalNormalizationRunRecord = z.infer<
194
248
  export type ZodCanonicalEvolutionEvidenceRecord = z.infer<
195
249
  typeof CanonicalEvolutionEvidenceRecordSchema
196
250
  >;
251
+ export type ZodCanonicalGradingResultRecord = z.infer<typeof CanonicalGradingResultRecordSchema>;
252
+ export type ZodCanonicalImprovementSignalRecord = z.infer<
253
+ typeof CanonicalImprovementSignalRecordSchema
254
+ >;
197
255
  export type ZodPushOrchestrateRunRecord = z.infer<typeof PushOrchestrateRunRecordSchema>;
@@ -1,7 +1,7 @@
1
1
  export const CANONICAL_SCHEMA_VERSION = "2.0" as const;
2
2
  export type CanonicalSchemaVersion = typeof CANONICAL_SCHEMA_VERSION;
3
3
 
4
- export const CANONICAL_PLATFORMS = ["claude_code", "codex", "opencode", "openclaw"] as const;
4
+ export const CANONICAL_PLATFORMS = ["claude_code", "codex", "opencode", "openclaw", "pi"] as const;
5
5
  export type CanonicalPlatform = (typeof CANONICAL_PLATFORMS)[number];
6
6
 
7
7
  export const CANONICAL_CAPTURE_MODES = [
@@ -54,7 +54,7 @@ export const CANONICAL_RECORD_KINDS = [
54
54
  ] as const;
55
55
  export type CanonicalRecordKind = (typeof CANONICAL_RECORD_KINDS)[number];
56
56
 
57
- export interface CanonicalRawSourceRef {
57
+ export interface CanonicalRawSourceRef extends Record<string, unknown> {
58
58
  path?: string;
59
59
  line?: number;
60
60
  event_type?: string;
@@ -62,7 +62,7 @@ export interface CanonicalRawSourceRef {
62
62
  metadata?: Record<string, unknown>;
63
63
  }
64
64
 
65
- export interface CanonicalRecordBase {
65
+ export interface CanonicalRecordBase extends Record<string, unknown> {
66
66
  record_kind: CanonicalRecordKind;
67
67
  schema_version: CanonicalSchemaVersion;
68
68
  normalizer_version: string;
@@ -146,15 +146,14 @@ export interface CanonicalExecutionFactRecord extends CanonicalSessionRecordBase
146
146
  cached_input_tokens?: number;
147
147
  reasoning_output_tokens?: number;
148
148
  cost_usd?: number;
149
- duration_ms?: number;
150
149
  files_changed?: number;
151
150
  lines_added?: number;
152
151
  lines_removed?: number;
153
152
  lines_modified?: number;
154
- /** Count of output-producing tool calls (Write, Edit, WebFetch, WebSearch, Skill, Agent). */
155
153
  artifact_count?: number;
156
- /** Inferred session type based on tool distribution. */
157
- session_type?: "dev" | "research" | "content" | "mixed";
154
+ session_type?: string;
155
+ agent_summary?: string;
156
+ duration_ms?: number;
158
157
  completion_status?: CanonicalCompletionStatus;
159
158
  end_reason?: string;
160
159
  }
@@ -168,9 +167,100 @@ export interface CanonicalNormalizationRunRecord extends CanonicalRecordBase {
168
167
  repair_applied: boolean;
169
168
  }
170
169
 
170
+ export interface CanonicalEvolutionEvidenceRecord {
171
+ evidence_id?: string;
172
+ timestamp?: string;
173
+ proposal_id?: string;
174
+ skill_name: string;
175
+ skill_path?: string;
176
+ target: string;
177
+ stage: string;
178
+ rationale?: string;
179
+ confidence?: number;
180
+ details?: string;
181
+ original_text?: string;
182
+ proposed_text?: string;
183
+ eval_set_json?: unknown;
184
+ validation_json?: unknown;
185
+ raw_source_ref?: CanonicalRawSourceRef;
186
+ }
187
+
188
+ export interface CanonicalGradingResultRecord {
189
+ grading_id: string;
190
+ session_id: string;
191
+ skill_name: string;
192
+ transcript_path?: string | null;
193
+ graded_at: string;
194
+ pass_rate?: number | null;
195
+ mean_score?: number | null;
196
+ score_std_dev?: number | null;
197
+ passed_count?: number | null;
198
+ failed_count?: number | null;
199
+ total_count?: number | null;
200
+ expectations_json?: string | null;
201
+ claims_json?: string | null;
202
+ eval_feedback_json?: string | null;
203
+ failure_feedback_json?: string | null;
204
+ execution_metrics_json?: string | null;
205
+ }
206
+
207
+ export interface CanonicalImprovementSignalRecord {
208
+ signal_id: string;
209
+ timestamp: string;
210
+ session_id: string;
211
+ query: string;
212
+ signal_type: string;
213
+ mentioned_skill?: string | null;
214
+ consumed: boolean;
215
+ consumed_at?: string | null;
216
+ consumed_by_run?: string | null;
217
+ }
218
+
171
219
  export type CanonicalRecord =
172
220
  | CanonicalSessionRecord
173
221
  | CanonicalPromptRecord
174
222
  | CanonicalSkillInvocationRecord
175
223
  | CanonicalExecutionFactRecord
176
224
  | CanonicalNormalizationRunRecord;
225
+
226
+ export interface PushOrchestrateRunRecord {
227
+ run_id: string;
228
+ timestamp: string;
229
+ elapsed_ms: number;
230
+ dry_run: boolean;
231
+ approval_mode: "auto" | "review";
232
+ total_skills: number;
233
+ evaluated: number;
234
+ evolved: number;
235
+ deployed: number;
236
+ watched: number;
237
+ skipped: number;
238
+ skill_actions: Array<{
239
+ skill: string;
240
+ action: "evolve" | "watch" | "skip";
241
+ reason: string;
242
+ deployed?: boolean;
243
+ rolledBack?: boolean;
244
+ alert?: string | null;
245
+ elapsed_ms?: number;
246
+ llm_calls?: number;
247
+ }>;
248
+ }
249
+
250
+ export interface PushPayloadV2 {
251
+ schema_version: CanonicalSchemaVersion;
252
+ client_version: string;
253
+ push_id: string;
254
+ normalizer_version: string;
255
+ canonical: {
256
+ sessions: CanonicalSessionRecord[];
257
+ prompts: CanonicalPromptRecord[];
258
+ skill_invocations: CanonicalSkillInvocationRecord[];
259
+ execution_facts: CanonicalExecutionFactRecord[];
260
+ normalization_runs: CanonicalNormalizationRunRecord[];
261
+ evolution_evidence?: CanonicalEvolutionEvidenceRecord[];
262
+ orchestrate_runs?: PushOrchestrateRunRecord[];
263
+ grading_results?: CanonicalGradingResultRecord[];
264
+ improvement_signals?: CanonicalImprovementSignalRecord[];
265
+ };
266
+ }
@@ -1,5 +1,4 @@
1
1
  import { describe, expect, test } from "bun:test";
2
-
3
2
  import { completePush } from "../fixtures/complete-push.js";
4
3
  import { evidenceOnlyPush } from "../fixtures/evidence-only-push.js";
5
4
  import { partialPushNoSessions } from "../fixtures/partial-push-no-sessions.js";
@@ -0,0 +1,16 @@
1
+ # @selftune/ui
2
+
3
+ Shared React component library used by both the cloud dashboard and the local OSS dashboard. Canonical copy lives here; synced to `oss/selftune/packages/ui` via `scripts/sync-embedded-shared.sh`.
4
+
5
+ | Directory | Contents |
6
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | `src/primitives/` | Base UI: Badge, Button, Card, Checkbox, Collapsible, DropdownMenu, Label, Select, Table, Tabs, Tooltip |
8
+ | `src/components/` | Shared components: SkillHealthGrid, EvolutionTimeline, EvidenceViewer, ActivityTimeline, OrchestrateRunsPanel, SectionCards, InfoTip, SkillReportPanels, SkillReportGuide, InvocationsPanel, SkillsLibrary, AnalyticsCharts, OverviewPanels |
9
+ | `src/types.ts` | Shared types: SkillCard, SkillHealthStatus, EvalSnapshot, EvolutionEntry, TrustState, TrustFields, ExampleRow, AutonomyStatus, TrustWatchlistEntry, AttentionItem, AutonomousDecision |
10
+ | `src/lib/` | Utilities: format (formatRate, timeAgo), constants (STATUS_CONFIG), utils (deriveStatus, sortByPassRateAndChecks) |
11
+
12
+ **Exports:** `./primitives`, `./components`, `./types`, `./lib`
13
+
14
+ **Dependencies:** react, @base-ui/react, lucide-react, clsx, tailwind-merge
15
+
16
+ **Important:** Do NOT edit `oss/selftune/packages/ui/` directly. Edit here and run `scripts/sync-embedded-shared.sh`.
@@ -57,7 +57,7 @@ Presentational components for selftune dashboard views. No data fetching, no rou
57
57
  | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
58
58
  | `SkillHealthGrid` | Sortable/filterable data table with drag-and-drop, pagination, and view tabs. Accepts `renderSkillName` prop for custom routing. |
59
59
  | `EvolutionTimeline` | Proposal lifecycle timeline grouped by proposal ID, with pass rate deltas. |
60
- | `ActivityPanel` | Tabbed activity feed (undeployed proposals, timeline events, unmatched queries). |
60
+ | `ActivityPanel` | Tabbed activity feed (pending proposals, timeline events, unmatched queries). |
61
61
  | `EvidenceViewer` | Full evidence trail for a proposal — side-by-side diffs, validation results, iteration rounds. |
62
62
  | `SectionCards` | Dashboard metric stat cards (skills count, pass rate, unmatched, sessions, etc.). |
63
63
  | `OrchestrateRunsPanel` | Collapsible orchestrate run reports with per-skill action details. |
@@ -38,7 +38,7 @@
38
38
  "react": "^19.0.0",
39
39
  "react-dom": "^19.0.0",
40
40
  "react-markdown": "^10.0.0",
41
- "recharts": "^2.0.0"
41
+ "recharts": "^3.0.0"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "@dnd-kit/core": {