selftune 0.2.18 → 0.2.19

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 (65) hide show
  1. package/README.md +9 -4
  2. package/apps/local-dashboard/dist/assets/index-DnhnXQm6.js +60 -0
  3. package/apps/local-dashboard/dist/assets/index-_EcLywDg.css +1 -0
  4. package/apps/local-dashboard/dist/assets/vendor-table-BIiI3YhS.js +1 -0
  5. package/apps/local-dashboard/dist/assets/vendor-ui-CGEmUayx.js +12 -0
  6. package/apps/local-dashboard/dist/index.html +5 -5
  7. package/cli/selftune/alpha-upload/stage-canonical.ts +7 -6
  8. package/cli/selftune/constants.ts +10 -0
  9. package/cli/selftune/contribute/contribute.ts +30 -2
  10. package/cli/selftune/contribution-config.ts +249 -0
  11. package/cli/selftune/contribution-relay.ts +177 -0
  12. package/cli/selftune/contribution-signals.ts +219 -0
  13. package/cli/selftune/contribution-staging.ts +147 -0
  14. package/cli/selftune/contributions.ts +532 -0
  15. package/cli/selftune/creator-contributions.ts +333 -0
  16. package/cli/selftune/dashboard-contract.ts +205 -1
  17. package/cli/selftune/dashboard-server.ts +45 -11
  18. package/cli/selftune/eval/family-overlap.ts +395 -0
  19. package/cli/selftune/eval/hooks-to-evals.ts +182 -28
  20. package/cli/selftune/eval/synthetic-evals.ts +298 -11
  21. package/cli/selftune/export.ts +2 -2
  22. package/cli/selftune/index.ts +41 -5
  23. package/cli/selftune/ingestors/codex-rollout.ts +31 -35
  24. package/cli/selftune/ingestors/codex-wrapper.ts +32 -24
  25. package/cli/selftune/localdb/db.ts +2 -2
  26. package/cli/selftune/localdb/queries.ts +701 -30
  27. package/cli/selftune/localdb/schema.ts +20 -0
  28. package/cli/selftune/recover.ts +153 -0
  29. package/cli/selftune/repair/skill-usage.ts +363 -4
  30. package/cli/selftune/routes/actions.ts +35 -1
  31. package/cli/selftune/routes/analytics.ts +14 -0
  32. package/cli/selftune/routes/index.ts +1 -0
  33. package/cli/selftune/routes/overview.ts +112 -4
  34. package/cli/selftune/routes/skill-report.ts +569 -10
  35. package/cli/selftune/status.ts +81 -2
  36. package/cli/selftune/sync.ts +56 -2
  37. package/cli/selftune/trust-model.ts +66 -0
  38. package/cli/selftune/types.ts +49 -0
  39. package/cli/selftune/utils/skill-detection.ts +43 -0
  40. package/cli/selftune/watchlist.ts +65 -0
  41. package/package.json +1 -1
  42. package/packages/ui/src/components/ActivityTimeline.tsx +165 -150
  43. package/packages/ui/src/components/EvidenceViewer.tsx +335 -144
  44. package/packages/ui/src/components/EvolutionTimeline.tsx +58 -28
  45. package/packages/ui/src/components/OrchestrateRunsPanel.tsx +33 -16
  46. package/packages/ui/src/components/RecentActivityFeed.tsx +72 -41
  47. package/packages/ui/src/components/section-cards.tsx +12 -9
  48. package/packages/ui/src/primitives/card.tsx +1 -1
  49. package/skill/SKILL.md +11 -1
  50. package/skill/Workflows/AlphaUpload.md +4 -0
  51. package/skill/Workflows/Composability.md +64 -0
  52. package/skill/Workflows/Contribute.md +6 -3
  53. package/skill/Workflows/Contributions.md +97 -0
  54. package/skill/Workflows/CreatorContributions.md +74 -0
  55. package/skill/Workflows/Dashboard.md +31 -0
  56. package/skill/Workflows/Evals.md +57 -8
  57. package/skill/Workflows/Ingest.md +7 -0
  58. package/skill/Workflows/Initialize.md +20 -1
  59. package/skill/Workflows/Recover.md +84 -0
  60. package/skill/Workflows/RepairSkillUsage.md +12 -4
  61. package/skill/Workflows/Sync.md +18 -12
  62. package/apps/local-dashboard/dist/assets/index-BMIS6uUh.css +0 -2
  63. package/apps/local-dashboard/dist/assets/index-DOu3iLD9.js +0 -16
  64. package/apps/local-dashboard/dist/assets/vendor-table-pHbDxq36.js +0 -8
  65. package/apps/local-dashboard/dist/assets/vendor-ui-DIwlrGlb.js +0 -12
@@ -6,6 +6,7 @@
6
6
 
7
7
  export type { ActionRunner } from "./actions.js";
8
8
  export { handleAction, runAction } from "./actions.js";
9
+ export { handleAnalytics } from "./analytics.js";
9
10
  export { handleBadge } from "./badge.js";
10
11
  export { handleDoctor } from "./doctor.js";
11
12
  export { handleOrchestrateRuns } from "./orchestrate-runs.js";
@@ -8,12 +8,24 @@
8
8
 
9
9
  import type { Database } from "bun:sqlite";
10
10
 
11
+ import type {
12
+ AttentionItem,
13
+ AutonomousDecision,
14
+ AutonomyStatus,
15
+ AutonomyStatusLevel,
16
+ OverviewResponse,
17
+ } from "../dashboard-contract.js";
11
18
  import { parseCursorParam, parseIntParam } from "../dashboard-contract.js";
12
19
  import {
20
+ getAttentionQueue,
13
21
  getOverviewPayload,
14
22
  getOverviewPayloadPaginated,
23
+ getRecentDecisions,
24
+ getSkillTrustSummaries,
15
25
  getSkillsList,
16
26
  } from "../localdb/queries.js";
