selftune 0.2.23 → 0.2.25

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 (219) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +93 -15
  3. package/apps/local-dashboard/dist/assets/index-DgY2KGP-.css +1 -0
  4. package/apps/local-dashboard/dist/assets/index-Dhgv5BQO.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/alpha-upload/build-payloads.ts +3 -3
  12. package/cli/selftune/alpha-upload/stage-canonical.ts +17 -11
  13. package/cli/selftune/auto-update.ts +200 -8
  14. package/cli/selftune/canonical-export.ts +55 -25
  15. package/cli/selftune/command-surface.ts +397 -0
  16. package/cli/selftune/contribute/contribute.ts +64 -13
  17. package/cli/selftune/contribution-config.ts +57 -3
  18. package/cli/selftune/contribution-preferences.ts +117 -0
  19. package/cli/selftune/contribution-signals.ts +8 -4
  20. package/cli/selftune/contribution-staging.ts +13 -2
  21. package/cli/selftune/contributions.ts +55 -121
  22. package/cli/selftune/creator-contributions.ts +29 -10
  23. package/cli/selftune/cron/setup.ts +7 -3
  24. package/cli/selftune/dashboard-contract.ts +73 -0
  25. package/cli/selftune/dashboard-server.ts +168 -17
  26. package/cli/selftune/dashboard.ts +350 -17
  27. package/cli/selftune/eval/baseline.ts +21 -5
  28. package/cli/selftune/eval/execution-eval.ts +170 -0
  29. package/cli/selftune/eval/family-overlap.ts +2 -2
  30. package/cli/selftune/eval/hooks-to-evals.ts +228 -82
  31. package/cli/selftune/eval/import-skillsbench.ts +2 -2
  32. package/cli/selftune/eval/invocation-classifier.ts +56 -0
  33. package/cli/selftune/eval/synthetic-evals.ts +5 -3
  34. package/cli/selftune/eval/unit-test-cli.ts +7 -4
  35. package/cli/selftune/evolution/apply-proposal.ts +295 -0
  36. package/cli/selftune/evolution/engines/replay-engine.ts +79 -57
  37. package/cli/selftune/evolution/evolve-body.ts +100 -39
  38. package/cli/selftune/evolution/evolve.ts +244 -52
  39. package/cli/selftune/evolution/rollback.ts +0 -1
  40. package/cli/selftune/evolution/validate-body.ts +68 -42
  41. package/cli/selftune/evolution/validate-host-replay.ts +510 -60
  42. package/cli/selftune/evolution/validate-proposal.ts +11 -150
  43. package/cli/selftune/evolution/validate-routing.ts +43 -41
  44. package/cli/selftune/evolution/validation-contract.ts +91 -0
  45. package/cli/selftune/grading/auto-grade.ts +11 -7
  46. package/cli/selftune/grading/grade-session.ts +10 -16
  47. package/cli/selftune/index.ts +35 -10
  48. package/cli/selftune/ingestors/claude-replay.ts +15 -10
  49. package/cli/selftune/ingestors/codex-wrapper.ts +3 -3
  50. package/cli/selftune/ingestors/opencode-ingest.ts +2 -2
  51. package/cli/selftune/ingestors/pi-ingest.ts +3 -2
  52. package/cli/selftune/init.ts +27 -3
  53. package/cli/selftune/localdb/direct-write.ts +35 -1
  54. package/cli/selftune/localdb/queries/cron.ts +34 -0
  55. package/cli/selftune/localdb/queries/dashboard.ts +834 -0
  56. package/cli/selftune/localdb/queries/evolution.ts +158 -0
  57. package/cli/selftune/localdb/queries/execution.ts +133 -0
  58. package/cli/selftune/localdb/queries/json.ts +18 -0
  59. package/cli/selftune/localdb/queries/monitoring.ts +263 -0
  60. package/cli/selftune/localdb/queries/raw.ts +95 -0
  61. package/cli/selftune/localdb/queries/staging.ts +270 -0
  62. package/cli/selftune/localdb/queries/trust.ts +392 -0
  63. package/cli/selftune/localdb/queries.ts +60 -2288
  64. package/cli/selftune/localdb/schema.ts +21 -0
  65. package/cli/selftune/monitoring/watch.ts +96 -29
  66. package/cli/selftune/normalization.ts +3 -0
  67. package/cli/selftune/observability.ts +4 -2
  68. package/cli/selftune/orchestrate/cli.ts +161 -0
  69. package/cli/selftune/orchestrate/execute.ts +295 -0
  70. package/cli/selftune/orchestrate/finalize.ts +157 -0
  71. package/cli/selftune/orchestrate/locks.ts +40 -0
  72. package/cli/selftune/orchestrate/plan.ts +131 -0
  73. package/cli/selftune/orchestrate/post-run.ts +59 -0
  74. package/cli/selftune/orchestrate/prepare.ts +334 -0
  75. package/cli/selftune/orchestrate/report.ts +182 -0
  76. package/cli/selftune/orchestrate/runtime.ts +120 -0
  77. package/cli/selftune/orchestrate/signals.ts +48 -0
  78. package/cli/selftune/orchestrate.ts +150 -1173
  79. package/cli/selftune/repair/skill-usage.ts +5 -2
  80. package/cli/selftune/routes/overview.ts +5 -2
  81. package/cli/selftune/routes/skill-report.ts +15 -2
  82. package/cli/selftune/schedule.ts +5 -5
  83. package/cli/selftune/status.ts +39 -2
  84. package/cli/selftune/testing-readiness.ts +597 -0
  85. package/cli/selftune/types.ts +44 -4
  86. package/cli/selftune/uninstall.ts +2 -1
  87. package/cli/selftune/utils/canonical-log.ts +1 -9
  88. package/cli/selftune/utils/cli-error.ts +9 -0
  89. package/cli/selftune/utils/llm-call.ts +126 -6
  90. package/cli/selftune/utils/skill-discovery.ts +2 -0
  91. package/cli/selftune/workflows/proposals.ts +184 -0
  92. package/cli/selftune/workflows/skill-scaffold.ts +241 -0
  93. package/cli/selftune/workflows/workflows.ts +100 -26
  94. package/node_modules/@selftune/telemetry-contract/fixtures/complete-push.ts +1 -1
  95. package/node_modules/@selftune/telemetry-contract/fixtures/evidence-only-push.ts +1 -1
  96. package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
  97. package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +1 -1
  98. package/node_modules/@selftune/telemetry-contract/src/schemas.ts +41 -1
  99. package/node_modules/@selftune/telemetry-contract/src/types.ts +103 -2
  100. package/package.json +25 -9
  101. package/packages/dashboard-core/AGENTS.md +18 -0
  102. package/packages/dashboard-core/README.md +30 -0
  103. package/packages/dashboard-core/index.ts +3 -0
  104. package/packages/dashboard-core/package.json +39 -0
  105. package/packages/dashboard-core/src/chrome/DashboardChrome.tsx +74 -0
  106. package/packages/dashboard-core/src/chrome/DashboardHeader.tsx +200 -0
  107. package/packages/dashboard-core/src/chrome/DashboardSidebar.tsx +219 -0
  108. package/packages/dashboard-core/src/chrome/RuntimeBadge.tsx +46 -0
  109. package/packages/dashboard-core/src/chrome/index.ts +14 -0
  110. package/packages/dashboard-core/src/chrome/types.ts +81 -0
  111. package/packages/dashboard-core/src/chrome/utils.ts +23 -0
  112. package/packages/dashboard-core/src/gates/FeatureGate.tsx +11 -0
  113. package/packages/dashboard-core/src/gates/LockedRoute.tsx +29 -0
  114. package/packages/dashboard-core/src/gates/UpgradeCard.tsx +89 -0
  115. package/packages/dashboard-core/src/gates/index.ts +3 -0
  116. package/packages/dashboard-core/src/host/DashboardHostProvider.tsx +62 -0
  117. package/packages/dashboard-core/src/host/adapter.ts +47 -0
  118. package/packages/dashboard-core/src/host/capabilities.ts +55 -0
  119. package/packages/dashboard-core/src/host/index.ts +3 -0
  120. package/packages/dashboard-core/src/models/analytics.ts +39 -0
  121. package/packages/dashboard-core/src/models/index.ts +4 -0
  122. package/packages/dashboard-core/src/models/overview.ts +98 -0
  123. package/packages/dashboard-core/src/models/runtime.ts +7 -0
  124. package/packages/dashboard-core/src/models/skills.ts +34 -0
  125. package/packages/dashboard-core/src/routes/index.ts +2 -0
  126. package/packages/dashboard-core/src/routes/manifest.test.ts +70 -0
  127. package/packages/dashboard-core/src/routes/manifest.ts +451 -0
  128. package/packages/dashboard-core/src/routes/types.ts +39 -0
  129. package/packages/dashboard-core/src/screens/analytics/AnalyticsScreen.tsx +278 -0
  130. package/packages/dashboard-core/src/screens/analytics/index.ts +1 -0
  131. package/packages/dashboard-core/src/screens/index.ts +37 -0
  132. package/packages/dashboard-core/src/screens/overview/OverviewComparisonSurface.test.ts +101 -0
  133. package/packages/dashboard-core/src/screens/overview/OverviewComparisonSurface.tsx +393 -0
  134. package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.test.tsx +113 -0
  135. package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.tsx +72 -0
  136. package/packages/dashboard-core/src/screens/overview/OverviewCoreSurface.tsx +71 -0
  137. package/packages/dashboard-core/src/screens/overview/OverviewOnboardingBanner.tsx +90 -0
  138. package/packages/dashboard-core/src/screens/overview/OverviewRunSummary.tsx +40 -0
  139. package/packages/dashboard-core/src/screens/overview/index.ts +16 -0
  140. package/packages/dashboard-core/src/screens/overview/types.ts +13 -0
  141. package/packages/dashboard-core/src/screens/skill-report/SkillReportDailyBreakdownSection.tsx +99 -0
  142. package/packages/dashboard-core/src/screens/skill-report/SkillReportDataQualityTabContent.tsx +35 -0
  143. package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceRail.tsx +71 -0
  144. package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceSection.tsx +63 -0
  145. package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceTabContent.tsx +25 -0
  146. package/packages/dashboard-core/src/screens/skill-report/SkillReportInvocationsSection.tsx +24 -0
  147. package/packages/dashboard-core/src/screens/skill-report/SkillReportMissedQueriesSection.tsx +79 -0
  148. package/packages/dashboard-core/src/screens/skill-report/SkillReportScaffold.tsx +150 -0
  149. package/packages/dashboard-core/src/screens/skill-report/SkillReportSections.test.tsx +224 -0
  150. package/packages/dashboard-core/src/screens/skill-report/SkillReportTabs.test.tsx +76 -0
  151. package/packages/dashboard-core/src/screens/skill-report/SkillReportTabs.tsx +88 -0
  152. package/packages/dashboard-core/src/screens/skill-report/SkillReportTrendSection.tsx +33 -0
  153. package/packages/dashboard-core/src/screens/skill-report/SkillReportTrustBadge.tsx +67 -0
  154. package/packages/dashboard-core/src/screens/skill-report/index.ts +45 -0
  155. package/packages/dashboard-core/src/screens/skills/SkillsLibraryScreen.tsx +162 -0
  156. package/packages/dashboard-core/src/screens/skills/index.ts +6 -0
  157. package/packages/telemetry-contract/fixtures/complete-push.ts +1 -1
  158. package/packages/telemetry-contract/fixtures/evidence-only-push.ts +1 -1
  159. package/packages/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
  160. package/packages/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +1 -1
  161. package/packages/telemetry-contract/src/schemas.ts +41 -1
  162. package/packages/telemetry-contract/src/types.ts +103 -2
  163. package/packages/ui/src/components/EvidenceViewer.tsx +80 -25
  164. package/packages/ui/src/components/OverviewPanels.tsx +67 -26
  165. package/packages/ui/src/primitives/tabs.tsx +7 -6
  166. package/packages/ui/src/types.ts +10 -0
  167. package/skill/SKILL.md +130 -332
  168. package/skill/agents/diagnosis-analyst.md +3 -3
  169. package/skill/agents/evolution-reviewer.md +3 -3
  170. package/skill/agents/integration-guide.md +3 -3
  171. package/skill/agents/pattern-analyst.md +2 -2
  172. package/skill/references/cli-quick-reference.md +89 -0
  173. package/skill/references/creator-playbook.md +131 -0
  174. package/skill/references/examples.md +48 -0
  175. package/skill/references/troubleshooting.md +47 -0
  176. package/skill/references/version-history.md +1 -1
  177. package/skill/selftune.contribute.json +11 -0
  178. package/skill/{Workflows → workflows}/Baseline.md +20 -1
  179. package/skill/{Workflows → workflows}/Contribute.md +23 -10
  180. package/skill/{Workflows → workflows}/Contributions.md +13 -5
  181. package/skill/workflows/CreateTestDeploy.md +170 -0
  182. package/skill/{Workflows → workflows}/CreatorContributions.md +18 -6
  183. package/skill/{Workflows → workflows}/Cron.md +1 -1
  184. package/skill/{Workflows → workflows}/Dashboard.md +20 -0
  185. package/skill/{Workflows → workflows}/Doctor.md +1 -1
  186. package/skill/{Workflows → workflows}/Evals.md +67 -2
  187. package/skill/{Workflows → workflows}/Evolve.md +119 -30
  188. package/skill/{Workflows → workflows}/EvolveBody.md +41 -1
  189. package/skill/{Workflows → workflows}/Grade.md +1 -1
  190. package/skill/{Workflows → workflows}/Initialize.md +8 -4
  191. package/skill/{Workflows → workflows}/Orchestrate.md +13 -3
  192. package/skill/{Workflows → workflows}/Schedule.md +3 -3
  193. package/skill/workflows/SignalsDashboard.md +87 -0
  194. package/skill/{Workflows → workflows}/UnitTest.md +19 -0
  195. package/skill/{Workflows → workflows}/Watch.md +42 -2
  196. package/skill/{Workflows → workflows}/Workflows.md +39 -2
  197. package/apps/local-dashboard/dist/assets/index-CwOtTrUS.css +0 -1
  198. package/apps/local-dashboard/dist/assets/index-f1HQpbeH.js +0 -59
  199. package/apps/local-dashboard/dist/assets/vendor-react-CKkiCskZ.js +0 -11
  200. package/apps/local-dashboard/dist/assets/vendor-ui-jVSaIZey.js +0 -12
  201. /package/skill/{Workflows → workflows}/AlphaUpload.md +0 -0
  202. /package/skill/{Workflows → workflows}/AutoActivation.md +0 -0
  203. /package/skill/{Workflows → workflows}/Badge.md +0 -0
  204. /package/skill/{Workflows → workflows}/Composability.md +0 -0
  205. /package/skill/{Workflows → workflows}/EvolutionMemory.md +0 -0
  206. /package/skill/{Workflows → workflows}/ExportCanonical.md +0 -0
  207. /package/skill/{Workflows → workflows}/Hook.md +0 -0
  208. /package/skill/{Workflows → workflows}/ImportSkillsBench.md +0 -0
  209. /package/skill/{Workflows → workflows}/Ingest.md +0 -0
  210. /package/skill/{Workflows → workflows}/PlatformHooks.md +0 -0
  211. /package/skill/{Workflows → workflows}/Quickstart.md +0 -0
  212. /package/skill/{Workflows → workflows}/Recover.md +0 -0
  213. /package/skill/{Workflows → workflows}/Registry.md +0 -0
  214. /package/skill/{Workflows → workflows}/RepairSkillUsage.md +0 -0
  215. /package/skill/{Workflows → workflows}/Replay.md +0 -0
  216. /package/skill/{Workflows → workflows}/Rollback.md +0 -0
  217. /package/skill/{Workflows → workflows}/Sync.md +0 -0
  218. /package/skill/{Workflows → workflows}/Telemetry.md +0 -0
  219. /package/skill/{Workflows → workflows}/Uninstall.md +0 -0
