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
@@ -7,6 +7,7 @@
7
7
  * - Codex rollout logs
8
8
  * - OpenCode session history
9
9
  * - OpenClaw session history
10
+ * - Pi session history
10
11
  *
11
12
  * After syncing raw session/query/telemetry records, it rebuilds the repaired
12
13
  * skill-usage overlay from Claude transcripts and Codex rollouts so monitoring,
@@ -25,6 +26,8 @@ import {
25
26
  OPENCLAW_AGENTS_DIR,
26
27
  OPENCLAW_INGEST_MARKER,
27
28
  OPENCODE_INGEST_MARKER,
29
+ PI_INGEST_MARKER,
30
+ PI_SESSIONS_DIR,
28
31
  QUERY_LOG,
29
32
  REPAIRED_SKILL_LOG,
30
33
  REPAIRED_SKILL_SESSIONS_MARKER,
@@ -56,7 +59,14 @@ import {
56
59
  readSessionsFromSqlite,
57
60
  writeSession as writeOpenCodeSession,
58
61
  } from "./ingestors/opencode-ingest.js";
62
+ import {
63
+ findPiSessions,
64
+ findPiSkillNames,
65
+ parsePiSession,
66
+ writeSession as writePiSession,
67
+ } from "./ingestors/pi-ingest.js";
59
68
  import { getDb } from "./localdb/db.js";
69
+ import { writeCronRunToDb } from "./localdb/direct-write.js";
60
70
  import { querySkillUsageRecords } from "./localdb/queries.js";
61
71
  import {
62
72
  persistRepairedSkillUsageToDb,
@@ -91,6 +101,7 @@ export interface SyncResult {
91
101
  codex: SyncStepResult;
92
102
  opencode: SyncStepResult;
93
103
  openclaw: SyncStepResult;
104
+ pi: SyncStepResult;
94
105
  };
95
106
  repair: {
96
107
  ran: boolean;
@@ -113,6 +124,7 @@ export interface SyncOptions {
113
124
  codexHome: string;
114
125
  opencodeDataDir: string;
115
126
  openclawAgentsDir: string;
127
+ piSessionsDir: string;
116
128
  skillLogPath: string;
117
129
  repairedSkillLogPath: string;
118
130
  repairedSessionsPath: string;
@@ -123,6 +135,7 @@ export interface SyncOptions {
123
135
  syncCodex: boolean;
124
136
  syncOpenCode: boolean;
125
137
  syncOpenClaw: boolean;
138
+ syncPi: boolean;
126
139
  rebuildSkillUsage: boolean;
127
140
  }
128
141
 
@@ -133,6 +146,7 @@ export interface SyncDeps {
133
146
  syncCodex?: (options: SyncOptions) => SyncStepResult;
134
147
  syncOpenCode?: (options: SyncOptions) => SyncStepResult;
135
148
  syncOpenClaw?: (options: SyncOptions) => SyncStepResult;
149
+ syncPi?: (options: SyncOptions) => SyncStepResult;
136
150
  rebuildSkillUsage?: (options: SyncOptions) => {
137
151
  repairedSessions: number;
138
152
  repairedRecords: number;
@@ -154,6 +168,7 @@ export function createDefaultSyncOptions(overrides: Partial<SyncOptions> = {}):
154
168
  codexHome: DEFAULT_CODEX_HOME,
155
169
  opencodeDataDir: DEFAULT_OPENCODE_DATA_DIR,
156
170
  openclawAgentsDir: OPENCLAW_AGENTS_DIR,
171
+ piSessionsDir: PI_SESSIONS_DIR,
157
172
  skillLogPath: SKILL_LOG,
158
173
  repairedSkillLogPath: REPAIRED_SKILL_LOG,
159
174
  repairedSessionsPath: REPAIRED_SKILL_SESSIONS_MARKER,
@@ -163,6 +178,7 @@ export function createDefaultSyncOptions(overrides: Partial<SyncOptions> = {}):
163
178
  syncCodex: true,
164
179
  syncOpenCode: true,
165
180
  syncOpenClaw: true,
181
+ syncPi: true,
166
182
  rebuildSkillUsage: true,
167
183
  ...overrides,
168
184
  };
@@ -356,6 +372,45 @@ function syncOpenClawSource(
356
372
  };
357
373
  }
358
374
 
375
+ function syncPiSource(options: SyncOptions, onProgress?: SyncProgressCallback): SyncStepResult {
376
+ if (!existsSync(options.piSessionsDir)) {
377
+ return { available: false, scanned: 0, synced: 0, skipped: 0 };
378
+ }
379
+
380
+ onProgress?.("scanning Pi sessions...");
381
+ const sinceTs = options.since ? options.since.getTime() : null;
382
+ const allSessions = findPiSessions(options.piSessionsDir, sinceTs);
383
+ const skillNames = findPiSkillNames();
384
+ const alreadyIngested = options.force ? new Set<string>() : loadMarker(PI_INGEST_MARKER);
385
+ const pending = allSessions.filter((session) => !alreadyIngested.has(session.sessionId));
386
+ onProgress?.(`found ${allSessions.length} sessions, ${pending.length} pending`);
387
+ const newIngested = new Set<string>();
388
+ let synced = 0;
389
+ let skipped = 0;
390
+
391
+ for (const sessionFile of pending) {
392
+ const session = parsePiSession(sessionFile.filePath, skillNames);
393
+ if (!session.session_id || !session.timestamp) {
394
+ skipped += 1;
395
+ continue;
396
+ }
397
+ writePiSession(session, options.dryRun);
398
+ newIngested.add(sessionFile.sessionId);
399
+ synced += 1;
400
+ }
401
+
402
+ if (!options.dryRun && newIngested.size > 0) {
403
+ saveMarker(PI_INGEST_MARKER, new Set([...alreadyIngested, ...newIngested]));
404
+ }
405
+
406
+ return {
407
+ available: true,
408
+ scanned: allSessions.length,
409
+ synced,
410
+ skipped,
411
+ };
412
+ }
413
+
359
414
  function rebuildSkillUsageOverlay(
360
415
  options: SyncOptions,
361
416
  onProgress?: SyncProgressCallback,
@@ -445,6 +500,7 @@ export function syncSources(
445
500
  const runCodex = deps.syncCodex;
446
501
  const runOpenCode = deps.syncOpenCode;
447
502
  const runOpenClaw = deps.syncOpenClaw;
503
+ const runPi = deps.syncPi;
448
504
  const runRepair = deps.rebuildSkillUsage;
449
505
  const runCreatorContributions = deps.stageCreatorContributions;
450
506
  const db = getDb();
@@ -485,6 +541,10 @@ export function syncSources(
485
541
  )
486
542
  : disabledStep;
487
543
 
544
+ const pi = options.syncPi
545
+ ? timePhase("pi", () => (runPi ? runPi(options) : syncPiSource(options, onProgress)), timings)
546
+ : disabledStep;
547
+
488
548
  const repair = options.rebuildSkillUsage
489
549
  ? timePhase(
490
550
  "repair",
@@ -512,10 +572,10 @@ export function syncSources(
512
572
 
513
573
  const totalElapsed = Math.round(performance.now() - totalStart);
514
574
 
515
- return {
575
+ const syncResult: SyncResult = {
516
576
  since: options.since ? options.since.toISOString() : null,
517
577
  dry_run: options.dryRun,
518
- sources: { claude, codex, opencode, openclaw },
578
+ sources: { claude, codex, opencode, openclaw, pi },
519
579
  repair: {
520
580
  ran: options.rebuildSkillUsage,
521
581
  repaired_sessions: repair.repairedSessions,
@@ -526,6 +586,8 @@ export function syncSources(
526
586
  timings,
527
587
  total_elapsed_ms: totalElapsed,
528
588
  };
589
+
590
+ return syncResult;
529
591
  }
530
592
 
531
593
  function formatMs(ms: number): string {
@@ -549,6 +611,7 @@ export async function cliMain(): Promise<void> {
549
611
  "codex-home": { type: "string", default: DEFAULT_CODEX_HOME },
550
612
  "opencode-data-dir": { type: "string", default: DEFAULT_OPENCODE_DATA_DIR },
551
613
  "openclaw-agents-dir": { type: "string", default: OPENCLAW_AGENTS_DIR },
614
+ "pi-sessions-dir": { type: "string", default: PI_SESSIONS_DIR },
552
615
  "skill-log": { type: "string", default: SKILL_LOG },
553
616
  "repaired-skill-log": { type: "string", default: REPAIRED_SKILL_LOG },
554
617
  "repaired-sessions-marker": { type: "string", default: REPAIRED_SKILL_SESSIONS_MARKER },
@@ -559,6 +622,7 @@ export async function cliMain(): Promise<void> {
559
622
  "no-codex": { type: "boolean", default: false },
560
623
  "no-opencode": { type: "boolean", default: false },
561
624
  "no-openclaw": { type: "boolean", default: false },
625
+ "no-pi": { type: "boolean", default: false },
562
626
  "no-repair": { type: "boolean", default: false },
563
627
  json: { type: "boolean", default: false },
564
628
  help: { type: "boolean", short: "h", default: false },
@@ -577,6 +641,7 @@ Options:
577
641
  --codex-home <dir> Codex home directory (default: ~/.codex)
578
642
  --opencode-data-dir <dir> OpenCode data directory
579
643
  --openclaw-agents-dir <dir> OpenClaw agents directory
644
+ --pi-sessions-dir <dir> Pi sessions directory
580
645
  --skill-log <path> Raw skill usage log path
581
646
  --repaired-skill-log <path> Repaired overlay log path
582
647
  --repaired-sessions-marker <p> Repaired session marker path
@@ -587,6 +652,7 @@ Options:
587
652
  --no-codex Skip Codex rollout ingest
588
653
  --no-opencode Skip OpenCode ingest
589
654
  --no-openclaw Skip OpenClaw ingest
655
+ --no-pi Skip Pi ingest
590
656
  --no-repair Skip rebuilt skill-usage overlay
591
657
  --json Output raw JSON instead of human-readable summary
592
658
  -h, --help Show this help`);
@@ -622,27 +688,64 @@ Options:
622
688
  process.stderr.write(`selftune sync${flags.length ? ` ${flags.join(" ")}` : ""}\n`);
623
689
  }
624
690
 
625
- const result = syncSources(
626
- createDefaultSyncOptions({
627
- projectsDir: values["projects-dir"] ?? CLAUDE_CODE_PROJECTS_DIR,
628
- codexHome: values["codex-home"] ?? DEFAULT_CODEX_HOME,
629
- opencodeDataDir: values["opencode-data-dir"] ?? DEFAULT_OPENCODE_DATA_DIR,
630
- openclawAgentsDir: values["openclaw-agents-dir"] ?? OPENCLAW_AGENTS_DIR,
631
- skillLogPath: values["skill-log"] ?? SKILL_LOG,
632
- repairedSkillLogPath: values["repaired-skill-log"] ?? REPAIRED_SKILL_LOG,
633
- repairedSessionsPath: values["repaired-sessions-marker"] ?? REPAIRED_SKILL_SESSIONS_MARKER,
634
- since,
635
- dryRun: values["dry-run"] ?? false,
636
- force: values.force ?? false,
637
- syncClaude: !(values["no-claude"] ?? false),
638
- syncCodex: !(values["no-codex"] ?? false),
639
- syncOpenCode: !(values["no-opencode"] ?? false),
640
- syncOpenClaw: !(values["no-openclaw"] ?? false),
641
- rebuildSkillUsage: !(values["no-repair"] ?? false),
642
- }),
643
- {},
644
- onProgress,
645
- );
691
+ const syncStartedAt = new Date();
692
+ const syncStart = performance.now();
693
+ let result: SyncResult;
694
+ try {
695
+ result = syncSources(
696
+ createDefaultSyncOptions({
697
+ projectsDir: values["projects-dir"] ?? CLAUDE_CODE_PROJECTS_DIR,
698
+ codexHome: values["codex-home"] ?? DEFAULT_CODEX_HOME,
699
+ opencodeDataDir: values["opencode-data-dir"] ?? DEFAULT_OPENCODE_DATA_DIR,
700
+ openclawAgentsDir: values["openclaw-agents-dir"] ?? OPENCLAW_AGENTS_DIR,
701
+ piSessionsDir: values["pi-sessions-dir"] ?? PI_SESSIONS_DIR,
702
+ skillLogPath: values["skill-log"] ?? SKILL_LOG,
703
+ repairedSkillLogPath: values["repaired-skill-log"] ?? REPAIRED_SKILL_LOG,
704
+ repairedSessionsPath: values["repaired-sessions-marker"] ?? REPAIRED_SKILL_SESSIONS_MARKER,
705
+ since,
706
+ dryRun: values["dry-run"] ?? false,
707
+ force: values.force ?? false,
708
+ syncClaude: !(values["no-claude"] ?? false),
709
+ syncCodex: !(values["no-codex"] ?? false),
710
+ syncOpenCode: !(values["no-opencode"] ?? false),
711
+ syncOpenClaw: !(values["no-openclaw"] ?? false),
712
+ syncPi: !(values["no-pi"] ?? false),
713
+ rebuildSkillUsage: !(values["no-repair"] ?? false),
714
+ }),
715
+ {},
716
+ onProgress,
717
+ );
718
+ } catch (err) {
719
+ const syncElapsed = Math.round(performance.now() - syncStart);
720
+ const message = err instanceof Error ? err.message : String(err);
721
+ writeCronRunToDb(getDb(), {
722
+ jobName: "sync",
723
+ startedAt: syncStartedAt.toISOString(),
724
+ elapsedMs: syncElapsed,
725
+ status: "error",
726
+ error: message,
727
+ });
728
+ throw err;
729
+ }
730
+
731
+ // Log successful sync run to unified cron_runs timeline
732
+ const syncElapsed = Math.round(performance.now() - syncStart);
733
+ const s = result.sources;
734
+ writeCronRunToDb(getDb(), {
735
+ jobName: "sync",
736
+ startedAt: syncStartedAt.toISOString(),
737
+ elapsedMs: syncElapsed,
738
+ status: "success",
739
+ metrics: {
740
+ total_synced:
741
+ s.claude.synced + s.codex.synced + s.opencode.synced + s.openclaw.synced + s.pi.synced,
742
+ claude_synced: s.claude.synced,
743
+ codex_synced: s.codex.synced,
744
+ opencode_synced: s.opencode.synced,
745
+ openclaw_synced: s.openclaw.synced,
746
+ pi_synced: s.pi.synced,
747
+ },
748
+ });
646
749
 
647
750
  if (jsonOutput) {
648
751
  console.log(JSON.stringify(result, null, 2));
@@ -662,6 +765,7 @@ Options:
662
765
  process.stderr.write(
663
766
  `${formatStepLine("OpenClaw", result.sources.openclaw, timingMap.get("openclaw"))}\n`,
664
767
  );
768
+ process.stderr.write(`${formatStepLine("Pi", result.sources.pi, timingMap.get("pi"))}\n`);
665
769
 
666
770
  if (result.repair.ran) {
667
771
  const repairTiming = timingMap.get("repair");