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.
- package/CHANGELOG.md +6 -0
- package/README.md +95 -15
- package/apps/local-dashboard/dist/assets/index-DgY2KGP-.css +1 -0
- package/apps/local-dashboard/dist/assets/index-Dmx7LPVX.js +15 -0
- package/apps/local-dashboard/dist/assets/vendor-react-C5oyHiV1.js +11 -0
- package/apps/local-dashboard/dist/assets/{vendor-table-BIiI3YhS.js → vendor-table-Bc_bbKd8.js} +1 -1
- package/apps/local-dashboard/dist/assets/vendor-ui-B3BPIYy7.js +1 -0
- package/apps/local-dashboard/dist/index.html +5 -5
- package/cli/selftune/adapters/codex/install.ts +310 -78
- package/cli/selftune/adapters/opencode/install.ts +3 -4
- package/cli/selftune/adapters/pi/hook.ts +273 -0
- package/cli/selftune/adapters/pi/install.ts +207 -0
- package/cli/selftune/alpha-upload/build-payloads.ts +3 -3
- package/cli/selftune/alpha-upload/stage-canonical.ts +17 -11
- package/cli/selftune/auto-update.ts +200 -8
- package/cli/selftune/canonical-export.ts +55 -25
- package/cli/selftune/command-surface.ts +397 -0
- package/cli/selftune/constants.ts +10 -1
- package/cli/selftune/contribute/contribute.ts +64 -13
- package/cli/selftune/contribution-config.ts +57 -3
- package/cli/selftune/contribution-preferences.ts +117 -0
- package/cli/selftune/contribution-signals.ts +8 -4
- package/cli/selftune/contribution-staging.ts +13 -2
- package/cli/selftune/contributions.ts +55 -121
- package/cli/selftune/creator-contributions.ts +29 -10
- package/cli/selftune/cron/setup.ts +7 -3
- package/cli/selftune/dashboard-contract.ts +87 -0
- package/cli/selftune/dashboard-server.ts +168 -17
- package/cli/selftune/dashboard.ts +350 -17
- package/cli/selftune/eval/baseline.ts +21 -5
- package/cli/selftune/eval/execution-eval.ts +170 -0
- package/cli/selftune/eval/family-overlap.ts +2 -2
- package/cli/selftune/eval/hooks-to-evals.ts +228 -82
- package/cli/selftune/eval/import-skillsbench.ts +2 -2
- package/cli/selftune/eval/invocation-classifier.ts +56 -0
- package/cli/selftune/eval/synthetic-evals.ts +5 -3
- package/cli/selftune/eval/unit-test-cli.ts +7 -4
- package/cli/selftune/evolution/apply-proposal.ts +295 -0
- package/cli/selftune/evolution/engines/judge-engine.ts +96 -0
- package/cli/selftune/evolution/engines/replay-engine.ts +180 -0
- package/cli/selftune/evolution/evidence.ts +2 -6
- package/cli/selftune/evolution/evolve-body.ts +152 -38
- package/cli/selftune/evolution/evolve.ts +244 -52
- package/cli/selftune/evolution/rollback.ts +0 -1
- package/cli/selftune/evolution/validate-body.ts +111 -49
- package/cli/selftune/evolution/validate-host-replay.ts +510 -60
- package/cli/selftune/evolution/validate-proposal.ts +11 -150
- package/cli/selftune/evolution/validate-routing.ts +51 -108
- package/cli/selftune/evolution/validation-contract.ts +91 -0
- package/cli/selftune/grading/auto-grade.ts +11 -7
- package/cli/selftune/grading/grade-session.ts +10 -16
- package/cli/selftune/hooks/skill-eval.ts +2 -1
- package/cli/selftune/hooks-shared/types.ts +1 -0
- package/cli/selftune/index.ts +58 -15
- package/cli/selftune/ingestors/claude-replay.ts +15 -10
- package/cli/selftune/ingestors/codex-wrapper.ts +3 -3
- package/cli/selftune/ingestors/opencode-ingest.ts +2 -2
- package/cli/selftune/ingestors/pi-ingest.ts +727 -0
- package/cli/selftune/init.ts +38 -4
- package/cli/selftune/localdb/direct-write.ts +120 -1
- package/cli/selftune/localdb/materialize.ts +6 -7
- package/cli/selftune/localdb/queries/cron.ts +34 -0
- package/cli/selftune/localdb/queries/dashboard.ts +834 -0
- package/cli/selftune/localdb/queries/evolution.ts +158 -0
- package/cli/selftune/localdb/queries/execution.ts +133 -0
- package/cli/selftune/localdb/queries/json.ts +18 -0
- package/cli/selftune/localdb/queries/monitoring.ts +263 -0
- package/cli/selftune/localdb/queries/raw.ts +95 -0
- package/cli/selftune/localdb/queries/staging.ts +270 -0
- package/cli/selftune/localdb/queries/trust.ts +392 -0
- package/cli/selftune/localdb/queries.ts +60 -2162
- package/cli/selftune/localdb/schema.ts +59 -0
- package/cli/selftune/monitoring/watch.ts +96 -29
- package/cli/selftune/normalization.ts +3 -0
- package/cli/selftune/observability.ts +12 -3
- package/cli/selftune/orchestrate/cli.ts +161 -0
- package/cli/selftune/orchestrate/execute.ts +295 -0
- package/cli/selftune/orchestrate/finalize.ts +157 -0
- package/cli/selftune/orchestrate/locks.ts +40 -0
- package/cli/selftune/orchestrate/plan.ts +131 -0
- package/cli/selftune/orchestrate/post-run.ts +59 -0
- package/cli/selftune/orchestrate/prepare.ts +334 -0
- package/cli/selftune/orchestrate/report.ts +182 -0
- package/cli/selftune/orchestrate/runtime.ts +120 -0
- package/cli/selftune/orchestrate/signals.ts +48 -0
- package/cli/selftune/orchestrate.ts +162 -1142
- package/cli/selftune/registry/client.ts +74 -0
- package/cli/selftune/registry/history.ts +54 -0
- package/cli/selftune/registry/index.ts +90 -0
- package/cli/selftune/registry/install.ts +141 -0
- package/cli/selftune/registry/list.ts +44 -0
- package/cli/selftune/registry/push.ts +171 -0
- package/cli/selftune/registry/rollback.ts +49 -0
- package/cli/selftune/registry/status.ts +62 -0
- package/cli/selftune/registry/sync.ts +125 -0
- package/cli/selftune/repair/skill-usage.ts +9 -3
- package/cli/selftune/routes/overview.ts +5 -2
- package/cli/selftune/routes/skill-report.ts +15 -2
- package/cli/selftune/schedule.ts +5 -5
- package/cli/selftune/status.ts +70 -2
- package/cli/selftune/sync.ts +127 -23
- package/cli/selftune/testing-readiness.ts +597 -0
- package/cli/selftune/types.ts +46 -5
- package/cli/selftune/uninstall.ts +2 -1
- package/cli/selftune/utils/canonical-log.ts +1 -9
- package/cli/selftune/utils/cli-error.ts +9 -0
- package/cli/selftune/utils/jsonl.ts +1 -30
- package/cli/selftune/utils/llm-call.ts +126 -6
- package/cli/selftune/utils/skill-discovery.ts +24 -0
- package/cli/selftune/workflows/proposals.ts +184 -0
- package/cli/selftune/workflows/skill-scaffold.ts +241 -0
- package/cli/selftune/workflows/workflows.ts +100 -26
- package/node_modules/@selftune/telemetry-contract/fixtures/complete-push.ts +1 -1
- package/node_modules/@selftune/telemetry-contract/fixtures/evidence-only-push.ts +2 -2
- package/node_modules/@selftune/telemetry-contract/fixtures/golden.test.ts +0 -1
- package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
- package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +2 -2
- package/node_modules/@selftune/telemetry-contract/package.json +1 -1
- package/node_modules/@selftune/telemetry-contract/src/index.ts +1 -0
- package/node_modules/@selftune/telemetry-contract/src/schemas.ts +63 -5
- package/node_modules/@selftune/telemetry-contract/src/types.ts +97 -7
- package/node_modules/@selftune/telemetry-contract/tests/compatibility.test.ts +0 -1
- package/package.json +25 -9
- package/packages/dashboard-core/AGENTS.md +18 -0
- package/packages/dashboard-core/README.md +30 -0
- package/packages/dashboard-core/index.ts +3 -0
- package/packages/dashboard-core/package.json +39 -0
- package/packages/dashboard-core/src/chrome/DashboardChrome.tsx +74 -0
- package/packages/dashboard-core/src/chrome/DashboardHeader.tsx +200 -0
- package/packages/dashboard-core/src/chrome/DashboardSidebar.tsx +219 -0
- package/packages/dashboard-core/src/chrome/RuntimeBadge.tsx +46 -0
- package/packages/dashboard-core/src/chrome/index.ts +14 -0
- package/packages/dashboard-core/src/chrome/types.ts +81 -0
- package/packages/dashboard-core/src/chrome/utils.ts +23 -0
- package/packages/dashboard-core/src/gates/FeatureGate.tsx +11 -0
- package/packages/dashboard-core/src/gates/LockedRoute.tsx +29 -0
- package/packages/dashboard-core/src/gates/UpgradeCard.tsx +89 -0
- package/packages/dashboard-core/src/gates/index.ts +3 -0
- package/packages/dashboard-core/src/host/DashboardHostProvider.tsx +62 -0
- package/packages/dashboard-core/src/host/adapter.ts +47 -0
- package/packages/dashboard-core/src/host/capabilities.ts +55 -0
- package/packages/dashboard-core/src/host/index.ts +3 -0
- package/packages/dashboard-core/src/models/analytics.ts +39 -0
- package/packages/dashboard-core/src/models/index.ts +4 -0
- package/packages/dashboard-core/src/models/overview.ts +98 -0
- package/packages/dashboard-core/src/models/runtime.ts +7 -0
- package/packages/dashboard-core/src/models/skills.ts +34 -0
- package/packages/dashboard-core/src/routes/index.ts +2 -0
- package/packages/dashboard-core/src/routes/manifest.test.ts +70 -0
- package/packages/dashboard-core/src/routes/manifest.ts +451 -0
- package/packages/dashboard-core/src/routes/types.ts +39 -0
- package/packages/dashboard-core/src/screens/analytics/AnalyticsScreen.tsx +278 -0
- package/packages/dashboard-core/src/screens/analytics/index.ts +1 -0
- package/packages/dashboard-core/src/screens/index.ts +37 -0
- package/packages/dashboard-core/src/screens/overview/OverviewComparisonSurface.test.ts +101 -0
- package/packages/dashboard-core/src/screens/overview/OverviewComparisonSurface.tsx +393 -0
- package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.test.tsx +113 -0
- package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.tsx +72 -0
- package/packages/dashboard-core/src/screens/overview/OverviewCoreSurface.tsx +71 -0
- package/packages/dashboard-core/src/screens/overview/OverviewOnboardingBanner.tsx +90 -0
- package/packages/dashboard-core/src/screens/overview/OverviewRunSummary.tsx +40 -0
- package/packages/dashboard-core/src/screens/overview/index.ts +16 -0
- package/packages/dashboard-core/src/screens/overview/types.ts +13 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportDailyBreakdownSection.tsx +99 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportDataQualityTabContent.tsx +35 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceRail.tsx +71 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceSection.tsx +63 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportEvidenceTabContent.tsx +25 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportInvocationsSection.tsx +24 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportMissedQueriesSection.tsx +79 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportScaffold.tsx +150 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportSections.test.tsx +224 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportTabs.test.tsx +76 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportTabs.tsx +88 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportTrendSection.tsx +33 -0
- package/packages/dashboard-core/src/screens/skill-report/SkillReportTrustBadge.tsx +67 -0
- package/packages/dashboard-core/src/screens/skill-report/index.ts +45 -0
- package/packages/dashboard-core/src/screens/skills/SkillsLibraryScreen.tsx +162 -0
- package/packages/dashboard-core/src/screens/skills/index.ts +6 -0
- package/packages/telemetry-contract/fixtures/complete-push.ts +1 -1
- package/packages/telemetry-contract/fixtures/evidence-only-push.ts +2 -2
- package/packages/telemetry-contract/fixtures/golden.test.ts +0 -1
- package/packages/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
- package/packages/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +2 -2
- package/packages/telemetry-contract/package.json +1 -1
- package/packages/telemetry-contract/src/index.ts +1 -0
- package/packages/telemetry-contract/src/schemas.ts +63 -5
- package/packages/telemetry-contract/src/types.ts +97 -7
- package/packages/telemetry-contract/tests/compatibility.test.ts +0 -1
- package/packages/ui/AGENTS.md +16 -0
- package/packages/ui/README.md +1 -1
- package/packages/ui/package.json +1 -1
- package/packages/ui/src/components/ActivityTimeline.tsx +152 -168
- package/packages/ui/src/components/AnalyticsCharts.tsx +344 -0
- package/packages/ui/src/components/EvidenceViewer.tsx +229 -464
- package/packages/ui/src/components/EvolutionTimeline.tsx +34 -87
- package/packages/ui/src/components/InfoTip.tsx +1 -2
- package/packages/ui/src/components/InvocationsPanel.tsx +413 -0
- package/packages/ui/src/components/JobHistoryTimeline.tsx +156 -0
- package/packages/ui/src/components/OrchestrateRunsPanel.tsx +18 -36
- package/packages/ui/src/components/OverviewPanels.tsx +693 -0
- package/packages/ui/src/components/PipelineStatusBar.tsx +65 -0
- package/packages/ui/src/components/SkillReportGuide.tsx +215 -0
- package/packages/ui/src/components/SkillReportPanels.tsx +919 -0
- package/packages/ui/src/components/SkillsLibrary.tsx +437 -0
- package/packages/ui/src/components/index.ts +56 -1
- package/packages/ui/src/components/section-cards.tsx +18 -35
- package/packages/ui/src/components/skill-health-grid.tsx +47 -37
- package/packages/ui/src/lib/constants.tsx +0 -1
- package/packages/ui/src/primitives/card.tsx +1 -1
- package/packages/ui/src/primitives/checkbox.tsx +1 -1
- package/packages/ui/src/primitives/dropdown-menu.tsx +2 -2
- package/packages/ui/src/primitives/select.tsx +2 -2
- package/packages/ui/src/primitives/tabs.tsx +7 -6
- package/packages/ui/src/types.ts +182 -4
- package/skill/SKILL.md +130 -318
- package/skill/agents/diagnosis-analyst.md +3 -3
- package/skill/agents/evolution-reviewer.md +3 -3
- package/skill/agents/integration-guide.md +3 -3
- package/skill/agents/pattern-analyst.md +2 -2
- package/skill/references/cli-quick-reference.md +89 -0
- package/skill/references/creator-playbook.md +131 -0
- package/skill/references/examples.md +48 -0
- package/skill/references/troubleshooting.md +47 -0
- package/skill/references/version-history.md +1 -1
- package/skill/selftune.contribute.json +11 -0
- package/skill/{Workflows → workflows}/Baseline.md +20 -1
- package/skill/{Workflows → workflows}/Contribute.md +23 -10
- package/skill/{Workflows → workflows}/Contributions.md +13 -5
- package/skill/workflows/CreateTestDeploy.md +170 -0
- package/skill/{Workflows → workflows}/CreatorContributions.md +18 -6
- package/skill/{Workflows → workflows}/Cron.md +1 -1
- package/skill/{Workflows → workflows}/Dashboard.md +20 -0
- package/skill/{Workflows → workflows}/Doctor.md +1 -1
- package/skill/{Workflows → workflows}/Evals.md +67 -2
- package/skill/{Workflows → workflows}/Evolve.md +119 -30
- package/skill/{Workflows → workflows}/EvolveBody.md +41 -1
- package/skill/{Workflows → workflows}/Grade.md +1 -1
- package/skill/{Workflows → workflows}/Ingest.md +60 -2
- package/skill/{Workflows → workflows}/Initialize.md +16 -9
- package/skill/{Workflows → workflows}/Orchestrate.md +13 -3
- package/skill/{Workflows → workflows}/PlatformHooks.md +19 -3
- package/skill/workflows/Registry.md +99 -0
- package/skill/{Workflows → workflows}/Schedule.md +3 -3
- package/skill/workflows/SignalsDashboard.md +87 -0
- package/skill/{Workflows → workflows}/Sync.md +3 -1
- package/skill/{Workflows → workflows}/UnitTest.md +19 -0
- package/skill/{Workflows → workflows}/Watch.md +42 -2
- package/skill/{Workflows → workflows}/Workflows.md +39 -2
- package/apps/local-dashboard/dist/assets/index-D8O-RG1I.js +0 -60
- package/apps/local-dashboard/dist/assets/index-_EcLywDg.css +0 -1
- package/apps/local-dashboard/dist/assets/vendor-react-CKkiCskZ.js +0 -11
- package/apps/local-dashboard/dist/assets/vendor-ui-CGEmUayx.js +0 -12
- package/cli/selftune/utils/html.ts +0 -27
- package/packages/ui/src/components/RecentActivityFeed.tsx +0 -117
- /package/skill/{Workflows → workflows}/AlphaUpload.md +0 -0
- /package/skill/{Workflows → workflows}/AutoActivation.md +0 -0
- /package/skill/{Workflows → workflows}/Badge.md +0 -0
- /package/skill/{Workflows → workflows}/Composability.md +0 -0
- /package/skill/{Workflows → workflows}/EvolutionMemory.md +0 -0
- /package/skill/{Workflows → workflows}/ExportCanonical.md +0 -0
- /package/skill/{Workflows → workflows}/Hook.md +0 -0
- /package/skill/{Workflows → workflows}/ImportSkillsBench.md +0 -0
- /package/skill/{Workflows → workflows}/Quickstart.md +0 -0
- /package/skill/{Workflows → workflows}/Recover.md +0 -0
- /package/skill/{Workflows → workflows}/RepairSkillUsage.md +0 -0
- /package/skill/{Workflows → workflows}/Replay.md +0 -0
- /package/skill/{Workflows → workflows}/Rollback.md +0 -0
- /package/skill/{Workflows → workflows}/Telemetry.md +0 -0
- /package/skill/{Workflows → workflows}/Uninstall.md +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* selftune registry sync — Check for updates and pull latest versions.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { writeFile, readFile, mkdir, unlink } from "node:fs/promises";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
|
|
8
|
+
import { registryRequest } from "./client.js";
|
|
9
|
+
|
|
10
|
+
interface LocalState {
|
|
11
|
+
entryId: string;
|
|
12
|
+
name: string;
|
|
13
|
+
versionHash: string;
|
|
14
|
+
installPath: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getStatePath(): string {
|
|
18
|
+
return join(process.env.HOME || "~", ".selftune", "registry-state.json");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function loadState(): Promise<LocalState[]> {
|
|
22
|
+
try {
|
|
23
|
+
const raw = await readFile(getStatePath(), "utf-8");
|
|
24
|
+
return JSON.parse(raw);
|
|
25
|
+
} catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function saveState(state: LocalState[]): Promise<void> {
|
|
31
|
+
await mkdir(join(process.env.HOME || "~", ".selftune"), { recursive: true });
|
|
32
|
+
await writeFile(getStatePath(), JSON.stringify(state, null, 2));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function cliMain() {
|
|
36
|
+
const state = await loadState();
|
|
37
|
+
if (state.length === 0) {
|
|
38
|
+
console.log(
|
|
39
|
+
JSON.stringify({
|
|
40
|
+
message: "No registry installations found. Use 'selftune registry install <name>' first.",
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check for updates
|
|
47
|
+
const syncResult = await registryRequest<{
|
|
48
|
+
entries: Array<{
|
|
49
|
+
entry_id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
has_update: boolean;
|
|
52
|
+
latest_version: string;
|
|
53
|
+
latest_content_hash: string;
|
|
54
|
+
download_url?: string;
|
|
55
|
+
}>;
|
|
56
|
+
}>("POST", "/sync", {
|
|
57
|
+
body: {
|
|
58
|
+
installations: state.map((s) => ({
|
|
59
|
+
entry_id: s.entryId,
|
|
60
|
+
current_version_hash: s.versionHash,
|
|
61
|
+
})),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (!syncResult.success) {
|
|
66
|
+
console.error(JSON.stringify({ error: syncResult.error }));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const updates = syncResult.data?.entries?.filter((e) => e.has_update) || [];
|
|
71
|
+
if (updates.length === 0) {
|
|
72
|
+
console.log(JSON.stringify({ message: "All installations up to date", count: state.length }));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log(`Found ${updates.length} update(s)...`);
|
|
77
|
+
let synced = 0;
|
|
78
|
+
let failed = 0;
|
|
79
|
+
|
|
80
|
+
for (const update of updates) {
|
|
81
|
+
if (!update.download_url) {
|
|
82
|
+
failed++;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const localEntry = state.find((s) => s.entryId === update.entry_id);
|
|
87
|
+
if (!localEntry) {
|
|
88
|
+
failed++;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const response = await fetch(update.download_url, { signal: AbortSignal.timeout(60_000) });
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
failed++;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const archiveBuffer = Buffer.from(await response.arrayBuffer());
|
|
100
|
+
const archivePath = `/tmp/selftune-sync-${Date.now()}.tar.gz`;
|
|
101
|
+
await writeFile(archivePath, archiveBuffer);
|
|
102
|
+
|
|
103
|
+
// Extract to existing install path
|
|
104
|
+
const proc = Bun.spawn(["tar", "xzf", archivePath, "-C", localEntry.installPath], {
|
|
105
|
+
stdout: "ignore",
|
|
106
|
+
stderr: "pipe",
|
|
107
|
+
});
|
|
108
|
+
await proc.exited;
|
|
109
|
+
await unlink(archivePath).catch(() => {});
|
|
110
|
+
|
|
111
|
+
if (proc.exitCode === 0) {
|
|
112
|
+
localEntry.versionHash = update.latest_content_hash;
|
|
113
|
+
synced++;
|
|
114
|
+
console.log(` updated: ${update.name} -> v${update.latest_version}`);
|
|
115
|
+
} else {
|
|
116
|
+
failed++;
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
failed++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
await saveState(state);
|
|
124
|
+
console.log(JSON.stringify({ synced, failed, total: state.length }));
|
|
125
|
+
}
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
findInstalledSkillPath,
|
|
32
32
|
findRepositoryClaudeSkillDirs,
|
|
33
33
|
findRepositorySkillDirs,
|
|
34
|
+
isTestFixturePath,
|
|
34
35
|
} from "../utils/skill-discovery.js";
|
|
35
36
|
import { writeRepairedSkillUsageRecords } from "../utils/skill-log.js";
|
|
36
37
|
|
|
@@ -299,8 +300,11 @@ function extractSessionSkillUsage(
|
|
|
299
300
|
|
|
300
301
|
const msg = (entry.message as Record<string, unknown>) ?? entry;
|
|
301
302
|
const role = (msg.role as string) ?? (entry.role as string) ?? "";
|
|
302
|
-
const timestamp =
|
|
303
|
-
(entry.timestamp
|
|
303
|
+
const timestamp: string =
|
|
304
|
+
optionalString(entry.timestamp) ??
|
|
305
|
+
optionalString(msg.timestamp) ??
|
|
306
|
+
lastUserMessage?.timestamp ??
|
|
307
|
+
"";
|
|
304
308
|
sessionCwd =
|
|
305
309
|
optionalString(entry.cwd) ??
|
|
306
310
|
optionalString(msg.cwd) ??
|
|
@@ -380,7 +384,7 @@ function extractSessionSkillUsage(
|
|
|
380
384
|
|
|
381
385
|
if (toolName === "Read") {
|
|
382
386
|
const filePath = (input.file_path as string) ?? "";
|
|
383
|
-
if (filePath.endsWith("SKILL.md")) {
|
|
387
|
+
if (filePath.endsWith("SKILL.md") && !isTestFixturePath(filePath)) {
|
|
384
388
|
const inferredSkillName = basename(dirname(filePath)).trim();
|
|
385
389
|
if (inferredSkillName && !skillPathLookup.has(inferredSkillName)) {
|
|
386
390
|
skillPathLookup.set(inferredSkillName.toLowerCase(), filePath);
|
|
@@ -421,6 +425,8 @@ function extractSessionSkillUsage(
|
|
|
421
425
|
? { skillPath: knownSkillPath, resolutionSource: "raw_log" as const }
|
|
422
426
|
: resolveClaudeSkillPath(skillName, sessionCwd, homeDir, codexHome);
|
|
423
427
|
|
|
428
|
+
if (isTestFixturePath(skillPath)) continue;
|
|
429
|
+
|
|
424
430
|
const recordIndex =
|
|
425
431
|
repaired.push({
|
|
426
432
|
timestamp: timestamp || lastUserMessage.timestamp || fallbackTimestamp,
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
getSkillTrustSummaries,
|
|
25
25
|
getSkillsList,
|
|
26
26
|
} from "../localdb/queries.js";
|
|
27
|
+
import { buildCreatorTestingOverview, listSkillTestingReadiness } from "../testing-readiness.js";
|
|
27
28
|
import { buildTrustWatchlist } from "../trust-model.js";
|
|
28
29
|
import { loadWatchedSkills } from "../watchlist.js";
|
|
29
30
|
|
|
@@ -32,15 +33,16 @@ export function handleOverview(
|
|
|
32
33
|
version: string,
|
|
33
34
|
searchParams?: URLSearchParams,
|
|
34
35
|
): Response {
|
|
35
|
-
const skills = getSkillsList(db);
|
|
36
|
-
|
|
37
36
|
// -- Autonomy-first enrichment fields ----------------------------------------
|
|
38
37
|
const attentionQueue = getAttentionQueue(db);
|
|
39
38
|
const recentDecisions = getRecentDecisions(db);
|
|
40
39
|
const trustSummaries = getSkillTrustSummaries(db);
|
|
40
|
+
const testingReadiness = listSkillTestingReadiness(db);
|
|
41
|
+
const skills = getSkillsList(db, testingReadiness);
|
|
41
42
|
const pendingReviews = attentionQueue.filter((a) => a.category === "needs_review").length;
|
|
42
43
|
|
|
43
44
|
const trustWatchlist = buildTrustWatchlist(trustSummaries);
|
|
45
|
+
const creatorTesting = buildCreatorTestingOverview(testingReadiness);
|
|
44
46
|
const autonomyStatus = buildAutonomyStatus(
|
|
45
47
|
db,
|
|
46
48
|
attentionQueue,
|
|
@@ -55,6 +57,7 @@ export function handleOverview(
|
|
|
55
57
|
attention_queue: attentionQueue,
|
|
56
58
|
trust_watchlist: trustWatchlist,
|
|
57
59
|
recent_decisions: recentDecisions,
|
|
60
|
+
creator_testing: creatorTesting,
|
|
58
61
|
};
|
|
59
62
|
|
|
60
63
|
// -- Standard overview payload -----------------------------------------------
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getSkillReportPayload,
|
|
18
18
|
safeParseJson,
|
|
19
19
|
} from "../localdb/queries.js";
|
|
20
|
+
import { getSkillTestingReadiness } from "../testing-readiness.js";
|
|
20
21
|
|
|
21
22
|
export function handleSkillReport(
|
|
22
23
|
db: Database,
|
|
@@ -24,6 +25,7 @@ export function handleSkillReport(
|
|
|
24
25
|
searchParams?: URLSearchParams,
|
|
25
26
|
): Response {
|
|
26
27
|
const report = getSkillReportPayload(db, skillName);
|
|
28
|
+
const testing_readiness = getSkillTestingReadiness(db, skillName);
|
|
27
29
|
|
|
28
30
|
// 1. Evolution audit with eval_snapshot
|
|
29
31
|
const evolution = db
|
|
@@ -178,7 +180,14 @@ export function handleSkillReport(
|
|
|
178
180
|
report.evidence.length > 0 ||
|
|
179
181
|
evolution.length > 0 ||
|
|
180
182
|
pending_proposals.length > 0 ||
|
|
181
|
-
invPageRows.length > 0
|
|
183
|
+
invPageRows.length > 0 ||
|
|
184
|
+
Boolean(
|
|
185
|
+
testing_readiness?.skill_path ||
|
|
186
|
+
testing_readiness?.eval_set_entries ||
|
|
187
|
+
testing_readiness?.unit_test_cases ||
|
|
188
|
+
testing_readiness?.replay_check_count ||
|
|
189
|
+
testing_readiness?.baseline_sample_size,
|
|
190
|
+
);
|
|
182
191
|
if (!hasData) {
|
|
183
192
|
return Response.json({ error: "Skill not found" }, { status: 404 });
|
|
184
193
|
}
|
|
@@ -784,7 +793,10 @@ export function handleSkillReport(
|
|
|
784
793
|
|
|
785
794
|
if (coverage.checks < 5) {
|
|
786
795
|
trustState = "low_sample";
|
|
787
|
-
trustSummary =
|
|
796
|
+
trustSummary =
|
|
797
|
+
coverage.checks === 0 && testing_readiness
|
|
798
|
+
? `No runtime observations yet. Use the creator test loop to bootstrap this skill before trusting live routing.`
|
|
799
|
+
: `Too few operational observations to assess trust — only ${coverage.checks} checks recorded.`;
|
|
788
800
|
} else if (latestAuditRow?.action === "rolled_back") {
|
|
789
801
|
trustState = "rolled_back";
|
|
790
802
|
trustSummary = "Recent evolution was rolled back — review evidence before re-deploying.";
|
|
@@ -879,5 +891,6 @@ export function handleSkillReport(
|
|
|
879
891
|
evolution_state,
|
|
880
892
|
data_hygiene,
|
|
881
893
|
examples,
|
|
894
|
+
testing_readiness,
|
|
882
895
|
});
|
|
883
896
|
}
|
package/cli/selftune/schedule.ts
CHANGED
|
@@ -376,7 +376,7 @@ export function buildInstallPlan(
|
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
const systemdDir = join(homeDir, ".config", "systemd", "user");
|
|
379
|
-
const definitions = SCHEDULE_ENTRIES.map(buildSystemdDefinition);
|
|
379
|
+
const definitions = SCHEDULE_ENTRIES.map((entry) => buildSystemdDefinition(entry));
|
|
380
380
|
return {
|
|
381
381
|
artifacts: definitions.flatMap((definition) => [
|
|
382
382
|
{ path: join(systemdDir, `${definition.baseName}.timer`), content: definition.timerContent },
|
|
@@ -531,7 +531,7 @@ export function cliMain(): void {
|
|
|
531
531
|
|
|
532
532
|
if (values["apply-cron-artifact"]) {
|
|
533
533
|
try {
|
|
534
|
-
applyCronArtifact(values["apply-cron-artifact"]);
|
|
534
|
+
applyCronArtifact(values["apply-cron-artifact"] as string);
|
|
535
535
|
return;
|
|
536
536
|
} catch (err) {
|
|
537
537
|
throw new CLIError(
|
|
@@ -567,8 +567,8 @@ For OpenClaw-specific scheduling, see: selftune cron`);
|
|
|
567
567
|
if (values.install) {
|
|
568
568
|
try {
|
|
569
569
|
const result = installSchedule({
|
|
570
|
-
format: values.format,
|
|
571
|
-
dryRun: values["dry-run"]
|
|
570
|
+
format: typeof values.format === "string" ? values.format : undefined,
|
|
571
|
+
dryRun: values["dry-run"] === true,
|
|
572
572
|
});
|
|
573
573
|
if (!result.dryRun && !result.activated) {
|
|
574
574
|
throw new CLIError(
|
|
@@ -601,7 +601,7 @@ For OpenClaw-specific scheduling, see: selftune cron`);
|
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
-
const result = formatOutput(values.format);
|
|
604
|
+
const result = formatOutput(typeof values.format === "string" ? values.format : undefined);
|
|
605
605
|
if (!result.ok) {
|
|
606
606
|
throw new CLIError(
|
|
607
607
|
result.error ?? "Invalid schedule format",
|
package/cli/selftune/status.ts
CHANGED
|
@@ -16,7 +16,9 @@ import { getAlphaLinkState, readAlphaIdentity } from "./alpha-identity.js";
|
|
|
16
16
|
import { getQueueStats } from "./alpha-upload/queue.js";
|
|
17
17
|
import { getBaseUrl } from "./auth/device-code.js";
|
|
18
18
|
import { SELFTUNE_CONFIG_PATH } from "./constants.js";
|
|
19
|
+
import type { SkillTestingReadiness } from "./dashboard-contract.js";
|
|
19
20
|
import { getDb } from "./localdb/db.js";
|
|
21
|
+
import { writeCronRunToDb } from "./localdb/direct-write.js";
|
|
20
22
|
import {
|
|
21
23
|
getLastUploadError,
|
|
22
24
|
getLastUploadSuccess,
|
|
@@ -30,6 +32,7 @@ import {
|
|
|
30
32
|
import { computeMonitoringSnapshot, MIN_MONITORING_SKILL_CHECKS } from "./monitoring/watch.js";
|
|
31
33
|
import { doctor } from "./observability.js";
|
|
32
34
|
import { deriveTrustBucket, deriveTrustBucketReason } from "./trust-model.js";
|
|
35
|
+
import { buildCreatorTestingOverview, listSkillTestingReadiness } from "./testing-readiness.js";
|
|
33
36
|
import type {
|
|
34
37
|
AgentCommandGuidance,
|
|
35
38
|
AlphaLinkState,
|
|
@@ -313,7 +316,35 @@ function formatTrustHighlights(trustSummaries: SkillTrustSummary[] | undefined):
|
|
|
313
316
|
return lines;
|
|
314
317
|
}
|
|
315
318
|
|
|
316
|
-
|
|
319
|
+
function formatCreatorLoopLines(readinessRows: SkillTestingReadiness[] | undefined): string[] {
|
|
320
|
+
if (!readinessRows || readinessRows.length === 0) return [];
|
|
321
|
+
|
|
322
|
+
const overview = buildCreatorTestingOverview(readinessRows);
|
|
323
|
+
const lines = ["Creator loop"];
|
|
324
|
+
lines.push(` ${overview.summary}`);
|
|
325
|
+
|
|
326
|
+
const counts = overview.counts;
|
|
327
|
+
lines.push(
|
|
328
|
+
` Generate evals: ${counts.generate_evals} | Unit tests: ${counts.run_unit_tests} | Replay dry-run: ${counts.run_replay_dry_run} | Baseline: ${counts.measure_baseline} | Deploy: ${counts.deploy_candidate} | Watching: ${counts.watch_deployment}`,
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
if (overview.priorities.length > 0) {
|
|
332
|
+
lines.push(" Next:");
|
|
333
|
+
for (const priority of overview.priorities.slice(0, 3)) {
|
|
334
|
+
lines.push(
|
|
335
|
+
` ${priority.skill_name}: ${priority.next_step.replaceAll("_", " ")} — ${priority.recommended_command}`,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return lines;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export function formatStatus(
|
|
344
|
+
result: StatusResult,
|
|
345
|
+
trustSummaries?: SkillTrustSummary[],
|
|
346
|
+
testingReadiness?: SkillTestingReadiness[],
|
|
347
|
+
): string {
|
|
317
348
|
const noColor = !!process.env.NO_COLOR;
|
|
318
349
|
|
|
319
350
|
const green = noColor ? (s: string) => s : (s: string) => colorize(s, "#788c5d");
|
|
@@ -333,6 +364,12 @@ export function formatStatus(result: StatusResult, trustSummaries?: SkillTrustSu
|
|
|
333
364
|
lines.push("");
|
|
334
365
|
}
|
|
335
366
|
|
|
367
|
+
const creatorLoopLines = formatCreatorLoopLines(testingReadiness);
|
|
368
|
+
if (creatorLoopLines.length > 0) {
|
|
369
|
+
lines.push(...creatorLoopLines);
|
|
370
|
+
lines.push("");
|
|
371
|
+
}
|
|
372
|
+
|
|
336
373
|
// Skills table
|
|
337
374
|
const skillCount = result.skills.length;
|
|
338
375
|
lines.push(
|
|
@@ -576,6 +613,8 @@ export function formatAlphaStatus(info: AlphaStatusInfo | null): string {
|
|
|
576
613
|
|
|
577
614
|
export async function cliMain(): Promise<void> {
|
|
578
615
|
const db = getDb();
|
|
616
|
+
const statusStartedAt = new Date();
|
|
617
|
+
const statusStart = performance.now();
|
|
579
618
|
try {
|
|
580
619
|
const telemetry = querySessionTelemetry(db) as SessionTelemetryRecord[];
|
|
581
620
|
const skillRecords = querySkillUsageRecords(db) as SkillUsageRecord[];
|
|
@@ -585,7 +624,8 @@ export async function cliMain(): Promise<void> {
|
|
|
585
624
|
|
|
586
625
|
const result = computeStatus(telemetry, skillRecords, queryRecords, auditEntries, doctorResult);
|
|
587
626
|
const trustSummaries = getSkillTrustSummaries(db);
|
|
588
|
-
const
|
|
627
|
+
const testingReadiness = listSkillTestingReadiness(db);
|
|
628
|
+
const output = formatStatus(result, trustSummaries, testingReadiness);
|
|
589
629
|
console.log(output);
|
|
590
630
|
|
|
591
631
|
// Alpha upload status section
|
|
@@ -610,9 +650,37 @@ export async function cliMain(): Promise<void> {
|
|
|
610
650
|
}
|
|
611
651
|
console.log(formatAlphaStatus(alphaInfo));
|
|
612
652
|
|
|
653
|
+
// Log cron run for unified timeline visibility
|
|
654
|
+
const statusElapsed = Math.round(performance.now() - statusStart);
|
|
655
|
+
writeCronRunToDb(db, {
|
|
656
|
+
jobName: "status",
|
|
657
|
+
startedAt: statusStartedAt.toISOString(),
|
|
658
|
+
elapsedMs: statusElapsed,
|
|
659
|
+
status: "success",
|
|
660
|
+
metrics: {
|
|
661
|
+
total_skills: result.skills.length,
|
|
662
|
+
healthy: result.skills.filter((s) => s.status === "HEALTHY").length,
|
|
663
|
+
warning: result.skills.filter((s) => s.status === "WARNING").length,
|
|
664
|
+
critical: result.skills.filter((s) => s.status === "CRITICAL").length,
|
|
665
|
+
system_healthy: result.system.healthy,
|
|
666
|
+
unmatched_queries: result.unmatchedQueries,
|
|
667
|
+
pending_proposals: result.pendingProposals,
|
|
668
|
+
},
|
|
669
|
+
});
|
|
670
|
+
|
|
613
671
|
process.exit(0);
|
|
614
672
|
} catch (err) {
|
|
673
|
+
// Log failed status run
|
|
674
|
+
const statusElapsed = Math.round(performance.now() - statusStart);
|
|
615
675
|
const message = err instanceof Error ? err.message : String(err);
|
|
676
|
+
writeCronRunToDb(db, {
|
|
677
|
+
jobName: "status",
|
|
678
|
+
startedAt: statusStartedAt.toISOString(),
|
|
679
|
+
elapsedMs: statusElapsed,
|
|
680
|
+
status: "error",
|
|
681
|
+
error: message,
|
|
682
|
+
});
|
|
683
|
+
|
|
616
684
|
console.error(`selftune status failed: ${message}`);
|
|
617
685
|
process.exit(1);
|
|
618
686
|
}
|