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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const CANONICAL_SCHEMA_VERSION = "2.0" as const;
|
|
2
2
|
export type CanonicalSchemaVersion = typeof CANONICAL_SCHEMA_VERSION;
|
|
3
3
|
|
|
4
|
-
export const CANONICAL_PLATFORMS = ["claude_code", "codex", "opencode", "openclaw"] as const;
|
|
4
|
+
export const CANONICAL_PLATFORMS = ["claude_code", "codex", "opencode", "openclaw", "pi"] as const;
|
|
5
5
|
export type CanonicalPlatform = (typeof CANONICAL_PLATFORMS)[number];
|
|
6
6
|
|
|
7
7
|
export const CANONICAL_CAPTURE_MODES = [
|
|
@@ -54,7 +54,7 @@ export const CANONICAL_RECORD_KINDS = [
|
|
|
54
54
|
] as const;
|
|
55
55
|
export type CanonicalRecordKind = (typeof CANONICAL_RECORD_KINDS)[number];
|
|
56
56
|
|
|
57
|
-
export interface CanonicalRawSourceRef {
|
|
57
|
+
export interface CanonicalRawSourceRef extends Record<string, unknown> {
|
|
58
58
|
path?: string;
|
|
59
59
|
line?: number;
|
|
60
60
|
event_type?: string;
|
|
@@ -62,7 +62,7 @@ export interface CanonicalRawSourceRef {
|
|
|
62
62
|
metadata?: Record<string, unknown>;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
export interface CanonicalRecordBase {
|
|
65
|
+
export interface CanonicalRecordBase extends Record<string, unknown> {
|
|
66
66
|
record_kind: CanonicalRecordKind;
|
|
67
67
|
schema_version: CanonicalSchemaVersion;
|
|
68
68
|
normalizer_version: string;
|
|
@@ -146,15 +146,14 @@ export interface CanonicalExecutionFactRecord extends CanonicalSessionRecordBase
|
|
|
146
146
|
cached_input_tokens?: number;
|
|
147
147
|
reasoning_output_tokens?: number;
|
|
148
148
|
cost_usd?: number;
|
|
149
|
-
duration_ms?: number;
|
|
150
149
|
files_changed?: number;
|
|
151
150
|
lines_added?: number;
|
|
152
151
|
lines_removed?: number;
|
|
153
152
|
lines_modified?: number;
|
|
154
|
-
/** Count of output-producing tool calls (Write, Edit, WebFetch, WebSearch, Skill, Agent). */
|
|
155
153
|
artifact_count?: number;
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
session_type?: string;
|
|
155
|
+
agent_summary?: string;
|
|
156
|
+
duration_ms?: number;
|
|
158
157
|
completion_status?: CanonicalCompletionStatus;
|
|
159
158
|
end_reason?: string;
|
|
160
159
|
}
|
|
@@ -168,9 +167,100 @@ export interface CanonicalNormalizationRunRecord extends CanonicalRecordBase {
|
|
|
168
167
|
repair_applied: boolean;
|
|
169
168
|
}
|
|
170
169
|
|
|
170
|
+
export interface CanonicalEvolutionEvidenceRecord {
|
|
171
|
+
evidence_id?: string;
|
|
172
|
+
timestamp?: string;
|
|
173
|
+
proposal_id?: string;
|
|
174
|
+
skill_name: string;
|
|
175
|
+
skill_path?: string;
|
|
176
|
+
target: string;
|
|
177
|
+
stage: string;
|
|
178
|
+
rationale?: string;
|
|
179
|
+
confidence?: number;
|
|
180
|
+
details?: string;
|
|
181
|
+
original_text?: string;
|
|
182
|
+
proposed_text?: string;
|
|
183
|
+
eval_set_json?: unknown;
|
|
184
|
+
validation_json?: unknown;
|
|
185
|
+
raw_source_ref?: CanonicalRawSourceRef;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface CanonicalGradingResultRecord {
|
|
189
|
+
grading_id: string;
|
|
190
|
+
session_id: string;
|
|
191
|
+
skill_name: string;
|
|
192
|
+
transcript_path?: string | null;
|
|
193
|
+
graded_at: string;
|
|
194
|
+
pass_rate?: number | null;
|
|
195
|
+
mean_score?: number | null;
|
|
196
|
+
score_std_dev?: number | null;
|
|
197
|
+
passed_count?: number | null;
|
|
198
|
+
failed_count?: number | null;
|
|
199
|
+
total_count?: number | null;
|
|
200
|
+
expectations_json?: string | null;
|
|
201
|
+
claims_json?: string | null;
|
|
202
|
+
eval_feedback_json?: string | null;
|
|
203
|
+
failure_feedback_json?: string | null;
|
|
204
|
+
execution_metrics_json?: string | null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface CanonicalImprovementSignalRecord {
|
|
208
|
+
signal_id: string;
|
|
209
|
+
timestamp: string;
|
|
210
|
+
session_id: string;
|
|
211
|
+
query: string;
|
|
212
|
+
signal_type: string;
|
|
213
|
+
mentioned_skill?: string | null;
|
|
214
|
+
consumed: boolean;
|
|
215
|
+
consumed_at?: string | null;
|
|
216
|
+
consumed_by_run?: string | null;
|
|
217
|
+
}
|
|
218
|
+
|
|
171
219
|
export type CanonicalRecord =
|
|
172
220
|
| CanonicalSessionRecord
|
|
173
221
|
| CanonicalPromptRecord
|
|
174
222
|
| CanonicalSkillInvocationRecord
|
|
175
223
|
| CanonicalExecutionFactRecord
|
|
176
224
|
| CanonicalNormalizationRunRecord;
|
|
225
|
+
|
|
226
|
+
export interface PushOrchestrateRunRecord {
|
|
227
|
+
run_id: string;
|
|
228
|
+
timestamp: string;
|
|
229
|
+
elapsed_ms: number;
|
|
230
|
+
dry_run: boolean;
|
|
231
|
+
approval_mode: "auto" | "review";
|
|
232
|
+
total_skills: number;
|
|
233
|
+
evaluated: number;
|
|
234
|
+
evolved: number;
|
|
235
|
+
deployed: number;
|
|
236
|
+
watched: number;
|
|
237
|
+
skipped: number;
|
|
238
|
+
skill_actions: Array<{
|
|
239
|
+
skill: string;
|
|
240
|
+
action: "evolve" | "watch" | "skip";
|
|
241
|
+
reason: string;
|
|
242
|
+
deployed?: boolean;
|
|
243
|
+
rolledBack?: boolean;
|
|
244
|
+
alert?: string | null;
|
|
245
|
+
elapsed_ms?: number;
|
|
246
|
+
llm_calls?: number;
|
|
247
|
+
}>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface PushPayloadV2 {
|
|
251
|
+
schema_version: CanonicalSchemaVersion;
|
|
252
|
+
client_version: string;
|
|
253
|
+
push_id: string;
|
|
254
|
+
normalizer_version: string;
|
|
255
|
+
canonical: {
|
|
256
|
+
sessions: CanonicalSessionRecord[];
|
|
257
|
+
prompts: CanonicalPromptRecord[];
|
|
258
|
+
skill_invocations: CanonicalSkillInvocationRecord[];
|
|
259
|
+
execution_facts: CanonicalExecutionFactRecord[];
|
|
260
|
+
normalization_runs: CanonicalNormalizationRunRecord[];
|
|
261
|
+
evolution_evidence?: CanonicalEvolutionEvidenceRecord[];
|
|
262
|
+
orchestrate_runs?: PushOrchestrateRunRecord[];
|
|
263
|
+
grading_results?: CanonicalGradingResultRecord[];
|
|
264
|
+
improvement_signals?: CanonicalImprovementSignalRecord[];
|
|
265
|
+
};
|
|
266
|
+
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "selftune",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.24",
|
|
4
|
+
"description": "Skill-level observability and self-improvement for AI agents — monitors skill routing, detects missed triggers, and evolves descriptions automatically",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
7
|
+
"agent-skills",
|
|
8
|
+
"ai-agent",
|
|
9
|
+
"ai-observability",
|
|
7
10
|
"bun",
|
|
8
11
|
"claude-code",
|
|
9
12
|
"cli",
|
|
13
|
+
"cline",
|
|
10
14
|
"codex",
|
|
11
15
|
"eval",
|
|
16
|
+
"evals",
|
|
12
17
|
"evolution",
|
|
13
18
|
"grading",
|
|
19
|
+
"llm",
|
|
20
|
+
"observability",
|
|
14
21
|
"opencode",
|
|
15
22
|
"self-improving",
|
|
16
23
|
"selftune",
|
|
17
24
|
"skill",
|
|
25
|
+
"skill-evals",
|
|
26
|
+
"skill-observability",
|
|
27
|
+
"skill-routing",
|
|
28
|
+
"skill-testing",
|
|
18
29
|
"telemetry",
|
|
19
30
|
"typescript"
|
|
20
31
|
],
|
|
21
|
-
"homepage": "https://
|
|
32
|
+
"homepage": "https://selftune.dev",
|
|
22
33
|
"bugs": {
|
|
23
34
|
"url": "https://github.com/selftune-dev/selftune/issues"
|
|
24
35
|
},
|
|
@@ -44,6 +55,7 @@
|
|
|
44
55
|
"bin/",
|
|
45
56
|
"cli/selftune/",
|
|
46
57
|
"apps/local-dashboard/dist/",
|
|
58
|
+
"packages/dashboard-core/",
|
|
47
59
|
"packages/telemetry-contract/",
|
|
48
60
|
"packages/ui/",
|
|
49
61
|
"templates/",
|
|
@@ -53,9 +65,9 @@
|
|
|
53
65
|
],
|
|
54
66
|
"type": "module",
|
|
55
67
|
"scripts": {
|
|
56
|
-
"dev": "
|
|
57
|
-
"dev:server": "bun --watch run cli/selftune/dashboard-server.ts --port
|
|
58
|
-
"dev:dashboard": "bun run cli/selftune/index.ts dashboard --port
|
|
68
|
+
"dev": "cd apps/local-dashboard && bun run dev",
|
|
69
|
+
"dev:server": "sh -c 'dashboard_port=${DASHBOARD_PORT:-7888}; bun --watch run cli/selftune/dashboard-server.ts --port $dashboard_port --runtime-mode dev-server'",
|
|
70
|
+
"dev:dashboard": "sh -c 'dashboard_port=${DASHBOARD_PORT:-7888}; bun run cli/selftune/index.ts dashboard --port $dashboard_port --no-open'",
|
|
59
71
|
"lint": "bunx oxlint",
|
|
60
72
|
"lint:fix": "bunx oxlint --fix",
|
|
61
73
|
"format": "bunx oxfmt",
|
|
@@ -71,17 +83,21 @@
|
|
|
71
83
|
"sync-version": "bun run scripts/sync-skill-version.ts",
|
|
72
84
|
"validate:subagents": "bun run scripts/validate-subagent-docs.ts",
|
|
73
85
|
"prepublishOnly": "bun run sync-version && bun run build:dashboard",
|
|
86
|
+
"typecheck:runtime": "bunx tsc --noEmit -p tsconfig.runtime.json",
|
|
74
87
|
"typecheck:dashboard": "cd apps/local-dashboard && bunx tsc --noEmit",
|
|
75
|
-
"check": "bun run lint && bun run format:check && bun run lint:arch && bun run typecheck:dashboard && bun run test",
|
|
88
|
+
"check": "bun run lint && bun run format:check && bun run lint:arch && bun run typecheck:runtime && bun run typecheck:dashboard && bun run test",
|
|
76
89
|
"prepare": "bunx lefthook install || true",
|
|
77
90
|
"start": "bun run cli/selftune/index.ts --help"
|
|
78
91
|
},
|
|
79
92
|
"dependencies": {
|
|
80
|
-
"@selftune/telemetry-contract": "file:packages/telemetry-contract"
|
|
93
|
+
"@selftune/telemetry-contract": "file:packages/telemetry-contract",
|
|
94
|
+
"react-markdown": "^10.1.0",
|
|
95
|
+
"zod": "^4.3.6"
|
|
81
96
|
},
|
|
82
97
|
"devDependencies": {
|
|
83
98
|
"@evilmartians/lefthook": "^1.13.6",
|
|
84
|
-
"@types/bun": "^1.
|
|
99
|
+
"@types/bun": "^1.3.11",
|
|
100
|
+
"bun-types": "^1.3.11",
|
|
85
101
|
"oxfmt": "^0.41.0",
|
|
86
102
|
"oxlint": "^1.56.0"
|
|
87
103
|
},
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @selftune/dashboard-core
|
|
2
|
+
|
|
3
|
+
Shared dashboard application layer used by both the cloud dashboard and the local OSS dashboard. Canonical copy lives here; synced to `oss/selftune/packages/dashboard-core` via `scripts/sync-embedded-shared.sh`.
|
|
4
|
+
|
|
5
|
+
| Directory | Contents |
|
|
6
|
+
|-----------|----------|
|
|
7
|
+
| `src/host/` | Capability model, host adapter contracts, provider/context hooks |
|
|
8
|
+
| `src/models/` | Normalized view models shared across hosts |
|
|
9
|
+
| `src/routes/` | Route definition and route access helpers |
|
|
10
|
+
| `src/chrome/` | Shared shell, sidebar, header, runtime badge, and chrome types |
|
|
11
|
+
| `src/gates/` | Shared feature gates, locked-route surfaces, and upgrade CTAs |
|
|
12
|
+
| `src/screens/` | Shared screen implementations; analytics, the overview autonomy/comparison/support surfaces, skills library, and the skill report scaffold/trust chrome are extracted |
|
|
13
|
+
|
|
14
|
+
**Exports:** `.`, `./host`, `./models`, `./routes`, `./chrome`, `./gates`, `./screens`
|
|
15
|
+
|
|
16
|
+
**Dependencies:** `@selftune/ui`, `lucide-react`, `react` (peer), `react-dom` (peer)
|
|
17
|
+
|
|
18
|
+
**Important:** Do NOT edit `oss/selftune/packages/dashboard-core/` directly. Edit here and run `scripts/sync-embedded-shared.sh`.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @selftune/dashboard-core
|
|
2
|
+
|
|
3
|
+
Shared dashboard application layer for SelfTune cloud and local hosts.
|
|
4
|
+
|
|
5
|
+
This package owns:
|
|
6
|
+
|
|
7
|
+
- capability and entitlement contracts
|
|
8
|
+
- host adapter interfaces
|
|
9
|
+
- normalized dashboard view models
|
|
10
|
+
- shared route definition helpers
|
|
11
|
+
- shared dashboard chrome primitives used by cloud and local hosts
|
|
12
|
+
- shared feature gates and locked-route upgrade surfaces
|
|
13
|
+
- shared screen implementations, including analytics, the overview autonomy/comparison/support surfaces, skills library, and the shared skill report scaffold/trust chrome
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import {
|
|
19
|
+
DashboardChrome,
|
|
20
|
+
DashboardHostProvider,
|
|
21
|
+
canUseFeature,
|
|
22
|
+
type Capabilities,
|
|
23
|
+
type DashboardHostAdapter,
|
|
24
|
+
} from "@selftune/dashboard-core";
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## OSS Mirror
|
|
28
|
+
|
|
29
|
+
This package is canonical in the root `packages/` directory and mirrored into
|
|
30
|
+
`oss/selftune/packages/dashboard-core` via `scripts/sync-embedded-shared.sh`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@selftune/dashboard-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Shared dashboard application layer for selftune cloud and local hosts",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Daniel Petro",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/selftune-dev/selftune.git",
|
|
11
|
+
"directory": "packages/dashboard-core"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./index.ts",
|
|
16
|
+
"./host": "./src/host/index.ts",
|
|
17
|
+
"./models": "./src/models/index.ts",
|
|
18
|
+
"./routes": "./src/routes/index.ts",
|
|
19
|
+
"./chrome": "./src/chrome/index.ts",
|
|
20
|
+
"./gates": "./src/gates/index.ts",
|
|
21
|
+
"./screens": "./src/screens/index.ts",
|
|
22
|
+
"./screens/analytics": "./src/screens/analytics/index.ts",
|
|
23
|
+
"./screens/overview": "./src/screens/overview/index.ts",
|
|
24
|
+
"./screens/skill-report": "./src/screens/skill-report/index.ts",
|
|
25
|
+
"./screens/skills": "./src/screens/skills/index.ts"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@selftune/ui": "workspace:*",
|
|
29
|
+
"lucide-react": "^0.576.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/react": "^19.0.0",
|
|
33
|
+
"@types/react-dom": "^19.0.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": "^19.0.0",
|
|
37
|
+
"react-dom": "^19.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { PlayIcon } from "lucide-react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
|
|
6
|
+
import { TooltipProvider } from "@selftune/ui/primitives";
|
|
7
|
+
|
|
8
|
+
import { DashboardHeader } from "./DashboardHeader";
|
|
9
|
+
import { DashboardSidebar } from "./DashboardSidebar";
|
|
10
|
+
import { cn } from "./utils";
|
|
11
|
+
import type { DashboardChromeProps } from "./types";
|
|
12
|
+
|
|
13
|
+
const DEFAULT_CONTENT_CLASS_NAME = "@container/main mx-auto max-w-7xl px-4 py-8 sm:px-6 lg:px-8";
|
|
14
|
+
|
|
15
|
+
export function DashboardChrome({
|
|
16
|
+
brand,
|
|
17
|
+
navItems,
|
|
18
|
+
renderLink,
|
|
19
|
+
headerMeta,
|
|
20
|
+
searchItems = [],
|
|
21
|
+
headerUser,
|
|
22
|
+
sidebarUser,
|
|
23
|
+
sidebarAction,
|
|
24
|
+
onSignOut,
|
|
25
|
+
overlay,
|
|
26
|
+
contentClassName,
|
|
27
|
+
children,
|
|
28
|
+
}: DashboardChromeProps) {
|
|
29
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
30
|
+
|
|
31
|
+
const content =
|
|
32
|
+
contentClassName === null ? (
|
|
33
|
+
children
|
|
34
|
+
) : (
|
|
35
|
+
<div className={cn(contentClassName ?? DEFAULT_CONTENT_CLASS_NAME)}>{children}</div>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<TooltipProvider>
|
|
40
|
+
<div className="min-h-screen bg-background">
|
|
41
|
+
<DashboardSidebar
|
|
42
|
+
brand={brand}
|
|
43
|
+
navItems={navItems}
|
|
44
|
+
renderLink={renderLink}
|
|
45
|
+
sidebarAction={
|
|
46
|
+
sidebarAction ?? {
|
|
47
|
+
label: "Run Evolution",
|
|
48
|
+
tooltip: "Dashboard-triggered evolution is not available yet.",
|
|
49
|
+
icon: <PlayIcon className="size-4" />,
|
|
50
|
+
disabled: true,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
sidebarUser={sidebarUser}
|
|
54
|
+
onSignOut={onSignOut}
|
|
55
|
+
mobileOpen={mobileOpen}
|
|
56
|
+
onMobileOpenChange={setMobileOpen}
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
<div className="min-h-screen lg:pl-64">
|
|
60
|
+
<DashboardHeader
|
|
61
|
+
renderLink={renderLink}
|
|
62
|
+
headerMeta={headerMeta}
|
|
63
|
+
searchItems={searchItems}
|
|
64
|
+
headerUser={headerUser}
|
|
65
|
+
onToggleSidebar={() => setMobileOpen((open) => !open)}
|
|
66
|
+
/>
|
|
67
|
+
<main className="min-h-[calc(100vh-4rem)]">{content}</main>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
{overlay}
|
|
71
|
+
</div>
|
|
72
|
+
</TooltipProvider>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ArrowLeftIcon, BellIcon, BoltIcon, MenuIcon, SearchIcon, UserIcon } from "lucide-react";
|
|
4
|
+
import { useDeferredValue, useRef, useState } from "react";
|
|
5
|
+
|
|
6
|
+
import type { DashboardUser } from "../host/index";
|
|
7
|
+
import { getUserInitials, matchesSearchItem } from "./utils";
|
|
8
|
+
import type { DashboardHeaderMeta, DashboardLinkRenderer, DashboardSearchItem } from "./types";
|
|
9
|
+
|
|
10
|
+
interface DashboardHeaderProps {
|
|
11
|
+
renderLink: DashboardLinkRenderer;
|
|
12
|
+
headerMeta: DashboardHeaderMeta;
|
|
13
|
+
searchItems: DashboardSearchItem[];
|
|
14
|
+
headerUser?: DashboardUser;
|
|
15
|
+
onToggleSidebar(): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function DashboardHeader({
|
|
19
|
+
renderLink,
|
|
20
|
+
headerMeta,
|
|
21
|
+
searchItems,
|
|
22
|
+
headerUser,
|
|
23
|
+
onToggleSidebar,
|
|
24
|
+
}: DashboardHeaderProps) {
|
|
25
|
+
const [query, setQuery] = useState("");
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
27
|
+
const suppressBlurRef = useRef(false);
|
|
28
|
+
const deferredQuery = useDeferredValue(query);
|
|
29
|
+
|
|
30
|
+
const filteredItems = searchItems
|
|
31
|
+
.filter((item) => matchesSearchItem(item, deferredQuery))
|
|
32
|
+
.slice(0, deferredQuery.trim() ? 12 : 8);
|
|
33
|
+
|
|
34
|
+
const groups = new Map<string, DashboardSearchItem[]>();
|
|
35
|
+
for (const item of filteredItems) {
|
|
36
|
+
const existing = groups.get(item.group) ?? [];
|
|
37
|
+
existing.push(item);
|
|
38
|
+
groups.set(item.group, existing);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<header className="sticky top-0 z-40 border-b border-border/10 bg-background/80 backdrop-blur-xl">
|
|
43
|
+
<div className="flex h-16 items-center justify-between gap-4 px-4 lg:px-8">
|
|
44
|
+
<div className="flex min-w-0 flex-1 items-center gap-3 lg:gap-4">
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
className="rounded-lg bg-card p-2 text-foreground lg:hidden"
|
|
48
|
+
onClick={onToggleSidebar}
|
|
49
|
+
aria-label="Toggle sidebar"
|
|
50
|
+
>
|
|
51
|
+
<MenuIcon className="size-5" />
|
|
52
|
+
</button>
|
|
53
|
+
|
|
54
|
+
{headerMeta.backHref && headerMeta.backLabel
|
|
55
|
+
? renderLink({
|
|
56
|
+
href: headerMeta.backHref,
|
|
57
|
+
className:
|
|
58
|
+
"inline-flex items-center gap-1 font-headline text-[10px] uppercase tracking-[0.2em] text-slate-500 transition-colors hover:text-primary",
|
|
59
|
+
children: (
|
|
60
|
+
<>
|
|
61
|
+
<ArrowLeftIcon className="size-3" />
|
|
62
|
+
{headerMeta.backLabel}
|
|
63
|
+
</>
|
|
64
|
+
),
|
|
65
|
+
})
|
|
66
|
+
: null}
|
|
67
|
+
|
|
68
|
+
<div className="hidden xl:flex items-center gap-3 rounded-full border border-border/15 bg-card/60 px-3 py-1.5 text-sm shadow-[0_10px_40px_rgba(0,0,0,0.12)]">
|
|
69
|
+
{headerMeta.icon ? (
|
|
70
|
+
<span className="shrink-0 text-primary">{headerMeta.icon}</span>
|
|
71
|
+
) : null}
|
|
72
|
+
<div className="flex min-w-0 items-center gap-2">
|
|
73
|
+
<span className="font-headline text-[10px] uppercase tracking-[0.18em] text-slate-500">
|
|
74
|
+
{headerMeta.badge ?? "View"}
|
|
75
|
+
</span>
|
|
76
|
+
<span className="truncate font-medium text-foreground">{headerMeta.title}</span>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<div className="relative w-full max-w-xl">
|
|
81
|
+
<SearchIcon className="pointer-events-none absolute left-3 top-1/2 z-10 size-4 -translate-y-1/2 text-slate-400" />
|
|
82
|
+
<input
|
|
83
|
+
value={query}
|
|
84
|
+
onChange={(event) => setQuery(event.target.value)}
|
|
85
|
+
onFocus={() => setOpen(true)}
|
|
86
|
+
onBlur={() => {
|
|
87
|
+
if (suppressBlurRef.current) {
|
|
88
|
+
suppressBlurRef.current = false;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
setOpen(false);
|
|
92
|
+
}}
|
|
93
|
+
placeholder="Search skills or pages..."
|
|
94
|
+
className="h-9 w-full rounded-full border border-border/10 bg-input/50 pl-10 pr-4 text-sm text-foreground outline-none transition focus:border-primary/30 focus:ring-1 focus:ring-primary/40 placeholder:text-slate-500"
|
|
95
|
+
/>
|
|
96
|
+
|
|
97
|
+
{open ? (
|
|
98
|
+
<div className="absolute left-0 right-0 top-full z-50 mt-2 max-h-80 overflow-y-auto rounded-2xl border border-border/15 bg-card shadow-[0_20px_60px_rgba(0,0,0,0.35)] backdrop-blur-xl">
|
|
99
|
+
{filteredItems.length === 0 ? (
|
|
100
|
+
<div className="px-4 py-5 text-sm text-muted-foreground">No results found.</div>
|
|
101
|
+
) : (
|
|
102
|
+
Array.from(groups.entries()).map(([group, items]) => (
|
|
103
|
+
<div key={group} className="border-b border-border/10 last:border-b-0">
|
|
104
|
+
<div className="px-4 pt-3 text-[10px] uppercase tracking-[0.18em] text-slate-500">
|
|
105
|
+
{group}
|
|
106
|
+
</div>
|
|
107
|
+
<div className="p-2">
|
|
108
|
+
{items.map((item) => (
|
|
109
|
+
<button
|
|
110
|
+
key={item.id}
|
|
111
|
+
type="button"
|
|
112
|
+
onMouseDown={(event) => {
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
suppressBlurRef.current = true;
|
|
115
|
+
}}
|
|
116
|
+
onClick={() => {
|
|
117
|
+
item.onSelect();
|
|
118
|
+
setOpen(false);
|
|
119
|
+
setQuery("");
|
|
120
|
+
}}
|
|
121
|
+
className="flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40"
|
|
122
|
+
>
|
|
123
|
+
{item.leading ? (
|
|
124
|
+
<span className="shrink-0">{item.leading}</span>
|
|
125
|
+
) : (
|
|
126
|
+
<span className="shrink-0 text-slate-400">
|
|
127
|
+
{item.meta ? "•" : ""}
|
|
128
|
+
</span>
|
|
129
|
+
)}
|
|
130
|
+
<div className="min-w-0 flex-1">
|
|
131
|
+
<div className="truncate text-foreground">{item.label}</div>
|
|
132
|
+
{item.meta ? (
|
|
133
|
+
<div className="truncate text-xs text-muted-foreground">
|
|
134
|
+
{item.meta}
|
|
135
|
+
</div>
|
|
136
|
+
) : null}
|
|
137
|
+
</div>
|
|
138
|
+
{item.trailing ? (
|
|
139
|
+
<span className="shrink-0 text-xs text-muted-foreground">
|
|
140
|
+
{item.trailing}
|
|
141
|
+
</span>
|
|
142
|
+
) : null}
|
|
143
|
+
</button>
|
|
144
|
+
))}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
))
|
|
148
|
+
)}
|
|
149
|
+
</div>
|
|
150
|
+
) : null}
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<div className="hidden items-center gap-4 sm:flex lg:gap-6">
|
|
155
|
+
<div className="flex items-center gap-4 text-slate-400">
|
|
156
|
+
<span className="relative" aria-hidden="true">
|
|
157
|
+
<BellIcon className="size-4" />
|
|
158
|
+
<span className="absolute -right-0.5 -top-0.5 size-2 rounded-full border-2 border-background bg-primary shadow-[0_0_6px_color-mix(in_srgb,var(--primary)_50%,transparent)]" />
|
|
159
|
+
</span>
|
|
160
|
+
<BoltIcon className="size-4" aria-hidden="true" />
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
{headerUser ? (
|
|
164
|
+
<>
|
|
165
|
+
<div className="h-8 w-px bg-border/20" />
|
|
166
|
+
<div className="flex items-center gap-3">
|
|
167
|
+
<div className="hidden text-right md:block">
|
|
168
|
+
<div className="font-headline text-[10px] uppercase tracking-widest text-slate-400">
|
|
169
|
+
{headerUser.name}
|
|
170
|
+
</div>
|
|
171
|
+
<div className="text-[10px] uppercase tracking-widest text-primary">
|
|
172
|
+
{headerUser.subtitle ?? headerUser.email ?? "Active"}
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
{headerUser.image ? (
|
|
176
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
177
|
+
<img
|
|
178
|
+
src={headerUser.image}
|
|
179
|
+
alt={headerUser.name}
|
|
180
|
+
className="size-8 rounded-full"
|
|
181
|
+
/>
|
|
182
|
+
) : (
|
|
183
|
+
<div className="flex size-8 items-center justify-center rounded-full border border-primary/20 bg-card text-primary">
|
|
184
|
+
{headerUser.name ? (
|
|
185
|
+
<span className="text-xs font-medium">
|
|
186
|
+
{getUserInitials(headerUser.name)}
|
|
187
|
+
</span>
|
|
188
|
+
) : (
|
|
189
|
+
<UserIcon className="size-4" />
|
|
190
|
+
)}
|
|
191
|
+
</div>
|
|
192
|
+
)}
|
|
193
|
+
</div>
|
|
194
|
+
</>
|
|
195
|
+
) : null}
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
</header>
|
|
199
|
+
);
|
|
200
|
+
}
|