selftune 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +1 -0
  2. package/apps/local-dashboard/dist/assets/index-Bk9vSHHd.js +15 -0
  3. package/apps/local-dashboard/dist/assets/index-CRtLkBTi.css +1 -0
  4. package/apps/local-dashboard/dist/assets/vendor-react-BQH_6WrG.js +60 -0
  5. package/apps/local-dashboard/dist/assets/{vendor-table-B7VF2Ipl.js → vendor-table-dK1QMLq9.js} +1 -1
  6. package/apps/local-dashboard/dist/assets/{vendor-ui-r2k_Ku_V.js → vendor-ui-CO2mrx6e.js} +60 -65
  7. package/apps/local-dashboard/dist/index.html +5 -5
  8. package/cli/selftune/activation-rules.ts +30 -9
  9. package/cli/selftune/agent-guidance.ts +96 -0
  10. package/cli/selftune/alpha-identity.ts +157 -0
  11. package/cli/selftune/alpha-upload/build-payloads.ts +151 -0
  12. package/cli/selftune/alpha-upload/client.ts +113 -0
  13. package/cli/selftune/alpha-upload/flush.ts +191 -0
  14. package/cli/selftune/alpha-upload/index.ts +194 -0
  15. package/cli/selftune/alpha-upload/queue.ts +252 -0
  16. package/cli/selftune/alpha-upload/stage-canonical.ts +242 -0
  17. package/cli/selftune/alpha-upload-contract.ts +52 -0
  18. package/cli/selftune/auth/device-code.ts +110 -0
  19. package/cli/selftune/auto-update.ts +130 -0
  20. package/cli/selftune/badge/badge.ts +19 -9
  21. package/cli/selftune/canonical-export.ts +16 -3
  22. package/cli/selftune/constants.ts +28 -8
  23. package/cli/selftune/contribute/bundle.ts +32 -5
  24. package/cli/selftune/dashboard-contract.ts +32 -1
  25. package/cli/selftune/dashboard-server.ts +256 -692
  26. package/cli/selftune/dashboard.ts +1 -1
  27. package/cli/selftune/eval/baseline.ts +11 -7
  28. package/cli/selftune/eval/hooks-to-evals.ts +27 -9
  29. package/cli/selftune/eval/synthetic-evals.ts +54 -1
  30. package/cli/selftune/evolution/audit.ts +24 -19
  31. package/cli/selftune/evolution/constitutional.ts +176 -0
  32. package/cli/selftune/evolution/evidence.ts +18 -13
  33. package/cli/selftune/evolution/evolve-body.ts +104 -7
  34. package/cli/selftune/evolution/evolve.ts +195 -22
  35. package/cli/selftune/evolution/propose-body.ts +18 -1
  36. package/cli/selftune/evolution/propose-description.ts +27 -2
  37. package/cli/selftune/evolution/rollback.ts +11 -15
  38. package/cli/selftune/export.ts +84 -0
  39. package/cli/selftune/grading/auto-grade.ts +13 -4
  40. package/cli/selftune/grading/grade-session.ts +16 -6
  41. package/cli/selftune/hooks/evolution-guard.ts +26 -9
  42. package/cli/selftune/hooks/prompt-log.ts +23 -9
  43. package/cli/selftune/hooks/session-stop.ts +78 -15
  44. package/cli/selftune/hooks/skill-eval.ts +189 -10
  45. package/cli/selftune/index.ts +274 -2
  46. package/cli/selftune/ingestors/claude-replay.ts +48 -21
  47. package/cli/selftune/init.ts +249 -47
  48. package/cli/selftune/last.ts +7 -7
  49. package/cli/selftune/localdb/db.ts +90 -10
  50. package/cli/selftune/localdb/direct-write.ts +531 -0
  51. package/cli/selftune/localdb/materialize.ts +296 -42
  52. package/cli/selftune/localdb/queries.ts +325 -32
  53. package/cli/selftune/localdb/schema.ts +109 -0
  54. package/cli/selftune/monitoring/watch.ts +26 -8
  55. package/cli/selftune/normalization.ts +85 -15
  56. package/cli/selftune/observability.ts +248 -2
  57. package/cli/selftune/orchestrate.ts +165 -20
  58. package/cli/selftune/quickstart.ts +34 -10
  59. package/cli/selftune/repair/skill-usage.ts +12 -2
  60. package/cli/selftune/routes/actions.ts +77 -0
  61. package/cli/selftune/routes/badge.ts +66 -0
  62. package/cli/selftune/routes/doctor.ts +12 -0
  63. package/cli/selftune/routes/index.ts +14 -0
  64. package/cli/selftune/routes/orchestrate-runs.ts +13 -0
  65. package/cli/selftune/routes/overview.ts +14 -0
  66. package/cli/selftune/routes/report.ts +293 -0
  67. package/cli/selftune/routes/skill-report.ts +230 -0
  68. package/cli/selftune/status.ts +203 -7
  69. package/cli/selftune/sync.ts +13 -1
  70. package/cli/selftune/types.ts +50 -0
  71. package/cli/selftune/utils/jsonl.ts +58 -1
  72. package/cli/selftune/utils/selftune-meta.ts +38 -0
  73. package/cli/selftune/utils/skill-log.ts +30 -4
  74. package/cli/selftune/utils/transcript.ts +15 -0
  75. package/cli/selftune/workflows/workflows.ts +7 -6
  76. package/package.json +10 -6
  77. package/packages/telemetry-contract/fixtures/complete-push.ts +184 -0
  78. package/packages/telemetry-contract/fixtures/evidence-only-push.ts +58 -0
  79. package/packages/telemetry-contract/fixtures/golden.json +1 -0
  80. package/packages/telemetry-contract/fixtures/index.ts +4 -0
  81. package/packages/telemetry-contract/fixtures/partial-push-no-sessions.ts +40 -0
  82. package/packages/telemetry-contract/fixtures/partial-push-unresolved-parents.ts +79 -0
  83. package/packages/telemetry-contract/package.json +6 -1
  84. package/packages/telemetry-contract/src/index.ts +1 -0
  85. package/packages/telemetry-contract/src/schemas.ts +215 -0
  86. package/packages/telemetry-contract/src/types.ts +3 -1
  87. package/packages/telemetry-contract/src/validators.ts +3 -1
  88. package/packages/telemetry-contract/tests/compatibility.test.ts +144 -0
  89. package/packages/ui/package.json +4 -0
  90. package/packages/ui/src/components/ActivityTimeline.tsx +61 -29
  91. package/packages/ui/src/components/section-cards.tsx +31 -14
  92. package/packages/ui/src/types.ts +1 -0
  93. package/skill/SKILL.md +214 -174
  94. package/skill/Workflows/AlphaUpload.md +45 -0
  95. package/skill/Workflows/Baseline.md +18 -12
  96. package/skill/Workflows/Composability.md +3 -3
  97. package/skill/Workflows/Dashboard.md +44 -91
  98. package/skill/Workflows/Doctor.md +93 -66
  99. package/skill/Workflows/Evals.md +49 -40
  100. package/skill/Workflows/Evolve.md +76 -28
  101. package/skill/Workflows/EvolveBody.md +37 -38
  102. package/skill/Workflows/Initialize.md +172 -26
  103. package/skill/Workflows/Orchestrate.md +11 -2
  104. package/skill/Workflows/Sync.md +23 -0
  105. package/skill/Workflows/Watch.md +2 -5
  106. package/skill/agents/diagnosis-analyst.md +163 -0
  107. package/skill/agents/evolution-reviewer.md +149 -0
  108. package/skill/agents/integration-guide.md +154 -0
  109. package/skill/agents/pattern-analyst.md +149 -0
  110. package/skill/assets/multi-skill-settings.json +1 -1
  111. package/skill/assets/single-skill-settings.json +1 -1
  112. package/skill/references/interactive-config.md +39 -0
  113. package/skill/references/invocation-taxonomy.md +34 -0
  114. package/skill/references/logs.md +9 -1
  115. package/skill/references/setup-patterns.md +3 -3
  116. package/skill/settings_snippet.json +1 -1
  117. package/apps/local-dashboard/dist/assets/index-C75H1Q3n.css +0 -1
  118. package/apps/local-dashboard/dist/assets/index-axE4kz3Q.js +0 -15
  119. package/apps/local-dashboard/dist/assets/vendor-react-U7zYD9Rg.js +0 -60
