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.
- package/CHANGELOG.md +6 -0
- package/README.md +93 -15
- package/apps/local-dashboard/dist/assets/index-DgY2KGP-.css +1 -0
- package/apps/local-dashboard/dist/assets/index-Dhgv5BQO.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/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/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 +73 -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/replay-engine.ts +79 -57
- package/cli/selftune/evolution/evolve-body.ts +100 -39
- package/cli/selftune/evolution/evolve.ts +244 -52
- package/cli/selftune/evolution/rollback.ts +0 -1
- package/cli/selftune/evolution/validate-body.ts +68 -42
- 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 +43 -41
- 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/index.ts +35 -10
- 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 +3 -2
- package/cli/selftune/init.ts +27 -3
- package/cli/selftune/localdb/direct-write.ts +35 -1
- 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 -2288
- package/cli/selftune/localdb/schema.ts +21 -0
- package/cli/selftune/monitoring/watch.ts +96 -29
- package/cli/selftune/normalization.ts +3 -0
- package/cli/selftune/observability.ts +4 -2
- 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 +150 -1173
- package/cli/selftune/repair/skill-usage.ts +5 -2
- 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 +39 -2
- package/cli/selftune/testing-readiness.ts +597 -0
- package/cli/selftune/types.ts +44 -4
- 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/llm-call.ts +126 -6
- package/cli/selftune/utils/skill-discovery.ts +2 -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 +1 -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 +1 -1
- package/node_modules/@selftune/telemetry-contract/src/schemas.ts +41 -1
- package/node_modules/@selftune/telemetry-contract/src/types.ts +103 -2
- 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 +1 -1
- package/packages/telemetry-contract/fixtures/partial-push-no-sessions.ts +1 -1
- package/packages/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +1 -1
- package/packages/telemetry-contract/src/schemas.ts +41 -1
- package/packages/telemetry-contract/src/types.ts +103 -2
- package/packages/ui/src/components/EvidenceViewer.tsx +80 -25
- package/packages/ui/src/components/OverviewPanels.tsx +67 -26
- package/packages/ui/src/primitives/tabs.tsx +7 -6
- package/packages/ui/src/types.ts +10 -0
- package/skill/SKILL.md +130 -332
- 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}/Initialize.md +8 -4
- package/skill/{Workflows → workflows}/Orchestrate.md +13 -3
- package/skill/{Workflows → workflows}/Schedule.md +3 -3
- package/skill/workflows/SignalsDashboard.md +87 -0
- 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-CwOtTrUS.css +0 -1
- package/apps/local-dashboard/dist/assets/index-f1HQpbeH.js +0 -59
- package/apps/local-dashboard/dist/assets/vendor-react-CKkiCskZ.js +0 -11
- package/apps/local-dashboard/dist/assets/vendor-ui-jVSaIZey.js +0 -12
- /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}/Ingest.md +0 -0
- /package/skill/{Workflows → workflows}/PlatformHooks.md +0 -0
- /package/skill/{Workflows → workflows}/Quickstart.md +0 -0
- /package/skill/{Workflows → workflows}/Recover.md +0 -0
- /package/skill/{Workflows → workflows}/Registry.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}/Sync.md +0 -0
- /package/skill/{Workflows → workflows}/Telemetry.md +0 -0
- /package/skill/{Workflows → workflows}/Uninstall.md +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { CONTRIBUTION_PREFERENCES_PATH, SELFTUNE_CONFIG_DIR } from "./constants.js";
|
|
5
|
+
import type { ContributionSignal } from "./contribution-signals.js";
|
|
6
|
+
|
|
7
|
+
export type ContributionGlobalDefault = "ask" | "always" | "never";
|
|
8
|
+
export type ContributionSkillStatus = "opted_in" | "opted_out";
|
|
9
|
+
|
|
10
|
+
export interface ContributionSkillPreference {
|
|
11
|
+
status: ContributionSkillStatus;
|
|
12
|
+
opted_in_at?: string;
|
|
13
|
+
opted_out_at?: string;
|
|
14
|
+
creator_id?: string;
|
|
15
|
+
signals?: ContributionSignal[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ContributionPreferences {
|
|
19
|
+
version: 1;
|
|
20
|
+
global_default: ContributionGlobalDefault;
|
|
21
|
+
skills: Record<string, ContributionSkillPreference>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const DEFAULT_PREFERENCES: ContributionPreferences = {
|
|
25
|
+
version: 1,
|
|
26
|
+
global_default: "ask",
|
|
27
|
+
skills: {},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
let cachedPreferences: ContributionPreferences | undefined;
|
|
31
|
+
|
|
32
|
+
function getSelftuneConfigDir(): string {
|
|
33
|
+
return process.env.SELFTUNE_CONFIG_DIR || SELFTUNE_CONFIG_DIR;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getContributionPreferencesPath(): string {
|
|
37
|
+
return process.env.SELFTUNE_CONFIG_DIR
|
|
38
|
+
? join(process.env.SELFTUNE_CONFIG_DIR, "contribution-preferences.json")
|
|
39
|
+
: CONTRIBUTION_PREFERENCES_PATH;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function cloneDefaultContributionPreferences(): ContributionPreferences {
|
|
43
|
+
return {
|
|
44
|
+
version: 1,
|
|
45
|
+
global_default: "ask",
|
|
46
|
+
skills: {},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function isValidGlobalDefault(value: unknown): value is ContributionGlobalDefault {
|
|
51
|
+
return value === "ask" || value === "always" || value === "never";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizePreferences(raw: unknown): ContributionPreferences {
|
|
55
|
+
if (!raw || typeof raw !== "object") return cloneDefaultContributionPreferences();
|
|
56
|
+
const candidate = raw as Partial<ContributionPreferences>;
|
|
57
|
+
const globalDefault = isValidGlobalDefault(candidate.global_default)
|
|
58
|
+
? candidate.global_default
|
|
59
|
+
: DEFAULT_PREFERENCES.global_default;
|
|
60
|
+
const skills: Record<string, ContributionSkillPreference> = {};
|
|
61
|
+
|
|
62
|
+
if (candidate.skills && typeof candidate.skills === "object") {
|
|
63
|
+
for (const [skill, pref] of Object.entries(candidate.skills)) {
|
|
64
|
+
if (!pref || typeof pref !== "object") continue;
|
|
65
|
+
const status = (pref as Partial<ContributionSkillPreference>).status;
|
|
66
|
+
if (status !== "opted_in" && status !== "opted_out") continue;
|
|
67
|
+
skills[skill] = {
|
|
68
|
+
status,
|
|
69
|
+
opted_in_at: (pref as Partial<ContributionSkillPreference>).opted_in_at,
|
|
70
|
+
opted_out_at: (pref as Partial<ContributionSkillPreference>).opted_out_at,
|
|
71
|
+
creator_id:
|
|
72
|
+
typeof (pref as Partial<ContributionSkillPreference>).creator_id === "string"
|
|
73
|
+
? (pref as Partial<ContributionSkillPreference>).creator_id
|
|
74
|
+
: undefined,
|
|
75
|
+
signals: Array.isArray((pref as Partial<ContributionSkillPreference>).signals)
|
|
76
|
+
? (pref as Partial<ContributionSkillPreference>).signals?.filter(
|
|
77
|
+
(signal): signal is ContributionSignal =>
|
|
78
|
+
signal === "trigger" || signal === "grade" || signal === "miss_category",
|
|
79
|
+
)
|
|
80
|
+
: undefined,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
version: 1,
|
|
87
|
+
global_default: globalDefault,
|
|
88
|
+
skills,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function loadContributionPreferences(): ContributionPreferences {
|
|
93
|
+
if (cachedPreferences) return cachedPreferences;
|
|
94
|
+
const preferencesPath = getContributionPreferencesPath();
|
|
95
|
+
try {
|
|
96
|
+
if (!existsSync(preferencesPath)) {
|
|
97
|
+
cachedPreferences = cloneDefaultContributionPreferences();
|
|
98
|
+
return cachedPreferences;
|
|
99
|
+
}
|
|
100
|
+
const parsed = JSON.parse(readFileSync(preferencesPath, "utf-8")) as unknown;
|
|
101
|
+
cachedPreferences = normalizePreferences(parsed);
|
|
102
|
+
return cachedPreferences;
|
|
103
|
+
} catch {
|
|
104
|
+
cachedPreferences = cloneDefaultContributionPreferences();
|
|
105
|
+
return cachedPreferences;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function saveContributionPreferences(preferences: ContributionPreferences): void {
|
|
110
|
+
mkdirSync(getSelftuneConfigDir(), { recursive: true });
|
|
111
|
+
writeFileSync(getContributionPreferencesPath(), JSON.stringify(preferences, null, 2), "utf-8");
|
|
112
|
+
cachedPreferences = preferences;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function resetContributionPreferencesState(): void {
|
|
116
|
+
cachedPreferences = undefined;
|
|
117
|
+
}
|
|
@@ -12,6 +12,7 @@ export type ContributionSignal = "trigger" | "grade" | "miss_category";
|
|
|
12
12
|
export interface CreatorContributionRelayPayload {
|
|
13
13
|
version: 1;
|
|
14
14
|
signal_type: "skill_session";
|
|
15
|
+
skill_name?: string;
|
|
15
16
|
relay_destination: string;
|
|
16
17
|
skill_hash: string;
|
|
17
18
|
user_cohort: string;
|
|
@@ -114,11 +115,12 @@ export function buildCreatorDirectedContributionSignals(
|
|
|
114
115
|
options: ContributionSignalBuildOptions = {},
|
|
115
116
|
): CreatorContributionSignalRecord[] {
|
|
116
117
|
const bySkill = new Map(configs.map((config) => [config.skill_name, config]));
|
|
117
|
-
const
|
|
118
|
+
const gradingBySkillSession = new Map<string, "A" | "B" | "C" | "F">();
|
|
118
119
|
for (const row of queryGradingResults(db)) {
|
|
119
120
|
const source = typeof row.mean_score === "number" ? row.mean_score : row.pass_rate;
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
const key = `${row.skill_name}::${row.session_id}`;
|
|
122
|
+
if (typeof source === "number" && !gradingBySkillSession.has(key)) {
|
|
123
|
+
gradingBySkillSession.set(key, gradeBucket(source));
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
|
|
@@ -136,7 +138,7 @@ export function buildCreatorDirectedContributionSignals(
|
|
|
136
138
|
signals.miss_detected = row.triggered === 0;
|
|
137
139
|
}
|
|
138
140
|
if (config.contribution.signals.includes("grade")) {
|
|
139
|
-
const grade =
|
|
141
|
+
const grade = gradingBySkillSession.get(`${row.skill_name}::${row.session_id}`);
|
|
140
142
|
if (grade) signals.execution_grade = grade;
|
|
141
143
|
}
|
|
142
144
|
if (config.contribution.signals.includes("miss_category")) {
|
|
@@ -162,6 +164,7 @@ export function buildCreatorDirectedContributionSignals(
|
|
|
162
164
|
payload: {
|
|
163
165
|
version: 1 as const,
|
|
164
166
|
signal_type: "skill_session" as const,
|
|
167
|
+
skill_name: config.skill_name,
|
|
165
168
|
relay_destination: config.creator_id,
|
|
166
169
|
skill_hash: buildContributionSkillHash(config.skill_name),
|
|
167
170
|
user_cohort: cohort,
|
|
@@ -206,6 +209,7 @@ export function buildContributionPreview(
|
|
|
206
209
|
samplePayload: payloads[0]?.payload ?? {
|
|
207
210
|
version: 1,
|
|
208
211
|
signal_type: "skill_session",
|
|
212
|
+
skill_name: config.skill_name,
|
|
209
213
|
relay_destination: config.creator_id,
|
|
210
214
|
skill_hash: buildContributionSkillHash(config.skill_name),
|
|
211
215
|
user_cohort: buildContributionUserCohort(options.now ?? new Date(), options.cohortSeed),
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
2
|
|
|
3
3
|
import type { CreatorContributionConfig } from "./contribution-config.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
discoverCreatorContributionConfigs,
|
|
6
|
+
isSupportedContributionSignal,
|
|
7
|
+
isValidCreatorUUID,
|
|
8
|
+
} from "./contribution-config.js";
|
|
9
|
+
import {
|
|
10
|
+
loadContributionPreferences,
|
|
11
|
+
type ContributionPreferences,
|
|
12
|
+
} from "./contribution-preferences.js";
|
|
5
13
|
import { buildCreatorDirectedContributionSignals } from "./contribution-signals.js";
|
|
6
|
-
import { loadContributionPreferences, type ContributionPreferences } from "./contributions.js";
|
|
7
14
|
|
|
8
15
|
export interface CreatorContributionStagingResult {
|
|
9
16
|
eligible_skills: number;
|
|
@@ -34,6 +41,10 @@ export function resolveEligibleContributionConfigs(
|
|
|
34
41
|
configs: CreatorContributionConfig[] = discoverCreatorContributionConfigs(),
|
|
35
42
|
): CreatorContributionConfig[] {
|
|
36
43
|
return configs.filter((config) => {
|
|
44
|
+
if (!isValidCreatorUUID(config.creator_id)) return false;
|
|
45
|
+
if (!config.contribution.signals.some((signal) => isSupportedContributionSignal(signal))) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
37
48
|
const pref = preferences.skills[config.skill_name];
|
|
38
49
|
if (pref?.status === "opted_out") return false;
|
|
39
50
|
if (pref?.status === "opted_in") return true;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
2
|
|
|
5
|
-
import { CONTRIBUTION_PREFERENCES_PATH, SELFTUNE_CONFIG_DIR } from "./constants.js";
|
|
6
3
|
import {
|
|
7
4
|
discoverCreatorContributionConfigs,
|
|
8
5
|
findCreatorContributionConfig,
|
|
6
|
+
isSupportedContributionSignal,
|
|
7
|
+
isValidCreatorUUID,
|
|
9
8
|
} from "./contribution-config.js";
|
|
9
|
+
import {
|
|
10
|
+
cloneDefaultContributionPreferences,
|
|
11
|
+
isValidGlobalDefault,
|
|
12
|
+
loadContributionPreferences,
|
|
13
|
+
resetContributionPreferencesState,
|
|
14
|
+
saveContributionPreferences,
|
|
15
|
+
type ContributionPreferences,
|
|
16
|
+
type ContributionSkillStatus,
|
|
17
|
+
} from "./contribution-preferences.js";
|
|
10
18
|
import {
|
|
11
19
|
flushCreatorContributionSignals,
|
|
12
20
|
resolveContributionRelayEndpoint,
|
|
@@ -17,6 +25,7 @@ import {
|
|
|
17
25
|
type ContributionSignalBuildOptions,
|
|
18
26
|
type CreatorContributionRelayPayload,
|
|
19
27
|
} from "./contribution-signals.js";
|
|
28
|
+
import type { CreatorContributionConfig } from "./contribution-config.js";
|
|
20
29
|
import { getDb } from "./localdb/db.js";
|
|
21
30
|
import {
|
|
22
31
|
getCreatorContributionRelayStats,
|
|
@@ -25,22 +34,16 @@ import {
|
|
|
25
34
|
} from "./localdb/queries.js";
|
|
26
35
|
import { CLIError } from "./utils/cli-error.js";
|
|
27
36
|
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface ContributionPreferences {
|
|
40
|
-
version: 1;
|
|
41
|
-
global_default: ContributionGlobalDefault;
|
|
42
|
-
skills: Record<string, ContributionSkillPreference>;
|
|
43
|
-
}
|
|
37
|
+
export {
|
|
38
|
+
cloneDefaultContributionPreferences,
|
|
39
|
+
loadContributionPreferences,
|
|
40
|
+
resetContributionPreferencesState,
|
|
41
|
+
saveContributionPreferences,
|
|
42
|
+
type ContributionGlobalDefault,
|
|
43
|
+
type ContributionPreferences,
|
|
44
|
+
type ContributionSkillPreference,
|
|
45
|
+
type ContributionSkillStatus,
|
|
46
|
+
} from "./contribution-preferences.js";
|
|
44
47
|
|
|
45
48
|
export interface ContributionPromptCandidate {
|
|
46
49
|
skill_name: string;
|
|
@@ -48,101 +51,6 @@ export interface ContributionPromptCandidate {
|
|
|
48
51
|
successful_triggers: number;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
const DEFAULT_PREFERENCES: ContributionPreferences = {
|
|
52
|
-
version: 1,
|
|
53
|
-
global_default: "ask",
|
|
54
|
-
skills: {},
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
let cachedPreferences: ContributionPreferences | undefined;
|
|
58
|
-
|
|
59
|
-
function getSelftuneConfigDir(): string {
|
|
60
|
-
return process.env.SELFTUNE_CONFIG_DIR || SELFTUNE_CONFIG_DIR;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function getContributionPreferencesPath(): string {
|
|
64
|
-
return process.env.SELFTUNE_CONFIG_DIR
|
|
65
|
-
? join(process.env.SELFTUNE_CONFIG_DIR, "contribution-preferences.json")
|
|
66
|
-
: CONTRIBUTION_PREFERENCES_PATH;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function cloneDefaultPreferences(): ContributionPreferences {
|
|
70
|
-
return {
|
|
71
|
-
version: 1,
|
|
72
|
-
global_default: "ask",
|
|
73
|
-
skills: {},
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function isValidGlobalDefault(value: unknown): value is ContributionGlobalDefault {
|
|
78
|
-
return value === "ask" || value === "always" || value === "never";
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function normalizePreferences(raw: unknown): ContributionPreferences {
|
|
82
|
-
if (!raw || typeof raw !== "object") return cloneDefaultPreferences();
|
|
83
|
-
const candidate = raw as Partial<ContributionPreferences>;
|
|
84
|
-
const globalDefault = isValidGlobalDefault(candidate.global_default)
|
|
85
|
-
? candidate.global_default
|
|
86
|
-
: DEFAULT_PREFERENCES.global_default;
|
|
87
|
-
const skills: Record<string, ContributionSkillPreference> = {};
|
|
88
|
-
|
|
89
|
-
if (candidate.skills && typeof candidate.skills === "object") {
|
|
90
|
-
for (const [skill, pref] of Object.entries(candidate.skills)) {
|
|
91
|
-
if (!pref || typeof pref !== "object") continue;
|
|
92
|
-
const status = (pref as Partial<ContributionSkillPreference>).status;
|
|
93
|
-
if (status !== "opted_in" && status !== "opted_out") continue;
|
|
94
|
-
skills[skill] = {
|
|
95
|
-
status,
|
|
96
|
-
opted_in_at: (pref as Partial<ContributionSkillPreference>).opted_in_at,
|
|
97
|
-
opted_out_at: (pref as Partial<ContributionSkillPreference>).opted_out_at,
|
|
98
|
-
creator_id:
|
|
99
|
-
typeof (pref as Partial<ContributionSkillPreference>).creator_id === "string"
|
|
100
|
-
? (pref as Partial<ContributionSkillPreference>).creator_id
|
|
101
|
-
: undefined,
|
|
102
|
-
signals: Array.isArray((pref as Partial<ContributionSkillPreference>).signals)
|
|
103
|
-
? (pref as Partial<ContributionSkillPreference>).signals?.filter(
|
|
104
|
-
(signal): signal is ContributionSignal =>
|
|
105
|
-
signal === "trigger" || signal === "grade" || signal === "miss_category",
|
|
106
|
-
)
|
|
107
|
-
: undefined,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
version: 1,
|
|
114
|
-
global_default: globalDefault,
|
|
115
|
-
skills,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function loadContributionPreferences(): ContributionPreferences {
|
|
120
|
-
if (cachedPreferences) return cachedPreferences;
|
|
121
|
-
const preferencesPath = getContributionPreferencesPath();
|
|
122
|
-
try {
|
|
123
|
-
if (!existsSync(preferencesPath)) {
|
|
124
|
-
cachedPreferences = cloneDefaultPreferences();
|
|
125
|
-
return cachedPreferences;
|
|
126
|
-
}
|
|
127
|
-
const parsed = JSON.parse(readFileSync(preferencesPath, "utf-8")) as unknown;
|
|
128
|
-
cachedPreferences = normalizePreferences(parsed);
|
|
129
|
-
return cachedPreferences;
|
|
130
|
-
} catch {
|
|
131
|
-
cachedPreferences = cloneDefaultPreferences();
|
|
132
|
-
return cachedPreferences;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function saveContributionPreferences(preferences: ContributionPreferences): void {
|
|
137
|
-
mkdirSync(getSelftuneConfigDir(), { recursive: true });
|
|
138
|
-
writeFileSync(getContributionPreferencesPath(), JSON.stringify(preferences, null, 2), "utf-8");
|
|
139
|
-
cachedPreferences = preferences;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export function resetContributionPreferencesState(): void {
|
|
143
|
-
cachedPreferences = undefined;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
54
|
function printStatus(preferences: ContributionPreferences): void {
|
|
147
55
|
const discovered = discoverCreatorContributionConfigs();
|
|
148
56
|
const promptCandidates = listContributionPromptCandidates(preferences);
|
|
@@ -223,6 +131,11 @@ export function listContributionPromptCandidates(
|
|
|
223
131
|
|
|
224
132
|
const bySkill = new Map(getSkillTrustSummaries(getDb()).map((row) => [row.skill_name, row]));
|
|
225
133
|
return discoverCreatorContributionConfigs()
|
|
134
|
+
.filter(
|
|
135
|
+
(config) =>
|
|
136
|
+
isValidCreatorUUID(config.creator_id) &&
|
|
137
|
+
config.contribution.signals.some((signal) => isSupportedContributionSignal(signal)),
|
|
138
|
+
)
|
|
226
139
|
.filter((config) => !preferences.skills[config.skill_name])
|
|
227
140
|
.map((config) => {
|
|
228
141
|
const summary = bySkill.get(config.skill_name);
|
|
@@ -247,19 +160,40 @@ function upsertSkillPreference(skill: string, status: ContributionSkillStatus):
|
|
|
247
160
|
const preferences = loadContributionPreferences();
|
|
248
161
|
const timestamp = new Date().toISOString();
|
|
249
162
|
const discovered = findCreatorContributionConfig(normalizedSkill);
|
|
163
|
+
if (!discovered) {
|
|
164
|
+
throw new CLIError(
|
|
165
|
+
`No creator contribution request found for "${normalizedSkill}".`,
|
|
166
|
+
"FILE_NOT_FOUND",
|
|
167
|
+
"Run `selftune contributions` to see installed skill requests.",
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
if (!isValidCreatorUUID(discovered.creator_id)) {
|
|
171
|
+
throw new CLIError(
|
|
172
|
+
`Creator contribution request for "${normalizedSkill}" has an invalid creator_id.`,
|
|
173
|
+
"INVALID_FLAG",
|
|
174
|
+
"Ask the skill creator to ship a valid selftune.contribute.json or choose another skill.",
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
const validSignals = discovered.contribution.signals.filter(
|
|
178
|
+
(signal): signal is ContributionSignal => isSupportedContributionSignal(signal),
|
|
179
|
+
);
|
|
180
|
+
if (validSignals.length === 0) {
|
|
181
|
+
throw new CLIError(
|
|
182
|
+
`Creator contribution request for "${normalizedSkill}" does not declare any supported signals.`,
|
|
183
|
+
"INVALID_FLAG",
|
|
184
|
+
"Ask the skill creator to ship a valid selftune.contribute.json or choose another skill.",
|
|
185
|
+
);
|
|
186
|
+
}
|
|
250
187
|
preferences.skills[normalizedSkill] =
|
|
251
188
|
status === "opted_in"
|
|
252
189
|
? { status, opted_in_at: timestamp }
|
|
253
190
|
: { status, opted_out_at: timestamp };
|
|
254
|
-
if (status === "opted_in"
|
|
191
|
+
if (status === "opted_in") {
|
|
255
192
|
preferences.skills[normalizedSkill] = {
|
|
256
193
|
status,
|
|
257
194
|
opted_in_at: timestamp,
|
|
258
195
|
creator_id: discovered.creator_id,
|
|
259
|
-
signals:
|
|
260
|
-
(signal): signal is ContributionSignal =>
|
|
261
|
-
signal === "trigger" || signal === "grade" || signal === "miss_category",
|
|
262
|
-
),
|
|
196
|
+
signals: validSignals,
|
|
263
197
|
};
|
|
264
198
|
}
|
|
265
199
|
saveContributionPreferences(preferences);
|
|
@@ -273,7 +207,7 @@ function buildPreviewPayload(
|
|
|
273
207
|
skill: string,
|
|
274
208
|
options: ContributionSignalBuildOptions = {},
|
|
275
209
|
): {
|
|
276
|
-
config:
|
|
210
|
+
config: CreatorContributionConfig;
|
|
277
211
|
observedCount: number;
|
|
278
212
|
triggerRate: number | null;
|
|
279
213
|
missRate: number | null;
|
|
@@ -345,7 +279,7 @@ function setGlobalDefault(value: string | undefined): void {
|
|
|
345
279
|
}
|
|
346
280
|
|
|
347
281
|
function resetPreferences(): void {
|
|
348
|
-
saveContributionPreferences(
|
|
282
|
+
saveContributionPreferences(cloneDefaultContributionPreferences());
|
|
349
283
|
console.log("Creator-directed contribution preferences reset to defaults.");
|
|
350
284
|
}
|
|
351
285
|
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
discoverCreatorContributionConfigs,
|
|
10
10
|
findCreatorContributionConfig,
|
|
11
11
|
getContributionConfigSearchRoots,
|
|
12
|
+
isValidCreatorUUID,
|
|
13
|
+
normalizeSupportedContributionSignals,
|
|
12
14
|
removeCreatorContributionConfig,
|
|
13
15
|
resolveContributionSkillPath,
|
|
14
16
|
writeCreatorContributionConfig,
|
|
@@ -96,9 +98,16 @@ function enableCreatorContributionConfigs(options: {
|
|
|
96
98
|
const creatorId = inferCreatorId(options.explicitCreatorId);
|
|
97
99
|
if (!creatorId) {
|
|
98
100
|
throw new CLIError(
|
|
99
|
-
"Creator ID is required.",
|
|
101
|
+
"Creator ID is required. Must be the creator's cloud user UUID.",
|
|
100
102
|
"MISSING_FLAG",
|
|
101
|
-
"Pass --creator-id <
|
|
103
|
+
"Pass --creator-id <uuid> or enroll alpha so cloud_user_id is available.",
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (!isValidCreatorUUID(creatorId)) {
|
|
107
|
+
throw new CLIError(
|
|
108
|
+
`Creator ID must be a cloud user UUID. Received "${creatorId}".`,
|
|
109
|
+
"INVALID_FLAG",
|
|
110
|
+
"Pass --creator-id <uuid> or enroll alpha so cloud_user_id is available.",
|
|
102
111
|
);
|
|
103
112
|
}
|
|
104
113
|
|
|
@@ -158,7 +167,7 @@ export async function cliMain(): Promise<void> {
|
|
|
158
167
|
const rest = process.argv.slice(3);
|
|
159
168
|
|
|
160
169
|
if (sub === "--help" || sub === "-h") {
|
|
161
|
-
console.log(`selftune creator-contributions — Manage creator
|
|
170
|
+
console.log(`selftune creator-contributions — Manage creator sharing setup configs
|
|
162
171
|
|
|
163
172
|
Usage:
|
|
164
173
|
selftune creator-contributions
|
|
@@ -168,9 +177,11 @@ Usage:
|
|
|
168
177
|
selftune creator-contributions disable --skill <name> [--skill-path <path>]
|
|
169
178
|
|
|
170
179
|
Purpose:
|
|
171
|
-
Manage the local selftune.contribute.json
|
|
172
|
-
with a skill package.
|
|
173
|
-
|
|
180
|
+
Manage the local selftune.contribute.json creator sharing setup file that
|
|
181
|
+
a skill creator bundles with a skill package. The --creator-id must be the
|
|
182
|
+
creator's cloud user UUID (the cloud_user_id from alpha enrollment).
|
|
183
|
+
This is separate from:
|
|
184
|
+
selftune contributions Sharing preferences (end-user opt-in/out)
|
|
174
185
|
selftune contribute Community export bundle`);
|
|
175
186
|
return;
|
|
176
187
|
}
|
|
@@ -225,10 +236,18 @@ Purpose:
|
|
|
225
236
|
);
|
|
226
237
|
}
|
|
227
238
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
239
|
+
let signals: string[];
|
|
240
|
+
try {
|
|
241
|
+
signals = normalizeSupportedContributionSignals(
|
|
242
|
+
(values.signals ?? "trigger,grade,miss_category").split(","),
|
|
243
|
+
);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new CLIError(
|
|
246
|
+
error instanceof Error ? error.message : String(error),
|
|
247
|
+
"INVALID_FLAG",
|
|
248
|
+
"selftune creator-contributions enable --help",
|
|
249
|
+
);
|
|
250
|
+
}
|
|
232
251
|
const outcome = enableCreatorContributionConfigs({
|
|
233
252
|
skillName: values.skill?.trim(),
|
|
234
253
|
all: values.all,
|
|
@@ -231,17 +231,21 @@ export async function cliMain(): Promise<void> {
|
|
|
231
231
|
});
|
|
232
232
|
|
|
233
233
|
// Get timezone: flag > env > system default
|
|
234
|
-
const tz =
|
|
234
|
+
const tz =
|
|
235
|
+
(typeof values.tz === "string" ? values.tz : undefined) ??
|
|
236
|
+
process.env.TZ ??
|
|
237
|
+
Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
238
|
+
const dryRun = values["dry-run"] === true;
|
|
235
239
|
|
|
236
240
|
switch (subcommand) {
|
|
237
241
|
case "setup":
|
|
238
|
-
await setupCronJobs(tz,
|
|
242
|
+
await setupCronJobs(tz, dryRun);
|
|
239
243
|
break;
|
|
240
244
|
case "list":
|
|
241
245
|
listCronJobs();
|
|
242
246
|
break;
|
|
243
247
|
case "remove":
|
|
244
|
-
await removeCronJobs(
|
|
248
|
+
await removeCronJobs(dryRun);
|
|
245
249
|
break;
|
|
246
250
|
default:
|
|
247
251
|
console.log(`selftune cron — OpenClaw cron integration
|
|
@@ -91,6 +91,16 @@ export interface EvalSnapshot {
|
|
|
91
91
|
improved?: boolean;
|
|
92
92
|
regressions?: Array<Record<string, unknown>>;
|
|
93
93
|
new_passes?: Array<Record<string, unknown>>;
|
|
94
|
+
per_entry_results?: Array<Record<string, unknown>>;
|
|
95
|
+
before_entry_results?: Array<Record<string, unknown>>;
|
|
96
|
+
gates_passed?: number;
|
|
97
|
+
gates_total?: number;
|
|
98
|
+
gate_results?: Array<Record<string, unknown>>;
|
|
99
|
+
validation_mode?: string;
|
|
100
|
+
validation_agent?: string;
|
|
101
|
+
validation_fixture_id?: string;
|
|
102
|
+
validation_fallback_reason?: string;
|
|
103
|
+
validation_evidence_ref?: string;
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
export interface EvolutionEntry {
|
|
@@ -140,6 +150,7 @@ export interface SkillSummary {
|
|
|
140
150
|
has_evidence: boolean;
|
|
141
151
|
routing_confidence: number | null;
|
|
142
152
|
confidence_coverage: number;
|
|
153
|
+
testing_readiness?: SkillTestingReadiness;
|
|
143
154
|
}
|
|
144
155
|
|
|
145
156
|
// -- Autonomy-first overview types -------------------------------------------
|
|
@@ -226,6 +237,7 @@ export interface OverviewResponse {
|
|
|
226
237
|
attention_queue: AttentionItem[];
|
|
227
238
|
trust_watchlist: TrustWatchlistEntry[];
|
|
228
239
|
recent_decisions: AutonomousDecision[];
|
|
240
|
+
creator_testing?: CreatorTestingOverview;
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
export interface EvidenceEntry {
|
|
@@ -303,6 +315,62 @@ export interface SkillReportPayload {
|
|
|
303
315
|
sessions_with_skill: number;
|
|
304
316
|
}
|
|
305
317
|
|
|
318
|
+
export type SkillEvalReadiness = "log_ready" | "cold_start_ready" | "telemetry_only";
|
|
319
|
+
|
|
320
|
+
export type CreatorLoopNextStep =
|
|
321
|
+
| "generate_evals"
|
|
322
|
+
| "run_unit_tests"
|
|
323
|
+
| "run_replay_dry_run"
|
|
324
|
+
| "measure_baseline"
|
|
325
|
+
| "deploy_candidate"
|
|
326
|
+
| "watch_deployment";
|
|
327
|
+
|
|
328
|
+
export type DeploymentReadiness = "blocked" | "ready_to_deploy" | "watching" | "rolled_back";
|
|
329
|
+
|
|
330
|
+
export interface SkillTestingReadiness {
|
|
331
|
+
skill_name: string;
|
|
332
|
+
eval_readiness: SkillEvalReadiness;
|
|
333
|
+
next_step: CreatorLoopNextStep;
|
|
334
|
+
summary: string;
|
|
335
|
+
recommended_command: string;
|
|
336
|
+
skill_path: string | null;
|
|
337
|
+
trusted_trigger_count: number;
|
|
338
|
+
trusted_session_count: number;
|
|
339
|
+
eval_set_entries: number;
|
|
340
|
+
latest_eval_at: string | null;
|
|
341
|
+
unit_test_cases: number;
|
|
342
|
+
unit_test_pass_rate: number | null;
|
|
343
|
+
unit_test_ran_at: string | null;
|
|
344
|
+
replay_check_count: number;
|
|
345
|
+
latest_validation_mode: "structural_guard" | "host_replay" | "llm_judge" | null;
|
|
346
|
+
baseline_sample_size: number;
|
|
347
|
+
baseline_pass_rate: number | null;
|
|
348
|
+
latest_baseline_at: string | null;
|
|
349
|
+
deployment_readiness: DeploymentReadiness;
|
|
350
|
+
deployment_summary: string;
|
|
351
|
+
deployment_command: string | null;
|
|
352
|
+
latest_evolution_action: string | null;
|
|
353
|
+
latest_evolution_at: string | null;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export interface CreatorTestingOverview {
|
|
357
|
+
summary: string;
|
|
358
|
+
counts: {
|
|
359
|
+
generate_evals: number;
|
|
360
|
+
run_unit_tests: number;
|
|
361
|
+
run_replay_dry_run: number;
|
|
362
|
+
measure_baseline: number;
|
|
363
|
+
deploy_candidate: number;
|
|
364
|
+
watch_deployment: number;
|
|
365
|
+
};
|
|
366
|
+
priorities: Array<{
|
|
367
|
+
skill_name: string;
|
|
368
|
+
next_step: CreatorLoopNextStep;
|
|
369
|
+
summary: string;
|
|
370
|
+
recommended_command: string;
|
|
371
|
+
}>;
|
|
372
|
+
}
|
|
373
|
+
|
|
306
374
|
// -- Orchestrate run report types --------------------------------------------
|
|
307
375
|
|
|
308
376
|
export interface OrchestrateRunSkillAction {
|
|
@@ -384,7 +452,11 @@ export interface HealthResponse {
|
|
|
384
452
|
ok: boolean;
|
|
385
453
|
service: string;
|
|
386
454
|
version: string;
|
|
455
|
+
pid: number;
|
|
387
456
|
spa: boolean;
|
|
457
|
+
spa_mode?: "dist" | "proxy" | "missing";
|
|
458
|
+
spa_build_id?: string | null;
|
|
459
|
+
spa_proxy_url?: string | null;
|
|
388
460
|
v2_data_available: boolean;
|
|
389
461
|
workspace_root: string;
|
|
390
462
|
git_sha: string;
|
|
@@ -574,4 +646,5 @@ export interface SkillReportResponse extends SkillReportPayload, TrustFields {
|
|
|
574
646
|
not_just_name: number;
|
|
575
647
|
};
|
|
576
648
|
} | null;
|
|
649
|
+
testing_readiness?: SkillTestingReadiness;
|
|
577
650
|
}
|