27
+ import { buildTrustWatchlist } from "../trust-model.js";
28
+ import { loadWatchedSkills } from "../watchlist.js";
17
29
 
18
30
  export function handleOverview(
19
31
  db: Database,
@@ -22,18 +34,43 @@ export function handleOverview(
22
34
  ): Response {
23
35
  const skills = getSkillsList(db);
24
36
 
25
- // Check if any pagination params are provided
37
+ // -- Autonomy-first enrichment fields ----------------------------------------
38
+ const attentionQueue = getAttentionQueue(db);
39
+ const recentDecisions = getRecentDecisions(db);
40
+ const trustSummaries = getSkillTrustSummaries(db);
41
+ const pendingReviews = attentionQueue.filter((a) => a.category === "needs_review").length;
42
+
43
+ const trustWatchlist = buildTrustWatchlist(trustSummaries);
44
+ const autonomyStatus = buildAutonomyStatus(
45
+ db,
46
+ attentionQueue,
47
+ recentDecisions,
48
+ skills.length,
49
+ pendingReviews,
50
+ );
51
+
52
+ const enrichment = {
53
+ watched_skills: loadWatchedSkills(),
54
+ autonomy_status: autonomyStatus,
55
+ attention_queue: attentionQueue,
56
+ trust_watchlist: trustWatchlist,
57
+ recent_decisions: recentDecisions,
58
+ };
59
+
60
+ // -- Standard overview payload -----------------------------------------------
26
61
  const hasPaginationParams =
27
62
  searchParams &&
28
63
  (searchParams.has("telemetry_cursor") ||
29
64
  searchParams.has("telemetry_limit") ||
30
65
  searchParams.has("skills_cursor") ||
31
66
  searchParams.has("skills_limit"));
67
+ const hasSkillsPagination =
68
+ searchParams && (searchParams.has("skills_cursor") || searchParams.has("skills_limit"));
32
69
 
33
70
  if (!hasPaginationParams) {
34
- // Backward-compatible: return the unpaginated overview
35
71
  const overview = getOverviewPayload(db);
36
- return Response.json({ overview, skills, version });
72
+ const response: OverviewResponse = { overview, skills, version, ...enrichment };
73
+ return Response.json(response);
37
74
  }
38
75
 
39
76
  // Parse pagination params
@@ -49,5 +86,76 @@ export function handleOverview(
49
86
  skills_limit: skillsLimit,
50
87
  });
51
88
 
52
- return Response.json({ overview, skills, version });
89
+ const paginatedSkillNames = new Set(overview.skills_page.items.map((row) => row.skill_name));
90
+ const paginatedSkills = hasSkillsPagination
91
+ ? skills.filter((skill) => paginatedSkillNames.has(skill.skill_name))
92
+ : skills;
93
+
94
+ return Response.json({ overview, skills: paginatedSkills, version, ...enrichment });
95
+ }
96
+
97
+ // -- Internal helpers ----------------------------------------------------------
98
+
99
+ function buildAutonomyStatus(
100
+ db: Database,
101
+ attentionQueue: AttentionItem[],
102
+ recentDecisions: AutonomousDecision[],
103
+ skillsObserved: number,
104
+ pendingReviews: number,
105
+ ): AutonomyStatus {
106
+ let lastRun: string | null = null;
107
+ try {
108
+ const row = db
109
+ .query(`SELECT timestamp FROM orchestrate_runs ORDER BY timestamp DESC LIMIT 1`)
110
+ .get() as { timestamp: string } | null;
111
+ lastRun = row?.timestamp ?? null;
112
+ } catch {
113
+ // Table may not exist
114
+ }
115
+
116
+ const hasCritical = attentionQueue.some((a) => a.severity === "critical");
117
+
118
+ // "watching" means recent autonomous activity — last run within 24 hours
119
+ // or recent decisions within the 7-day freshness window
120
+ const hasRecentActivity =
121
+ (lastRun != null && Date.now() - new Date(lastRun).getTime() < 24 * 60 * 60 * 1000) ||
122
+ recentDecisions.length > 0;
123
+
124
+ let level: AutonomyStatusLevel;
125
+ if (hasCritical) {
126
+ level = "blocked";
127
+ } else if (pendingReviews > 0) {
128
+ level = "needs_review";
129
+ } else if (hasRecentActivity) {
130
+ level = "watching";
131
+ } else {
132
+ level = "healthy";
133
+ }
134
+
135
+ let summary: string;
136
+ switch (level) {
137
+ case "healthy":
138
+ summary = "No action needed. System is healthy.";
139
+ break;
140
+ case "blocked": {
141
+ const critCount = attentionQueue.filter((a) => a.severity === "critical").length;
142
+ summary = `${critCount} skill${critCount !== 1 ? "s" : ""} need${critCount === 1 ? "s" : ""} urgent attention after rollback.`;
143
+ break;
144
+ }
145
+ case "needs_review":
146
+ summary = `selftune is watching ${skillsObserved} skill${skillsObserved !== 1 ? "s" : ""} and needs review on ${pendingReviews} proposal${pendingReviews !== 1 ? "s" : ""}.`;
147
+ break;
148
+ case "watching":
149
+ summary = `selftune is actively watching ${skillsObserved} skill${skillsObserved !== 1 ? "s" : ""}. No action needed.`;
150
+ break;
151
+ }
152
+
153
+ return {
154
+ level,
155
+ summary,
156
+ last_run: lastRun,
157
+ skills_observed: skillsObserved,
158
+ pending_reviews: pendingReviews,
159
+ attention_required: attentionQueue.length,
160
+ };
53
161
  }