pikakit 3.8.4 → 3.9.0
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/bin/kit.mjs +3 -0
- package/bin/lib/commands/metrics.js +208 -0
- package/package.json +1 -1
package/bin/kit.mjs
CHANGED
|
@@ -24,6 +24,9 @@ const COMMANDS = {
|
|
|
24
24
|
validate: { module: "./lib/commands/validate.js", hasParam: true, aliases: ["check"] },
|
|
25
25
|
analyze: { module: "./lib/commands/analyze.js", hasParam: true },
|
|
26
26
|
|
|
27
|
+
// Metrics & Observability
|
|
28
|
+
metrics: { module: "./lib/commands/metrics.js", hasParam: true, aliases: ["stats"] },
|
|
29
|
+
|
|
27
30
|
// Info
|
|
28
31
|
info: { module: "./lib/commands/info.js", hasParam: true, aliases: ["show"] },
|
|
29
32
|
help: { module: "./lib/commands/help.js", aliases: ["--help", "-h"] }
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kit metrics - View autopilot execution metrics
|
|
3
|
+
* @description Display metrics from autopilot runs with various views
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* kit metrics - Show latest run summary
|
|
7
|
+
* kit metrics list - List all runs
|
|
8
|
+
* kit metrics <id> - Show specific run details
|
|
9
|
+
* kit metrics summary - Show aggregate stats
|
|
10
|
+
*/
|
|
11
|
+
import { c } from "../ui.js";
|
|
12
|
+
import path from "path";
|
|
13
|
+
import { createRequire } from "module";
|
|
14
|
+
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Find agent-skill-kit installation
|
|
19
|
+
*/
|
|
20
|
+
function findSkillKit() {
|
|
21
|
+
// Try common locations
|
|
22
|
+
const searchPaths = [
|
|
23
|
+
process.cwd(),
|
|
24
|
+
path.join(process.cwd(), ".."),
|
|
25
|
+
path.join(process.cwd(), "../agent-skill-kit")
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
for (const basePath of searchPaths) {
|
|
29
|
+
const metricsPath = path.join(basePath, ".agent/skills/skill-generator/lib/metrics-collector.cjs");
|
|
30
|
+
try {
|
|
31
|
+
const { MetricsCollector } = require(metricsPath);
|
|
32
|
+
return new MetricsCollector({
|
|
33
|
+
metricsDir: path.join(basePath, ".agent/metrics")
|
|
34
|
+
});
|
|
35
|
+
} catch {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Format duration in human-readable format
|
|
44
|
+
*/
|
|
45
|
+
function formatDuration(seconds) {
|
|
46
|
+
if (!seconds) return "0s";
|
|
47
|
+
if (seconds < 60) return `${seconds}s`;
|
|
48
|
+
const mins = Math.floor(seconds / 60);
|
|
49
|
+
const secs = seconds % 60;
|
|
50
|
+
return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Print run summary
|
|
55
|
+
*/
|
|
56
|
+
function printRunSummary(run) {
|
|
57
|
+
if (!run || !run.metrics) {
|
|
58
|
+
console.log(c.yellow("No metrics data available"));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const m = run.metrics;
|
|
63
|
+
|
|
64
|
+
console.log(`\n${c.cyan("╔")}${"═".repeat(50)}${c.cyan("╗")}`);
|
|
65
|
+
console.log(`${c.cyan("║")} ${c.bold("📊 AUTOPILOT RUN: " + (run.task_id || "Unknown"))}`.padEnd(60) + `${c.cyan("║")}`);
|
|
66
|
+
console.log(`${c.cyan("╠")}${"═".repeat(50)}${c.cyan("╣")}`);
|
|
67
|
+
|
|
68
|
+
console.log(`${c.cyan("║")} Duration: ${formatDuration(m.speed?.time_to_completion || 0)}`.padEnd(51) + `${c.cyan("║")}`);
|
|
69
|
+
console.log(`${c.cyan("║")} Phases: ${m.speed?.total_phases || 0}`.padEnd(51) + `${c.cyan("║")}`);
|
|
70
|
+
console.log(`${c.cyan("╠")}${"─".repeat(50)}${c.cyan("╣")}`);
|
|
71
|
+
|
|
72
|
+
const autonomy = m.autonomy?.autonomous_completion_rate || 0;
|
|
73
|
+
const autonomyColor = autonomy >= 80 ? c.green : autonomy >= 50 ? c.yellow : c.red;
|
|
74
|
+
console.log(`${c.cyan("║")} Autonomy: ${autonomyColor(autonomy + "%")}`.padEnd(60) + `${c.cyan("║")}`);
|
|
75
|
+
|
|
76
|
+
const interventions = m.intervention?.human_interventions || 0;
|
|
77
|
+
const intColor = interventions === 0 ? c.green : c.yellow;
|
|
78
|
+
console.log(`${c.cyan("║")} Interventions: ${intColor(interventions)}`.padEnd(60) + `${c.cyan("║")}`);
|
|
79
|
+
|
|
80
|
+
const successRate = m.quality?.first_time_success_rate || 0;
|
|
81
|
+
const successColor = successRate >= 90 ? c.green : successRate >= 70 ? c.yellow : c.red;
|
|
82
|
+
console.log(`${c.cyan("║")} Success Rate: ${successColor(successRate + "%")}`.padEnd(60) + `${c.cyan("║")}`);
|
|
83
|
+
|
|
84
|
+
console.log(`${c.cyan("╚")}${"═".repeat(50)}${c.cyan("╝")}\n`);
|
|
85
|
+
|
|
86
|
+
// Show phases if available
|
|
87
|
+
if (run.phases && run.phases.length > 0) {
|
|
88
|
+
console.log(c.gray("Phases:"));
|
|
89
|
+
for (const phase of run.phases) {
|
|
90
|
+
const icon = phase.status === "success" ? c.green("✓") : c.red("✗");
|
|
91
|
+
console.log(` ${icon} ${phase.name} (${formatDuration(Math.round(phase.duration_ms / 1000))})`);
|
|
92
|
+
}
|
|
93
|
+
console.log();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Print runs list
|
|
99
|
+
*/
|
|
100
|
+
function printRunsList(runs) {
|
|
101
|
+
if (!runs || runs.length === 0) {
|
|
102
|
+
console.log(c.yellow("\nNo autopilot runs found.\n"));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(`\n${c.cyan("📋 AUTOPILOT RUNS")} (${runs.length} total)\n`);
|
|
107
|
+
console.log(`${"ID".padEnd(20)} ${"TASK".padEnd(25)} ${"DURATION".padEnd(10)} ${"STATUS"}`);
|
|
108
|
+
console.log(`${"-".repeat(20)} ${"-".repeat(25)} ${"-".repeat(10)} ${"-".repeat(8)}`);
|
|
109
|
+
|
|
110
|
+
for (const run of runs.slice(0, 10)) {
|
|
111
|
+
const summary = run.metrics_summary || {};
|
|
112
|
+
const duration = formatDuration(summary.time_to_completion || 0);
|
|
113
|
+
const status = (summary.human_interventions || 0) === 0 ? c.green("✓ Auto") : c.yellow("⚡ Mixed");
|
|
114
|
+
|
|
115
|
+
console.log(
|
|
116
|
+
`${(run.id || "?").slice(0, 20).padEnd(20)} ` +
|
|
117
|
+
`${(run.task_id || "?").slice(0, 24).padEnd(25)} ` +
|
|
118
|
+
`${duration.padEnd(10)} ` +
|
|
119
|
+
`${status}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
console.log();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Print aggregate summary
|
|
127
|
+
*/
|
|
128
|
+
function printSummary(collector) {
|
|
129
|
+
const runs = collector.listRuns();
|
|
130
|
+
|
|
131
|
+
console.log(`\n${c.cyan("╔")}${"═".repeat(50)}${c.cyan("╗")}`);
|
|
132
|
+
console.log(`${c.cyan("║")} ${c.bold("📈 AUTOPILOT METRICS SUMMARY")}`.padEnd(60) + `${c.cyan("║")}`);
|
|
133
|
+
console.log(`${c.cyan("╠")}${"═".repeat(50)}${c.cyan("╣")}`);
|
|
134
|
+
|
|
135
|
+
if (runs.length === 0) {
|
|
136
|
+
console.log(`${c.cyan("║")} ${c.yellow("No runs recorded yet")}`.padEnd(60) + `${c.cyan("║")}`);
|
|
137
|
+
console.log(`${c.cyan("╚")}${"═".repeat(50)}${c.cyan("╝")}\n`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Calculate aggregates
|
|
142
|
+
let totalDuration = 0;
|
|
143
|
+
let totalInterventions = 0;
|
|
144
|
+
let totalAutonomy = 0;
|
|
145
|
+
let validRuns = 0;
|
|
146
|
+
|
|
147
|
+
for (const runInfo of runs.slice(0, 10)) {
|
|
148
|
+
const run = collector.loadRun(runInfo.id);
|
|
149
|
+
if (run && run.metrics) {
|
|
150
|
+
totalDuration += run.metrics.speed?.time_to_completion || 0;
|
|
151
|
+
totalInterventions += run.metrics.intervention?.human_interventions || 0;
|
|
152
|
+
totalAutonomy += run.metrics.autonomy?.autonomous_completion_rate || 0;
|
|
153
|
+
validRuns++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const avgDuration = validRuns > 0 ? Math.round(totalDuration / validRuns) : 0;
|
|
158
|
+
const avgInterventions = validRuns > 0 ? (totalInterventions / validRuns).toFixed(1) : 0;
|
|
159
|
+
const avgAutonomy = validRuns > 0 ? Math.round(totalAutonomy / validRuns) : 0;
|
|
160
|
+
|
|
161
|
+
console.log(`${c.cyan("║")} Total Runs: ${runs.length}`.padEnd(51) + `${c.cyan("║")}`);
|
|
162
|
+
console.log(`${c.cyan("║")} Avg Duration: ${formatDuration(avgDuration)}`.padEnd(51) + `${c.cyan("║")}`);
|
|
163
|
+
console.log(`${c.cyan("║")} Avg Interventions: ${avgInterventions}`.padEnd(51) + `${c.cyan("║")}`);
|
|
164
|
+
|
|
165
|
+
const autoColor = avgAutonomy >= 80 ? c.green : avgAutonomy >= 50 ? c.yellow : c.red;
|
|
166
|
+
console.log(`${c.cyan("║")} Avg Autonomy: ${autoColor(avgAutonomy + "%")}`.padEnd(60) + `${c.cyan("║")}`);
|
|
167
|
+
|
|
168
|
+
console.log(`${c.cyan("╚")}${"═".repeat(50)}${c.cyan("╝")}\n`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Run the metrics command
|
|
173
|
+
*/
|
|
174
|
+
export async function run(subcommand) {
|
|
175
|
+
const collector = findSkillKit();
|
|
176
|
+
|
|
177
|
+
if (!collector) {
|
|
178
|
+
console.log(c.red("\n✗ Could not find agent-skill-kit installation."));
|
|
179
|
+
console.log(c.gray(" Make sure you're in a directory with .agent/skills/skill-generator/\n"));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const runs = collector.listRuns();
|
|
184
|
+
|
|
185
|
+
// Handle subcommands
|
|
186
|
+
if (!subcommand || subcommand === "latest") {
|
|
187
|
+
// Show latest run
|
|
188
|
+
if (runs.length === 0) {
|
|
189
|
+
console.log(c.yellow("\nNo autopilot runs found. Run /autopilot to generate metrics.\n"));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const latest = collector.loadRun(runs[0].id);
|
|
193
|
+
printRunSummary(latest);
|
|
194
|
+
} else if (subcommand === "list" || subcommand === "ls") {
|
|
195
|
+
printRunsList(runs);
|
|
196
|
+
} else if (subcommand === "summary" || subcommand === "stats") {
|
|
197
|
+
printSummary(collector);
|
|
198
|
+
} else {
|
|
199
|
+
// Try to load specific run by ID
|
|
200
|
+
const run = collector.loadRun(subcommand);
|
|
201
|
+
if (run) {
|
|
202
|
+
printRunSummary(run);
|
|
203
|
+
} else {
|
|
204
|
+
console.log(c.red(`\n✗ Run "${subcommand}" not found.`));
|
|
205
|
+
console.log(c.gray(" Use 'kit metrics list' to see available runs.\n"));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pikakit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0",
|
|
4
4
|
"description": "Enterprise-grade Agent Skill Manager with Antigravity Skills support, Progressive Disclosure detection, and semantic routing validation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "pikakit <pikakit@gmail.com>",
|