@@ -5,10 +5,22 @@
5
5
  import { homedir } from "node:os";
6
6
  import { join } from "node:path";
7
7
 
8
- export const SELFTUNE_CONFIG_DIR = join(homedir(), ".selftune");
8
+ const resolvedHome = process.env.SELFTUNE_HOME;
9
+ const defaultHome = resolvedHome ?? homedir();
10
+ const claudeHomeDir =
11
+ process.env.SELFTUNE_CLAUDE_DIR ??
12
+ (resolvedHome ? join(defaultHome, ".claude") : join(homedir(), ".claude"));
13
+ const openclawHomeDir =
14
+ process.env.SELFTUNE_OPENCLAW_DIR ??
15
+ (resolvedHome ? join(defaultHome, ".openclaw") : join(homedir(), ".openclaw"));
16
+
17
+ export const SELFTUNE_CONFIG_DIR =
18
+ (process.env.SELFTUNE_CONFIG_DIR || undefined) ??
19
+ (resolvedHome ? join(defaultHome, ".selftune") : join(homedir(), ".selftune"));
20
+
9
21
  export const SELFTUNE_CONFIG_PATH = join(SELFTUNE_CONFIG_DIR, "config.json");
10
22
 
11
- export const LOG_DIR = join(homedir(), ".claude");
23
+ export const LOG_DIR = (process.env.SELFTUNE_LOG_DIR || undefined) ?? claudeHomeDir;
12
24
 
