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,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* skill-scaffold.ts
|
|
3
|
+
*
|
|
4
|
+
* Builds draft workflow skills from repeated telemetry-discovered workflows.
|
|
5
|
+
* The draft is preview-first by default so agents can review the scaffold before
|
|
6
|
+
* writing it into a local skill registry.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
|
|
11
|
+
import type { DiscoveredWorkflow } from "../types.js";
|
|
12
|
+
import { findGitRepositoryRoot } from "../utils/skill-discovery.js";
|
|
13
|
+
|
|
14
|
+
export interface WorkflowSkillDraft {
|
|
15
|
+
title: string;
|
|
16
|
+
skill_name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
output_dir: string;
|
|
19
|
+
skill_dir: string;
|
|
20
|
+
skill_path: string;
|
|
21
|
+
content: string;
|
|
22
|
+
source_workflow: {
|
|
23
|
+
workflow_id: string;
|
|
24
|
+
skills: string[];
|
|
25
|
+
occurrence_count: number;
|
|
26
|
+
synergy_score: number;
|
|
27
|
+
representative_query: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface WorkflowSkillDraftOptions {
|
|
32
|
+
outputDir?: string;
|
|
33
|
+
skillName?: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
cwd?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const STOPWORDS = new Set([
|
|
39
|
+
"a",
|
|
40
|
+
"an",
|
|
41
|
+
"and",
|
|
42
|
+
"for",
|
|
43
|
+
"from",
|
|
44
|
+
"in",
|
|
45
|
+
"into",
|
|
46
|
+
"of",
|
|
47
|
+
"on",
|
|
48
|
+
"or",
|
|
49
|
+
"the",
|
|
50
|
+
"to",
|
|
51
|
+
"with",
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
function splitWords(value: string): string[] {
|
|
55
|
+
return value
|
|
56
|
+
.replace(/[^A-Za-z0-9]+/g, " ")
|
|
57
|
+
.trim()
|
|
58
|
+
.split(/\s+/)
|
|
59
|
+
.filter(Boolean);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function titleCase(value: string): string {
|
|
63
|
+
return splitWords(value)
|
|
64
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
65
|
+
.join(" ");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function slugifyWorkflowSkillName(value: string): string {
|
|
69
|
+
return splitWords(value)
|
|
70
|
+
.map((word) => word.toLowerCase())
|
|
71
|
+
.join("-")
|
|
72
|
+
.replace(/-+/g, "-")
|
|
73
|
+
.replace(/^-|-$/g, "");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function deriveBaseLabel(workflow: DiscoveredWorkflow): string {
|
|
77
|
+
const filteredQueryWords = splitWords(workflow.representative_query).filter(
|
|
78
|
+
(word) => !STOPWORDS.has(word.toLowerCase()),
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (filteredQueryWords.length >= 2) {
|
|
82
|
+
return filteredQueryWords.slice(0, 5).join(" ");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return `${workflow.skills.join(" ")} workflow`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function formatList(items: string[]): string {
|
|
89
|
+
if (items.length === 0) return "";
|
|
90
|
+
if (items.length === 1) return items[0];
|
|
91
|
+
if (items.length === 2) return `${items[0]} and ${items[1]}`;
|
|
92
|
+
return `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function wrapFoldedScalar(value: string, width = 78): string[] {
|
|
96
|
+
const words = value.split(/\s+/).filter(Boolean);
|
|
97
|
+
const lines: string[] = [];
|
|
98
|
+
let current = "";
|
|
99
|
+
|
|
100
|
+
for (const word of words) {
|
|
101
|
+
const candidate = current.length === 0 ? word : `${current} ${word}`;
|
|
102
|
+
if (candidate.length > width && current.length > 0) {
|
|
103
|
+
lines.push(` ${current}`);
|
|
104
|
+
current = word;
|
|
105
|
+
} else {
|
|
106
|
+
current = candidate;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (current.length > 0) lines.push(` ${current}`);
|
|
111
|
+
return lines.length > 0 ? lines : [" "];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function getDefaultWorkflowSkillOutputDir(cwd: string = process.cwd()): string {
|
|
115
|
+
const repoRoot = findGitRepositoryRoot(cwd);
|
|
116
|
+
return join(repoRoot ?? cwd, ".agents", "skills");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function buildWorkflowSkillDescription(
|
|
120
|
+
workflow: DiscoveredWorkflow,
|
|
121
|
+
override?: string,
|
|
122
|
+
): string {
|
|
123
|
+
if (override && override.trim().length > 0) return override.trim();
|
|
124
|
+
|
|
125
|
+
const chain = formatList(workflow.skills);
|
|
126
|
+
const query = workflow.representative_query.trim();
|
|
127
|
+
if (query.length > 0) {
|
|
128
|
+
return `Use when the user wants to ${query}. Coordinates ${chain} in sequence.`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return `Use when the task consistently needs ${chain} in sequence.`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function buildWorkflowSkillContent(
|
|
135
|
+
workflow: DiscoveredWorkflow,
|
|
136
|
+
title: string,
|
|
137
|
+
skillName: string,
|
|
138
|
+
description: string,
|
|
139
|
+
): string {
|
|
140
|
+
const workflowName = title.endsWith("Workflow") ? title : `${title} Workflow`;
|
|
141
|
+
const chain = workflow.skills.join(" → ");
|
|
142
|
+
const query = workflow.representative_query.trim();
|
|
143
|
+
const foldedDescription = wrapFoldedScalar(description).join("\n");
|
|
144
|
+
|
|
145
|
+
const whenToUseLines =
|
|
146
|
+
query.length > 0
|
|
147
|
+
? [
|
|
148
|
+
`- The user asks to "${query}"`,
|
|
149
|
+
`- The request repeatedly needs this skill chain: ${chain}`,
|
|
150
|
+
]
|
|
151
|
+
: [`- The request repeatedly needs this skill chain: ${chain}`];
|
|
152
|
+
|
|
153
|
+
const executionPlanLines = workflow.skills.map(
|
|
154
|
+
(skill, index) =>
|
|
155
|
+
`${index + 1}. Invoke \`${skill}\` in its established role for this workflow.`,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
return `---
|
|
159
|
+
name: ${skillName}
|
|
160
|
+
description: >
|
|
161
|
+
${foldedDescription}
|
|
162
|
+
metadata:
|
|
163
|
+
author: selftune-autogen
|
|
164
|
+
version: 0.1.0
|
|
165
|
+
category: developer-tools
|
|
166
|
+
generated_by: selftune workflows scaffold
|
|
167
|
+
source_workflow_id: ${workflow.workflow_id}
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
# ${title}
|
|
171
|
+
|
|
172
|
+
This draft skill was scaffolded by selftune from repeated workflow telemetry.
|
|
173
|
+
Review the routing language and execution notes before broad distribution.
|
|
174
|
+
|
|
175
|
+
## When to Use
|
|
176
|
+
|
|
177
|
+
${whenToUseLines.join("\n")}
|
|
178
|
+
|
|
179
|
+
## Execution Plan
|
|
180
|
+
|
|
181
|
+
${executionPlanLines.join("\n")}
|
|
182
|
+
|
|
183
|
+
## Workflows
|
|
184
|
+
|
|
185
|
+
### ${workflowName}
|
|
186
|
+
- **Skills:** ${chain}
|
|
187
|
+
${query.length > 0 ? `- **Trigger:** ${query}\n` : ""}- **Source:** Discovered from ${workflow.occurrence_count} sessions (synergy: ${workflow.synergy_score.toFixed(2)})
|
|
188
|
+
|
|
189
|
+
## Notes
|
|
190
|
+
|
|
191
|
+
- This is a proposal scaffold, not a silently published marketplace skill.
|
|
192
|
+
- Add tighter scope boundaries and richer examples before publishing.
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function buildWorkflowSkillDraft(
|
|
197
|
+
workflow: DiscoveredWorkflow,
|
|
198
|
+
options: WorkflowSkillDraftOptions = {},
|
|
199
|
+
): WorkflowSkillDraft {
|
|
200
|
+
const baseLabel = options.skillName?.trim() || deriveBaseLabel(workflow);
|
|
201
|
+
const skillName = slugifyWorkflowSkillName(baseLabel);
|
|
202
|
+
const title = titleCase(baseLabel) || titleCase(`${workflow.skills.join(" ")} workflow`);
|
|
203
|
+
const description = buildWorkflowSkillDescription(workflow, options.description);
|
|
204
|
+
const outputDir = options.outputDir?.trim() || getDefaultWorkflowSkillOutputDir(options.cwd);
|
|
205
|
+
const skillDir = join(outputDir, skillName);
|
|
206
|
+
const skillPath = join(skillDir, "SKILL.md");
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
title,
|
|
210
|
+
skill_name: skillName,
|
|
211
|
+
description,
|
|
212
|
+
output_dir: outputDir,
|
|
213
|
+
skill_dir: skillDir,
|
|
214
|
+
skill_path: skillPath,
|
|
215
|
+
content: buildWorkflowSkillContent(workflow, title, skillName, description),
|
|
216
|
+
source_workflow: {
|
|
217
|
+
workflow_id: workflow.workflow_id,
|
|
218
|
+
skills: workflow.skills,
|
|
219
|
+
occurrence_count: workflow.occurrence_count,
|
|
220
|
+
synergy_score: workflow.synergy_score,
|
|
221
|
+
representative_query: workflow.representative_query,
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function formatWorkflowSkillDraft(draft: WorkflowSkillDraft): string {
|
|
227
|
+
const lines = [
|
|
228
|
+
`Draft workflow skill: ${draft.title}`,
|
|
229
|
+
`Skill name: ${draft.skill_name}`,
|
|
230
|
+
`Output path: ${draft.skill_path}`,
|
|
231
|
+
`Source workflow: ${draft.source_workflow.workflow_id}`,
|
|
232
|
+
`Occurrences: ${draft.source_workflow.occurrence_count} | Synergy: ${draft.source_workflow.synergy_score.toFixed(2)}`,
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
if (draft.source_workflow.representative_query.trim().length > 0) {
|
|
236
|
+
lines.push(`Representative query: "${draft.source_workflow.representative_query.trim()}"`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
lines.push("", draft.content.trimEnd());
|
|
240
|
+
return lines.join("\n");
|
|
241
|
+
}
|
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
* - cliMain() (reads logs, discovers workflows, prints output or saves)
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
12
12
|
import { parseArgs } from "node:util";
|
|
13
13
|
|
|
14
14
|
import { getDb } from "../localdb/db.js";
|
|
15
15
|
import { querySessionTelemetry, querySkillUsageRecords } from "../localdb/queries.js";
|
|
16
16
|
import type {
|
|
17
17
|
CodifiedWorkflow,
|
|
18
|
+
DiscoveredWorkflow,
|
|
18
19
|
SessionTelemetryRecord,
|
|
19
20
|
SkillUsageRecord,
|
|
20
21
|
WorkflowDiscoveryReport,
|
|
@@ -22,6 +23,38 @@ import type {
|
|
|
22
23
|
import { CLIError } from "../utils/cli-error.js";
|
|
23
24
|
import { discoverWorkflows } from "./discover.js";
|
|
24
25
|
import { appendWorkflow } from "./skill-md-writer.js";
|
|
26
|
+
import { buildWorkflowSkillDraft, formatWorkflowSkillDraft } from "./skill-scaffold.js";
|
|
27
|
+
|
|
28
|
+
function resolveWorkflowSelection(
|
|
29
|
+
report: WorkflowDiscoveryReport,
|
|
30
|
+
selection: string | undefined,
|
|
31
|
+
): DiscoveredWorkflow {
|
|
32
|
+
if (!selection) {
|
|
33
|
+
throw new CLIError(
|
|
34
|
+
"Usage: selftune workflows <save|scaffold> <name-or-index>",
|
|
35
|
+
"MISSING_FLAG",
|
|
36
|
+
"Provide a workflow name or index (e.g., selftune workflows scaffold 1).",
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let workflow = report.workflows.find((w) => w.workflow_id === selection);
|
|
41
|
+
if (!workflow) {
|
|
42
|
+
const idx = Number.parseInt(selection, 10);
|
|
43
|
+
if (!Number.isNaN(idx) && idx >= 1 && idx <= report.workflows.length) {
|
|
44
|
+
workflow = report.workflows[idx - 1];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!workflow) {
|
|
49
|
+
throw new CLIError(
|
|
50
|
+
`No workflow found matching "${selection}".`,
|
|
51
|
+
"INVALID_FLAG",
|
|
52
|
+
"Run 'selftune workflows' to see discovered workflows and their indices.",
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return workflow;
|
|
57
|
+
}
|
|
25
58
|
|
|
26
59
|
// ---------------------------------------------------------------------------
|
|
27
60
|
// formatWorkflows — pure formatter
|
|
@@ -69,12 +102,41 @@ export async function cliMain(): Promise<void> {
|
|
|
69
102
|
window: { type: "string" },
|
|
70
103
|
skill: { type: "string" },
|
|
71
104
|
"skill-path": { type: "string" },
|
|
105
|
+
"output-dir": { type: "string" },
|
|
106
|
+
"skill-name": { type: "string" },
|
|
107
|
+
description: { type: "string" },
|
|
108
|
+
write: { type: "boolean" },
|
|
109
|
+
force: { type: "boolean" },
|
|
72
110
|
json: { type: "boolean" },
|
|
111
|
+
help: { type: "boolean", short: "h" },
|
|
73
112
|
},
|
|
74
113
|
strict: true,
|
|
75
114
|
allowPositionals: true,
|
|
76
115
|
});
|
|
77
116
|
|
|
117
|
+
if (values.help) {
|
|
118
|
+
console.log(`selftune workflows — Discover repeated multi-skill patterns
|
|
119
|
+
|
|
120
|
+
Usage:
|
|
121
|
+
selftune workflows [options]
|
|
122
|
+
selftune workflows save <name-or-index> [--skill-path <path>]
|
|
123
|
+
selftune workflows scaffold <name-or-index> [--output-dir <path>] [--skill-name <name>] [--description <text>] [--write] [--force] [--json]
|
|
124
|
+
|
|
125
|
+
Options:
|
|
126
|
+
--min-occurrences <n> Minimum workflow frequency to show (default: 3)
|
|
127
|
+
--window <n> Only analyze the most recent N sessions
|
|
128
|
+
--skill <name> Only show workflows containing the named skill
|
|
129
|
+
--skill-path <path> Target SKILL.md for the save subcommand
|
|
130
|
+
--output-dir <path> Target skill registry dir for scaffold previews/writes
|
|
131
|
+
--skill-name <name> Override the generated draft skill name
|
|
132
|
+
--description <text> Override the generated draft skill description
|
|
133
|
+
--write Persist the scaffolded draft skill to disk
|
|
134
|
+
--force Overwrite an existing scaffold path when combined with --write
|
|
135
|
+
--json Emit machine-readable JSON
|
|
136
|
+
-h, --help Show this help message`);
|
|
137
|
+
process.exit(0);
|
|
138
|
+
}
|
|
139
|
+
|
|
78
140
|
const subcommand = positionals[0];
|
|
79
141
|
const minOccurrences = values["min-occurrences"]
|
|
80
142
|
? Number.parseInt(values["min-occurrences"], 10)
|
|
@@ -101,31 +163,7 @@ export async function cliMain(): Promise<void> {
|
|
|
101
163
|
|
|
102
164
|
if (subcommand === "save") {
|
|
103
165
|
// Save subcommand: find workflow, append to SKILL.md
|
|
104
|
-
const
|
|
105
|
-
if (!nameArg) {
|
|
106
|
-
throw new CLIError(
|
|
107
|
-
"Usage: selftune workflows save <name-or-index>",
|
|
108
|
-
"MISSING_FLAG",
|
|
109
|
-
"Provide a workflow name or index (e.g., selftune workflows save 1).",
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Match by numeric index (1-based) or workflow_id
|
|
114
|
-
let workflow = report.workflows.find((w) => w.workflow_id === nameArg);
|
|
115
|
-
if (!workflow) {
|
|
116
|
-
const idx = Number.parseInt(nameArg, 10);
|
|
117
|
-
if (!Number.isNaN(idx) && idx >= 1 && idx <= report.workflows.length) {
|
|
118
|
-
workflow = report.workflows[idx - 1];
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (!workflow) {
|
|
123
|
-
throw new CLIError(
|
|
124
|
-
`No workflow found matching "${nameArg}".`,
|
|
125
|
-
"INVALID_FLAG",
|
|
126
|
-
"Run 'selftune workflows' to see discovered workflows and their indices.",
|
|
127
|
-
);
|
|
128
|
-
}
|
|
166
|
+
const workflow = resolveWorkflowSelection(report, positionals[1]);
|
|
129
167
|
|
|
130
168
|
// Determine SKILL.md path
|
|
131
169
|
let skillPath = values["skill-path"];
|
|
@@ -187,6 +225,42 @@ export async function cliMain(): Promise<void> {
|
|
|
187
225
|
return;
|
|
188
226
|
}
|
|
189
227
|
|
|
228
|
+
if (subcommand === "scaffold") {
|
|
229
|
+
const workflow = resolveWorkflowSelection(report, positionals[1]);
|
|
230
|
+
const draft = buildWorkflowSkillDraft(workflow, {
|
|
231
|
+
outputDir: values["output-dir"],
|
|
232
|
+
skillName: values["skill-name"],
|
|
233
|
+
description: values.description,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
if (values.write) {
|
|
237
|
+
if (existsSync(draft.skill_path) && !values.force) {
|
|
238
|
+
throw new CLIError(
|
|
239
|
+
`Refusing to overwrite existing draft at ${draft.skill_path}.`,
|
|
240
|
+
"FILE_EXISTS",
|
|
241
|
+
"Re-run with --force to overwrite the existing draft skill.",
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
mkdirSync(draft.skill_dir, { recursive: true });
|
|
246
|
+
writeFileSync(draft.skill_path, draft.content, "utf-8");
|
|
247
|
+
|
|
248
|
+
if (values.json || !process.stdout.isTTY) {
|
|
249
|
+
console.log(JSON.stringify({ ...draft, written: true }, null, 2));
|
|
250
|
+
} else {
|
|
251
|
+
console.log(`Scaffolded skill "${draft.skill_name}" to ${draft.skill_path}`);
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (values.json || !process.stdout.isTTY) {
|
|
257
|
+
console.log(JSON.stringify({ ...draft, written: false }, null, 2));
|
|
258
|
+
} else {
|
|
259
|
+
console.log(formatWorkflowSkillDraft(draft));
|
|
260
|
+
}
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
190
264
|
// Default: discover and display
|
|
191
265
|
if (values.json || !process.stdout.isTTY) {
|
|
192
266
|
console.log(JSON.stringify(report, null, 2));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PushPayloadV2 } from "../src/
|
|
1
|
+
import type { PushPayloadV2 } from "../src/types.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A valid PushPayloadV2 with only evolution_evidence entries and
|
|
@@ -7,7 +7,7 @@ import type { PushPayloadV2 } from "../src/schemas.js";
|
|
|
7
7
|
export const evidenceOnlyPush: PushPayloadV2 = {
|
|
8
8
|
schema_version: "2.0",
|
|
9
9
|
client_version: "0.9.0",
|
|
10
|
-
push_id: "d4e5f6a7-b8c9-
|
|
10
|
+
push_id: "d4e5f6a7-b8c9-8123-9efa-234567890123",
|
|
11
11
|
normalizer_version: "0.2.1",
|
|
12
12
|
canonical: {
|
|
13
13
|
sessions: [],
|
package/node_modules/@selftune/telemetry-contract/fixtures/partial-push-unresolved-parents.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PushPayloadV2 } from "../src/
|
|
1
|
+
import type { PushPayloadV2 } from "../src/types.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A valid PushPayloadV2 with invocations and prompts that reference a
|
|
@@ -10,7 +10,7 @@ import type { PushPayloadV2 } from "../src/schemas.js";
|
|
|
10
10
|
export const partialPushUnresolvedParents: PushPayloadV2 = {
|
|
11
11
|
schema_version: "2.0",
|
|
12
12
|
client_version: "0.9.0",
|
|
13
|
-
push_id: "c3d4e5f6-a7b8-
|
|
13
|
+
push_id: "c3d4e5f6-a7b8-8012-8def-123456789012",
|
|
14
14
|
normalizer_version: "0.2.1",
|
|
15
15
|
canonical: {
|
|
16
16
|
sessions: [],
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": "./index.ts",
|
|
16
|
-
"./schemas": "./src/schemas.ts",
|
|
17
16
|
"./types": "./src/types.ts",
|
|
18
17
|
"./validators": "./src/validators.ts",
|
|
18
|
+
"./schemas": "./src/schemas.ts",
|
|
19
19
|
"./fixtures": "./fixtures/index.ts"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Zod validation schemas for all canonical telemetry record types
|
|
3
|
+
* and the PushPayloadV2 envelope.
|
|
4
|
+
*
|
|
5
|
+
* This is the single source of truth -- cloud consumers should import
|
|
6
|
+
* from @selftune/telemetry-contract/schemas instead of maintaining
|
|
7
|
+
* their own copies.
|
|
8
|
+
*/
|
|
2
9
|
|
|
10
|
+
import { z } from "zod";
|
|
3
11
|
import {
|
|
4
12
|
CANONICAL_CAPTURE_MODES,
|
|
5
13
|
CANONICAL_COMPLETION_STATUSES,
|
|
@@ -11,6 +19,8 @@ import {
|
|
|
11
19
|
CANONICAL_SOURCE_SESSION_KINDS,
|
|
12
20
|
} from "./types.js";
|
|
13
21
|
|
|
22
|
+
// ---------- Shared enum schemas ----------
|
|
23
|
+
|
|
14
24
|
export const canonicalPlatformSchema = z.enum(CANONICAL_PLATFORMS);
|
|
15
25
|
export const captureModeSchema = z.enum(CANONICAL_CAPTURE_MODES);
|
|
16
26
|
export const sourceSessionKindSchema = z.enum(CANONICAL_SOURCE_SESSION_KINDS);
|
|
@@ -19,6 +29,8 @@ export const invocationModeSchema = z.enum(CANONICAL_INVOCATION_MODES);
|
|
|
19
29
|
export const completionStatusSchema = z.enum(CANONICAL_COMPLETION_STATUSES);
|
|
20
30
|
export const recordKindSchema = z.enum(CANONICAL_RECORD_KINDS);
|
|
21
31
|
|
|
32
|
+
// ---------- Shared structural schemas ----------
|
|
33
|
+
|
|
22
34
|
export const rawSourceRefSchema = z.object({
|
|
23
35
|
path: z.string().optional(),
|
|
24
36
|
line: z.number().int().nonnegative().optional(),
|
|
@@ -42,6 +54,8 @@ export const canonicalSessionRecordBaseSchema = canonicalRecordBaseSchema.extend
|
|
|
42
54
|
session_id: z.string().min(1),
|
|
43
55
|
});
|
|
44
56
|
|
|
57
|
+
// ---------- Canonical record schemas ----------
|
|
58
|
+
|
|
45
59
|
export const CanonicalSessionRecordSchema = canonicalSessionRecordBaseSchema.extend({
|
|
46
60
|
record_kind: z.literal("session"),
|
|
47
61
|
external_session_id: z.string().optional(),
|
|
@@ -126,10 +140,13 @@ export const CanonicalEvolutionEvidenceRecordSchema = z.object({
|
|
|
126
140
|
evidence_id: z.string().min(1),
|
|
127
141
|
skill_name: z.string().min(1),
|
|
128
142
|
proposal_id: z.string().optional(),
|
|
143
|
+
timestamp: z.string().datetime().optional(),
|
|
144
|
+
skill_path: z.string().optional(),
|
|
129
145
|
target: z.string().min(1),
|
|
130
146
|
stage: z.string().min(1),
|
|
131
147
|
rationale: z.string().optional(),
|
|
132
148
|
confidence: z.number().min(0).max(1).optional(),
|
|
149
|
+
details: z.string().optional(),
|
|
133
150
|
original_text: z.string().optional(),
|
|
134
151
|
proposed_text: z.string().optional(),
|
|
135
152
|
eval_set_json: z.unknown().optional(),
|
|
@@ -137,6 +154,39 @@ export const CanonicalEvolutionEvidenceRecordSchema = z.object({
|
|
|
137
154
|
raw_source_ref: rawSourceRefSchema.optional(),
|
|
138
155
|
});
|
|
139
156
|
|
|
157
|
+
export const CanonicalGradingResultRecordSchema = z.object({
|
|
158
|
+
grading_id: z.string().min(1),
|
|
159
|
+
session_id: z.string().min(1),
|
|
160
|
+
skill_name: z.string().min(1),
|
|
161
|
+
transcript_path: z.string().nullable().optional(),
|
|
162
|
+
graded_at: z.string().min(1),
|
|
163
|
+
pass_rate: z.number().min(0).max(1).nullable().optional(),
|
|
164
|
+
mean_score: z.number().min(0).max(1).nullable().optional(),
|
|
165
|
+
score_std_dev: z.number().nullable().optional(),
|
|
166
|
+
passed_count: z.number().int().nonnegative().nullable().optional(),
|
|
167
|
+
failed_count: z.number().int().nonnegative().nullable().optional(),
|
|
168
|
+
total_count: z.number().int().nonnegative().nullable().optional(),
|
|
169
|
+
expectations_json: z.string().nullable().optional(),
|
|
170
|
+
claims_json: z.string().nullable().optional(),
|
|
171
|
+
eval_feedback_json: z.string().nullable().optional(),
|
|
172
|
+
failure_feedback_json: z.string().nullable().optional(),
|
|
173
|
+
execution_metrics_json: z.string().nullable().optional(),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
export const CanonicalImprovementSignalRecordSchema = z.object({
|
|
177
|
+
signal_id: z.string().min(1),
|
|
178
|
+
timestamp: z.string().min(1),
|
|
179
|
+
session_id: z.string().min(1),
|
|
180
|
+
query: z.string().min(1),
|
|
181
|
+
signal_type: z.string().min(1),
|
|
182
|
+
mentioned_skill: z.string().nullable().optional(),
|
|
183
|
+
consumed: z.boolean(),
|
|
184
|
+
consumed_at: z.string().nullable().optional(),
|
|
185
|
+
consumed_by_run: z.string().nullable().optional(),
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// ---------- Orchestrate run schemas ----------
|
|
189
|
+
|
|
140
190
|
export const OrchestrateRunSkillActionSchema = z.object({
|
|
141
191
|
skill: z.string().min(1),
|
|
142
192
|
action: z.enum(["evolve", "watch", "skip"]),
|
|
@@ -163,12 +213,12 @@ export const PushOrchestrateRunRecordSchema = z.object({
|
|
|
163
213
|
skill_actions: z.array(OrchestrateRunSkillActionSchema),
|
|
164
214
|
});
|
|
165
215
|
|
|
216
|
+
// ---------- Push V2 envelope ----------
|
|
217
|
+
|
|
166
218
|
export const PushPayloadV2Schema = z.object({
|
|
167
219
|
schema_version: z.literal("2.0"),
|
|
168
220
|
client_version: z.string().min(1),
|
|
169
|
-
|
|
170
|
-
// requires a stable non-empty idempotency key.
|
|
171
|
-
push_id: z.string().min(1),
|
|
221
|
+
push_id: z.string().uuid(),
|
|
172
222
|
normalizer_version: z.string().min(1),
|
|
173
223
|
canonical: z.object({
|
|
174
224
|
sessions: z.array(CanonicalSessionRecordSchema).min(0),
|
|
@@ -178,10 +228,14 @@ export const PushPayloadV2Schema = z.object({
|
|
|
178
228
|
normalization_runs: z.array(CanonicalNormalizationRunRecordSchema).min(0),
|
|
179
229
|
evolution_evidence: z.array(CanonicalEvolutionEvidenceRecordSchema).optional(),
|
|
180
230
|
orchestrate_runs: z.array(PushOrchestrateRunRecordSchema).optional(),
|
|
231
|
+
grading_results: z.array(CanonicalGradingResultRecordSchema).optional(),
|
|
232
|
+
improvement_signals: z.array(CanonicalImprovementSignalRecordSchema).optional(),
|
|
181
233
|
}),
|
|
182
234
|
});
|
|
183
235
|
|
|
184
|
-
|
|
236
|
+
// ---------- Inferred types from Zod schemas ----------
|
|
237
|
+
|
|
238
|
+
export type ZodPushPayloadV2 = z.infer<typeof PushPayloadV2Schema>;
|
|
185
239
|
export type ZodCanonicalSessionRecord = z.infer<typeof CanonicalSessionRecordSchema>;
|
|
186
240
|
export type ZodCanonicalPromptRecord = z.infer<typeof CanonicalPromptRecordSchema>;
|
|
187
241
|
export type ZodCanonicalSkillInvocationRecord = z.infer<
|
|
@@ -194,4 +248,8 @@ export type ZodCanonicalNormalizationRunRecord = z.infer<
|
|
|
194
248
|
export type ZodCanonicalEvolutionEvidenceRecord = z.infer<
|
|
195
249
|
typeof CanonicalEvolutionEvidenceRecordSchema
|
|
196
250
|
>;
|
|
251
|
+
export type ZodCanonicalGradingResultRecord = z.infer<typeof CanonicalGradingResultRecordSchema>;
|
|
252
|
+
export type ZodCanonicalImprovementSignalRecord = z.infer<
|
|
253
|
+
typeof CanonicalImprovementSignalRecordSchema
|
|
254
|
+
>;
|
|
197
255
|
export type ZodPushOrchestrateRunRecord = z.infer<typeof PushOrchestrateRunRecordSchema>;
|