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
@@ -42,7 +42,17 @@ import {
42
42
  tryOpenUrl,
43
43
  } from "./auth/device-code.js";
44
44
  import { installAgentFiles } from "./claude-agents.js";
45
- import { CLAUDE_CODE_HOOK_KEYS, SELFTUNE_CONFIG_DIR, SELFTUNE_CONFIG_PATH } from "./constants.js";
45
+ import {
46
+ CLAUDE_CODE_HOOK_KEYS,
47
+ CLAUDE_CODE_PROJECTS_DIR,
48
+ OPENCLAW_AGENTS_DIR,
49
+ PI_SESSIONS_DIR,
50
+ REPAIRED_SKILL_LOG,
51
+ REPAIRED_SKILL_SESSIONS_MARKER,
52
+ SELFTUNE_CONFIG_DIR,
53
+ SELFTUNE_CONFIG_PATH,
54
+ SKILL_LOG,
55
+ } from "./constants.js";
46
56
  import type { AgentCommandGuidance, AlphaIdentity, SelftuneConfig } from "./types.js";
47
57
  import { CLIError, handleCLIError } from "./utils/cli-error.js";
48
58
  import { hookKeyHasSelftuneEntry, isSelftuneCommand } from "./utils/hooks.js";
@@ -75,13 +85,16 @@ class InitCliError extends Error {
75
85
  * 1. Claude Code — ~/.claude/ directory exists AND (`which claude` OR env signals)
76
86
  * 2. Codex — $CODEX_HOME set OR `which codex`
77
87
  * 3. OpenCode — ~/.local/share/opencode/opencode.db exists OR `which opencode`
78
- * 4. "unknown" fallback
88
+ * 4. OpenClaw — ~/.openclaw/agents/ exists OR `which openclaw`
89
+ * 5. Pi — ~/.pi/agent/ exists OR `which pi`
90
+ * 6. "unknown" fallback
79
91
  */
80
92
  const VALID_AGENT_TYPES: SelftuneConfig["agent_type"][] = [
81
93
  "claude_code",
82
94
  "codex",
83
95
  "opencode",
84
96
  "openclaw",
97
+ "pi",
85
98
  "unknown",
86
99
  ];
87
100
 
@@ -90,6 +103,7 @@ const AGENT_TYPE_CLI_MAP: Record<string, string> = {
90
103
  codex: "codex",
91
104
  opencode: "opencode",
92
105
  openclaw: "openclaw",
106
+ pi: "pi",
93
107
  };
94
108
 
95
109
  function agentTypeToCli(agentType: string): string | null {
@@ -134,6 +148,12 @@ export function detectAgentType(
134
148
  return "openclaw";
135
149
  }
136
150
 
151
+ // Pi: .pi directory or binary
152
+ const piDir = join(home, ".pi", "agent");
153
+ if (existsSync(piDir) || Bun.which("pi")) {
154
+ return "pi";
155
+ }
156
+
137
157
  return "unknown";
138
158
  }
139
159
 
@@ -990,19 +1010,33 @@ export async function cliMain(): Promise<void> {
990
1010
  try {
991
1011
  const { syncSources } = await import("./sync.js");
992
1012
  const syncResult = syncSources({
1013
+ projectsDir: CLAUDE_CODE_PROJECTS_DIR,
1014
+ codexHome: join(homedir(), ".codex"),
1015
+ opencodeDataDir: join(
1016
+ process.env.XDG_DATA_HOME ?? join(homedir(), ".local", "share"),
1017
+ "opencode",
1018
+ ),
1019
+ openclawAgentsDir: OPENCLAW_AGENTS_DIR,
1020
+ piSessionsDir: PI_SESSIONS_DIR,
1021
+ skillLogPath: SKILL_LOG,
1022
+ repairedSkillLogPath: REPAIRED_SKILL_LOG,
1023
+ repairedSessionsPath: REPAIRED_SKILL_SESSIONS_MARKER,
993
1024
  syncClaude: true,
994
1025
  syncCodex: true,
995
1026
  syncOpenCode: true,
996
1027
  syncOpenClaw: true,
1028
+ syncPi: true,
997
1029
  rebuildSkillUsage: true,
998
1030
  dryRun: false,
1031
+ force: false,
999
1032
  });
1000
1033
 
1001
1034
  const totalSynced =
1002
1035
  (syncResult.sources.claude?.synced ?? 0) +
1003
1036
  (syncResult.sources.codex?.synced ?? 0) +
1004
1037
  (syncResult.sources.opencode?.synced ?? 0) +
1005
- (syncResult.sources.openclaw?.synced ?? 0);
1038
+ (syncResult.sources.openclaw?.synced ?? 0) +
1039
+ (syncResult.sources.pi?.synced ?? 0);
1006
1040
 
1007
1041
  console.log(
1008
1042
  JSON.stringify({
@@ -1115,7 +1149,7 @@ export function checkAlphaReadiness(configPath: string): {
1115
1149
 
1116
1150
  // Guard: only run when invoked directly
1117
1151
  const isMain =
1118
- (import.meta as Record<string, unknown>).main === true ||
1152
+ (import.meta as unknown as Record<string, unknown>).main === true ||
1119
1153
  process.argv[1] === fileURLToPath(import.meta.url);
1120
1154
 
1121
1155
  if (isMain) {
@@ -469,7 +469,7 @@ export function updateSignalConsumed(
469
469
  `,
470
470
  ).run(new Date().toISOString(), runId, sessionId, query, signalType),
471
471
  );
472
- return result?.changes > 0;
472
+ return (result?.changes ?? 0) > 0;
473
473
  }
474
474
 
475
475
  export function writeCommitTracking(record: {
@@ -500,6 +500,125 @@ export function writeCommitTracking(record: {
500
500
  });
501
501
  }
502
502
 
503
+ // -- Grading baseline writer ---------------------------------------------------
504
+
505
+ export interface GradingBaselineInput {
506
+ skill_name: string;
507
+ proposal_id: string | null;
508
+ measured_at: string;
509
+ pass_rate: number;
510
+ mean_score: number | null;
511
+ sample_size: number;
512
+ grading_results_json: string | null;
513
+ }
514
+
515
+ export function writeGradingBaseline(baseline: GradingBaselineInput): boolean {
516
+ return safeWrite("grading-baseline", (db) => {
517
+ getStmt(
518
+ db,
519
+ "grading-baseline",
520
+ `
521
+ INSERT INTO grading_baselines
522
+ (skill_name, proposal_id, measured_at, pass_rate, mean_score, sample_size, grading_results_json)
523
+ VALUES (?, ?, ?, ?, ?, ?, ?)
524
+ `,
525
+ ).run(
526
+ baseline.skill_name,
527
+ baseline.proposal_id ?? null,
528
+ baseline.measured_at,
529
+ baseline.pass_rate,
530
+ baseline.mean_score ?? null,
531
+ baseline.sample_size,
532
+ baseline.grading_results_json ?? null,
533
+ );
534
+ });
535
+ }
536
+
537
+ // -- Cron run audit writer -----------------------------------------------------
538
+
539
+ export function writeCronRunToDb(
540
+ db: Database,
541
+ entry: {
542
+ jobName: string;
543
+ startedAt: string;
544
+ elapsedMs: number;
545
+ status: "success" | "error";
546
+ metrics?: Record<string, unknown>;
547
+ error?: string;
548
+ },
549
+ ): void {
550
+ try {
551
+ getStmt(
552
+ db,
553
+ "cron-run",
554
+ `
555
+ INSERT OR IGNORE INTO cron_runs
556
+ (job_name, started_at, elapsed_ms, status, metrics_json, error)
557
+ VALUES (?, ?, ?, ?, ?, ?)
558
+ `,
559
+ ).run(
560
+ entry.jobName,
561
+ entry.startedAt,
562
+ entry.elapsedMs,
563
+ entry.status,
564
+ entry.metrics ? JSON.stringify(entry.metrics) : null,
565
+ entry.error ?? null,
566
+ );
567
+ } catch {
568
+ /* fail-open: never throw from audit logging */
569
+ }
570
+ }
571
+
572
+ // -- Replay entry results writer -----------------------------------------------
573
+
574
+ export interface ReplayEntryResultInput {
575
+ proposal_id: string;
576
+ skill_name: string;
577
+ validation_mode: string;
578
+ phase: string;
579
+ query: string;
580
+ should_trigger: boolean;
581
+ triggered: boolean;
582
+ passed: boolean;
583
+ evidence?: string;
584
+ }
585
+
586
+ export function writeReplayEntryResultsToDb(results: ReplayEntryResultInput[]): boolean {
587
+ if (results.length === 0) return true;
588
+ return safeWrite("replay-entry-results", (db) => {
589
+ db.run("BEGIN TRANSACTION");
590
+ try {
591
+ const stmt = getStmt(
592
+ db,
593
+ "replay-entry-result",
594
+ `
595
+ INSERT INTO replay_entry_results
596
+ (proposal_id, skill_name, validation_mode, phase, query,
597
+ should_trigger, triggered, passed, evidence)
598
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
599
+ `,
600
+ );
601
+ for (const r of results) {
602
+ stmt.run(
603
+ r.proposal_id,
604
+ r.skill_name,
605
+ r.validation_mode,
606
+ r.phase,
607
+ r.query,
608
+ r.should_trigger ? 1 : 0,
609
+ r.triggered ? 1 : 0,
610
+ r.passed ? 1 : 0,
611
+ r.evidence ?? null,
612
+ );
613
+ }
614
+ db.run("COMMIT");
615
+ } catch (err) {
616
+ db.run("ROLLBACK");
617
+ throw err;
618
+ }
619
+ });
620
+ }
621
+
503
622
  // -- Internal insert helpers (used by cached statements) ----------------------
504
623
 
505
624
  function insertSession(db: Database, s: CanonicalSessionRecord): void {
@@ -1,18 +1,17 @@
1
1
  /**
2
- * Materializer: reads JSONL source-of-truth logs and inserts structured
2
+ * Materializer: reads legacy/exported JSONL files and inserts structured
3
3
  * records into the local SQLite database.
4
4
  *
5
+ * IMPORTANT: SQLite is the sole write target (Phase 3 complete). JSONL files
6
+ * on disk contain only pre-cutover history. This materializer is ONLY used for:
7
+ * 1. Recovery from selftune export JSONL snapshots
8
+ * 2. Backfill of pre-cutover JSONL data into a fresh SQLite DB
9
+ *
5
10
  * Supports two modes:
6
11
  * - Full rebuild: drops all data and re-inserts from scratch
7
12
  * - Incremental: only inserts records newer than last materialization
8
13
  */
9
14
 
10
- // NOTE: With dual-write active (Phase 1+), hooks insert directly into SQLite.
11
- // The materializer is only needed for:
12
- // 1. Initial startup (to catch pre-existing JSONL data from before dual-write)
13
- // 2. Manual recovery after exporting JSONL and recreating the DB file
14
- // 3. Backfill from batch ingestors that don't yet dual-write
15
-
16
15
  import type { Database } from "bun:sqlite";
17
16
 
18
17
  import {
@@ -0,0 +1,34 @@
1
+ import type { Database } from "bun:sqlite";
2
+
3
+ export interface CronRun {
4
+ id: number;
5
+ job_name: string;
6
+ started_at: string;
7
+ elapsed_ms: number;
8
+ status: string;
9
+ metrics_json: string | null;
10
+ error: string | null;
11
+ }
12
+
13
+ export function getRecentCronRuns(db: Database, limit = 50): CronRun[] {
14
+ return db
15
+ .query(
16
+ `SELECT id, job_name, started_at, elapsed_ms, status, metrics_json, error
17
+ FROM cron_runs
18
+ ORDER BY started_at DESC
19
+ LIMIT ?`,
20
+ )
21
+ .all(limit) as CronRun[];
22
+ }
23
+
24
+ export function getCronRunsByJob(db: Database, jobName: string, limit = 50): CronRun[] {
25
+ return db
26
+ .query(
27
+ `SELECT id, job_name, started_at, elapsed_ms, status, metrics_json, error
28
+ FROM cron_runs
29
+ WHERE job_name = ?
30
+ ORDER BY started_at DESC
31
+ LIMIT ?`,
32
+ )
33
+ .all(jobName, limit) as CronRun[];
34
+ }