13
25
  export const TELEMETRY_LOG = join(LOG_DIR, "session_telemetry_log.jsonl");
14
26
  export const SKILL_LOG = join(LOG_DIR, "skill_usage_log.jsonl");
@@ -106,22 +118,30 @@ export function canonicalSessionStatePath(sessionId: string): string {
106
118
  }
107
119
 
108
120
  /** Claude Code settings file path. */
109
- export const CLAUDE_SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
121
+ export const CLAUDE_SETTINGS_PATH =
122
+ process.env.SELFTUNE_CLAUDE_SETTINGS_PATH ?? join(claudeHomeDir, "settings.json");
110
123
 
111
124
  /** Path to Claude Code projects directory containing session transcripts. */
112
- export const CLAUDE_CODE_PROJECTS_DIR = join(homedir(), ".claude", "projects");
125
+ export const CLAUDE_CODE_PROJECTS_DIR =
126
+ process.env.SELFTUNE_CLAUDE_PROJECTS_DIR ?? join(claudeHomeDir, "projects");
113
127
 
114
128
  /** Marker file tracking which Claude Code sessions have been ingested. */
115
- export const CLAUDE_CODE_MARKER = join(homedir(), ".claude", "claude_code_ingested_sessions.json");
129
+ export const CLAUDE_CODE_MARKER =
130
+ process.env.SELFTUNE_CLAUDE_MARKER_PATH ??
131
+ join(claudeHomeDir, "claude_code_ingested_sessions.json");
116
132
 
117
133
  /** Marker file tracking which Codex rollout files have been ingested. */
118
- export const CODEX_INGEST_MARKER = join(homedir(), ".claude", "codex_ingested_rollouts.json");
134
+ export const CODEX_INGEST_MARKER =
135
+ process.env.SELFTUNE_CODEX_MARKER_PATH ?? join(claudeHomeDir, "codex_ingested_rollouts.json");
119
136
 
120
137
  /** Marker file tracking which OpenCode sessions have been ingested. */
121
- export const OPENCODE_INGEST_MARKER = join(homedir(), ".claude", "opencode_ingested_sessions.json");
138
+ export const OPENCODE_INGEST_MARKER =
139
+ process.env.SELFTUNE_OPENCODE_MARKER_PATH ??
140
+ join(claudeHomeDir, "opencode_ingested_sessions.json");
122
141
 
123
142
  /** OpenClaw agents directory containing session data. */
124
- export const OPENCLAW_AGENTS_DIR = join(homedir(), ".openclaw", "agents");
143
+ export const OPENCLAW_AGENTS_DIR =
144
+ process.env.SELFTUNE_OPENCLAW_AGENTS_DIR ?? join(openclawHomeDir, "agents");
125
145
 
126
146
  /** Marker file tracking which OpenClaw sessions have been ingested. */
127
147
  export const OPENCLAW_INGEST_MARKER = join(SELFTUNE_CONFIG_DIR, "openclaw-ingest-marker.json");
@@ -16,6 +16,13 @@ import {
16
16
  TELEMETRY_LOG,
17
17
  } from "../constants.js";
18
18
  import { buildEvalSet, classifyInvocation } from "../eval/hooks-to-evals.js";