@@ -347,13 +347,15 @@ export function cliMain(): void {
347
347
  );
348
348
  }
349
349
 
350
- const projectsDir = values["projects-dir"] ?? CLAUDE_CODE_PROJECTS_DIR;
350
+ const projectsDir =
351
+ typeof values["projects-dir"] === "string" ? values["projects-dir"] : CLAUDE_CODE_PROJECTS_DIR;
351
352
  let since: Date | undefined;
352
- if (values.since) {
353
- since = new Date(values.since);
353
+ const sinceValue = typeof values.since === "string" ? values.since : undefined;
354
+ if (sinceValue) {
355
+ since = new Date(sinceValue);
354
356
  if (Number.isNaN(since.getTime())) {
355
357
  throw new CLIError(
356
- `Invalid --since date: "${values.since}"`,
358
+ `Invalid --since date: "${sinceValue}"`,
357
359
  "INVALID_FLAG",
358
360
  "selftune ingest claude --since 2026-01-01",
359
361
  );
@@ -376,32 +378,35 @@ export function cliMain(): void {
376
378
  );
377
379
 
378
380
  if (since) {
379
- console.log(` Filtering to sessions from ${values.since} onward.`);
381
+ console.log(` Filtering to sessions from ${sinceValue} onward.`);
380
382
  }
381
383
 
382
384
  let ingestedCount = 0;
383
385
  let skippedCount = 0;
384
386
 
387
+ const dryRun = values["dry-run"] === true;
388
+ const verbose = values.verbose === true;
389
+
385
390
  for (const transcriptFile of pending) {
386
391
  const session = parseSession(transcriptFile);
387
392
  if (session === null) {
388
- if (values.verbose) {
393
+ if (verbose) {
389
394
  console.log(` SKIP (empty/no queries): ${basename(transcriptFile)}`);
390
395
  }
391
396
  skippedCount += 1;
392
397
  continue;
393
398
  }
394
399
 
395
- if (values.verbose || values["dry-run"]) {
396
- console.log(` ${values["dry-run"] ? "[DRY] " : ""}Ingesting: ${basename(transcriptFile)}`);
400
+ if (verbose || dryRun) {
401
+ console.log(` ${dryRun ? "[DRY] " : ""}Ingesting: ${basename(transcriptFile)}`);
397
402
  }
398
403
 
399
- writeSession(session, values["dry-run"]);
404
+ writeSession(session, dryRun);
400
405
  newIngested.add(transcriptFile);
401
406
  ingestedCount += 1;
402
407
  }
403
408
 
404
- if (!values["dry-run"]) {
409
+ if (!dryRun) {
405
410
  saveMarker(CLAUDE_CODE_MARKER, new Set([...alreadyIngested, ...newIngested]));
406
411
  }
407
412
 
@@ -87,7 +87,7 @@ export function extractPromptFromArgs(args: string[]): string {
87
87
  }
88
88
 
89
89
  export interface ParsedCodexStream {
90
- thread_id: string;
90
+ thread_id?: string;
91
91
  tool_calls: Record<string, number>;
92
92
  total_tool_calls: number;
93
93
  bash_commands: string[];
@@ -96,7 +96,7 @@ export interface ParsedCodexStream {
96
96
  errors_encountered: number;
97
97
  input_tokens: number;
98
98
  output_tokens: number;
99
- agent_summary: string;
99
+ agent_summary?: string;
100
100
  transcript_chars: number;
101
101
  }
102
102
 
@@ -475,7 +475,7 @@ export async function cliMain(): Promise<void> {
475
475
  // Parse and log
476
476
  const metrics = parseJsonlStream(collectedLines, skillNames);
477
477
  const actualThreadId = metrics.thread_id;
478
- const sessionId = actualThreadId !== "unknown" ? actualThreadId : threadId;
478
+ const sessionId = actualThreadId && actualThreadId !== "unknown" ? actualThreadId : threadId;
479
479
 
480
480
  const { thread_id: _, ...metricsWithoutThread } = metrics;
481
481
 
@@ -210,7 +210,7 @@ export function readSessionsFromSqlite(
210
210
 
211
211
  // Get sessions
212
212
  let whereClause = "";
213
- const queryParams: unknown[] = [];
213
+ const queryParams: number[] = [];
214
214
  if (sinceTs) {
215
215
  whereClause = "WHERE created > ?";
216
216
  queryParams.push(Math.floor(sinceTs * 1000));
@@ -239,7 +239,7 @@ export function readSessionsFromSqlite(
239
239
  try {
240
240
  msgRows = db
241
241
  .query(`SELECT * FROM ${safeMessagesTable} WHERE session_id = ? ORDER BY created ASC`)
242
- .all(sessionRow.id) as Array<Record<string, unknown>>;
242
+ .all(String(sessionRow.id)) as Array<Record<string, unknown>>;
243
243
  } catch {
244
244
  continue;
245
245
  }
@@ -214,10 +214,11 @@ function linearizeTree(entries: PiEntry[]): PiEntry[] {
214
214
 
215
215
  // Pick the child with the latest timestamp
216
216
  let latest = kids[0];
217
- let latestTs = latest.timestamp ? new Date(latest.timestamp).getTime() : 0;
217
+ let latestTs = typeof latest.timestamp === "string" ? new Date(latest.timestamp).getTime() : 0;
218
218
 
219
219
  for (let i = 1; i < kids.length; i++) {
220
- const ts = kids[i].timestamp ? new Date(kids[i].timestamp).getTime() : 0;
220
+ const childTimestamp = kids[i].timestamp;
221
+ const ts = typeof childTimestamp === "string" ? new Date(childTimestamp).getTime() : 0;
221
222
  if (ts > latestTs) {
222
223
  latest = kids[i];
223
224
  latestTs = ts;
@@ -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";
@@ -1000,19 +1010,33 @@ export async function cliMain(): Promise<void> {
1000
1010
  try {
1001
1011
  const { syncSources } = await import("./sync.js");
1002
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,
1003
1024
  syncClaude: true,
1004
1025
  syncCodex: true,
1005
1026
  syncOpenCode: true,
1006
1027
  syncOpenClaw: true,
1028
+ syncPi: true,
1007
1029
  rebuildSkillUsage: true,
1008
1030
  dryRun: false,
1031
+ force: false,
1009
1032
  });
1010
1033
 
1011
1034
  const totalSynced =
1012
1035
  (syncResult.sources.claude?.synced ?? 0) +
1013
1036
  (syncResult.sources.codex?.synced ?? 0) +
1014
1037
  (syncResult.sources.opencode?.synced ?? 0) +
1015
- (syncResult.sources.openclaw?.synced ?? 0);
1038
+ (syncResult.sources.openclaw?.synced ?? 0) +
1039
+ (syncResult.sources.pi?.synced ?? 0);
1016
1040
 
1017
1041
  console.log(
1018
1042
  JSON.stringify({
@@ -1125,7 +1149,7 @@ export function checkAlphaReadiness(configPath: string): {
1125
1149
 
1126
1150
  // Guard: only run when invoked directly
1127
1151
  const isMain =
1128
- (import.meta as Record<string, unknown>).main === true ||
1152
+ (import.meta as unknown as Record<string, unknown>).main === true ||
1129
1153
  process.argv[1] === fileURLToPath(import.meta.url);
1130
1154
 
1131
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,40 @@ 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
+
503
537
  // -- Cron run audit writer -----------------------------------------------------
504
538
 
505
539
  export function writeCronRunToDb(
@@ -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
+ }