19
+ import { getDb } from "../localdb/db.js";
20
+ import {
21
+ queryEvolutionAudit,
22
+ queryQueryLog,
23
+ querySessionTelemetry,
24
+ querySkillUsageRecords,
25
+ } from "../localdb/queries.js";
19
26
  import type {
20
27
  ContributionBundle,
21
28
  ContributionEvolutionSummary,
@@ -203,11 +210,31 @@ export function assembleBundle(options: {
203
210
  evolutionAuditLogPath = EVOLUTION_AUDIT_LOG,
204
211
  } = options;
205
212
 
206
- // Read all logs
207
- const allSkillRecords = readJsonl<SkillUsageRecord>(skillLogPath);
208
- const allQueryRecords = readJsonl<QueryLogRecord>(queryLogPath);
209
- const allTelemetryRecords = readJsonl<SessionTelemetryRecord>(telemetryLogPath);
210
- const allEvolutionRecords = readJsonl<EvolutionAuditEntry>(evolutionAuditLogPath);
213
+ // Read from JSONL when custom (non-default) paths are provided (test isolation),
214
+ // otherwise read from SQLite (production).
215
+ const useJsonl =
216
+ queryLogPath !== QUERY_LOG ||
217
+ skillLogPath !== SKILL_LOG ||
218
+ telemetryLogPath !== TELEMETRY_LOG ||
219
+ evolutionAuditLogPath !== EVOLUTION_AUDIT_LOG;
220
+
221
+ let allSkillRecords: SkillUsageRecord[];
222
+ let allQueryRecords: QueryLogRecord[];
223
+ let allTelemetryRecords: SessionTelemetryRecord[];
224
+ let allEvolutionRecords: EvolutionAuditEntry[];
225
+
226
+ if (useJsonl) {
227
+ allSkillRecords = readJsonl<SkillUsageRecord>(skillLogPath);
228
+ allQueryRecords = readJsonl<QueryLogRecord>(queryLogPath);
229
+ allTelemetryRecords = readJsonl<SessionTelemetryRecord>(telemetryLogPath);
230
+ allEvolutionRecords = readJsonl<EvolutionAuditEntry>(evolutionAuditLogPath);
231
+ } else {
232
+ const db = getDb();
233
+ allSkillRecords = querySkillUsageRecords(db) as SkillUsageRecord[];
234
+ allQueryRecords = queryQueryLog(db) as QueryLogRecord[];
235
+ allTelemetryRecords = querySessionTelemetry(db) as SessionTelemetryRecord[];
236
+ allEvolutionRecords = queryEvolutionAudit(db) as EvolutionAuditEntry[];
237
+ }
211
238
 
212
239
  // Filter by skill and since
213
240
  const skillRecords = filterSince(
@@ -28,6 +28,7 @@ export interface EvalSnapshot {
28
28
  export interface EvolutionEntry {
29
29
  timestamp: string;
30
30
  proposal_id: string;
31
+ skill_name?: string;
31
32
  action: string;
32
33
  details: string;
33
34
  eval_snapshot?: EvalSnapshot | null;
@@ -96,12 +97,18 @@ export interface EvidenceEntry {
96
97
 
97
98
  export interface CanonicalInvocation {
98
99
  timestamp: string;
100
+ occurred_at?: string;
99
101
  session_id: string;
100
102
  skill_name: string;
101
103
  invocation_mode: string | null;
102
104
  triggered: boolean;
103
105
  confidence: number | null;
104
106
  tool_name: string | null;
107
+ agent_type?: string | null;
108
+ query?: string | null;
109
+ source?: string | null;
110
+ skill_path?: string | null;
111
+ skill_scope?: string | null;
105
112
  }
106
113
 
107
114
  export interface PromptSample {
@@ -131,6 +138,11 @@ export interface SkillReportPayload {
131
138
  triggered_count: number;
132
139
  pass_rate: number;
133
140
  };
141
+ /**
142
+ * @deprecated Use `canonical_invocations` from SkillReportResponse instead.
143
+ * Retained for backward compatibility; the backend now returns unified data
144
+ * in `canonical_invocations` from the consolidated `skill_invocations` table.
145
+ */
134
146
  recent_invocations: Array<{
135
147
  timestamp: string;
136
148
  session_id: string;
@@ -174,6 +186,25 @@ export interface OrchestrateRunsResponse {
174
186
  runs: OrchestrateRunReport[];
175
187
  }
176
188
 
189
+ // -- Health endpoint response -------------------------------------------------
190
+
191
+ export interface HealthResponse {
192
+ ok: boolean;
193
+ service: string;
194
+ version: string;
195
+ spa: boolean;
196
+ v2_data_available: boolean;
197
+ workspace_root: string;
198
+ git_sha: string;
199
+ db_path: string;
200
+ log_dir: string;
201
+ config_dir: string;
202
+ watcher_mode: "jsonl" | "none";
203
+ process_mode: "standalone" | "dev-server" | "test";
204
+ host: string;
205
+ port: number;
206
+ }
207
+
177
208
  // -- Doctor / health check types ----------------------------------------------
178
209
  export type { DoctorResult, HealthCheck, HealthStatus } from "./types.js";
179
210
 
@@ -189,7 +220,7 @@ export interface SkillReportResponse extends SkillReportPayload {
189
220
  avg_duration_ms: number;
190
221
  total_duration_ms: number;
191
222
  execution_count: number;
192
- total_errors: number;
223
+ missed_triggers: number;
193
224
  };
194
225
  selftune_stats: {
195
226
  total_llm_calls: number;