pikakit 3.0.0 → 3.0.2

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.
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Auto-Learn Dashboard Server
4
+ *
5
+ * Simple HTTP server to display lessons, stats, and knowledge base.
6
+ * Bundled with pikakit for standalone usage.
7
+ */
8
+
9
+ import http from "http";
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import { fileURLToPath } from "url";
13
+
14
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
+
16
+ // Parse command line args
17
+ const args = process.argv.slice(2);
18
+ const portIndex = args.indexOf("--port");
19
+ const PORT = portIndex !== -1 ? parseInt(args[portIndex + 1], 10) : 3030;
20
+
21
+ // Paths
22
+ const AGENT_DIR = path.join(process.cwd(), ".agent");
23
+ const KNOWLEDGE_DIR = path.join(AGENT_DIR, "knowledge");
24
+
25
+ /**
26
+ * Load JSON/YAML data
27
+ */
28
+ function loadData(filename) {
29
+ const jsonPath = path.join(KNOWLEDGE_DIR, filename + ".json");
30
+ const yamlPath = path.join(KNOWLEDGE_DIR, filename + ".yaml");
31
+
32
+ try {
33
+ if (fs.existsSync(jsonPath)) {
34
+ return JSON.parse(fs.readFileSync(jsonPath, "utf8"));
35
+ }
36
+ if (fs.existsSync(yamlPath)) {
37
+ // Simple YAML parsing for basic structures
38
+ const content = fs.readFileSync(yamlPath, "utf8");
39
+ return { raw: content };
40
+ }
41
+ } catch (e) {
42
+ console.error(`Error loading ${filename}:`, e.message);
43
+ }
44
+ return null;
45
+ }
46
+
47
+ /**
48
+ * Get summary stats
49
+ */
50
+ function getSummary() {
51
+ const lessonsData = loadData("lessons-learned");
52
+ const metricsData = loadData("metrics");
53
+
54
+ const lessons = lessonsData?.lessons || [];
55
+
56
+ return {
57
+ totalLessons: lessons.length,
58
+ mistakes: lessons.filter(l => l.severity === "ERROR" || l.type === "mistake").length,
59
+ improvements: lessons.filter(l => l.type === "improvement").length,
60
+ lastUpdated: lessonsData?.updatedAt || new Date().toISOString(),
61
+ metrics: metricsData || {}
62
+ };
63
+ }
64
+
65
+ /**
66
+ * HTML Dashboard
67
+ */
68
+ function renderDashboard() {
69
+ const summary = getSummary();
70
+ const lessonsData = loadData("lessons-learned");
71
+ const lessons = lessonsData?.lessons || [];
72
+
73
+ return `<!DOCTYPE html>
74
+ <html>
75
+ <head>
76
+ <meta charset="UTF-8">
77
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
78
+ <title>PikaKit Dashboard</title>
79
+ <style>
80
+ * { box-sizing: border-box; margin: 0; padding: 0; }
81
+ body {
82
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
83
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
84
+ color: #e8e8e8;
85
+ min-height: 100vh;
86
+ padding: 2rem;
87
+ }
88
+ .container { max-width: 1200px; margin: 0 auto; }
89
+ h1 {
90
+ font-size: 2.5rem;
91
+ margin-bottom: 0.5rem;
92
+ background: linear-gradient(90deg, #fff, #888);
93
+ -webkit-background-clip: text;
94
+ -webkit-text-fill-color: transparent;
95
+ }
96
+ .subtitle { color: #888; margin-bottom: 2rem; }
97
+ .stats {
98
+ display: grid;
99
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
100
+ gap: 1rem;
101
+ margin-bottom: 2rem;
102
+ }
103
+ .stat-card {
104
+ background: rgba(255,255,255,0.05);
105
+ border: 1px solid rgba(255,255,255,0.1);
106
+ border-radius: 12px;
107
+ padding: 1.5rem;
108
+ text-align: center;
109
+ }
110
+ .stat-value { font-size: 2.5rem; font-weight: bold; color: #4ade80; }
111
+ .stat-label { color: #888; margin-top: 0.5rem; }
112
+ .lessons {
113
+ background: rgba(255,255,255,0.03);
114
+ border-radius: 12px;
115
+ padding: 1.5rem;
116
+ }
117
+ .lessons h2 { margin-bottom: 1rem; }
118
+ .lesson {
119
+ padding: 1rem;
120
+ border-bottom: 1px solid rgba(255,255,255,0.1);
121
+ }
122
+ .lesson:last-child { border-bottom: none; }
123
+ .lesson-id {
124
+ display: inline-block;
125
+ background: rgba(74, 222, 128, 0.2);
126
+ color: #4ade80;
127
+ padding: 0.2rem 0.5rem;
128
+ border-radius: 4px;
129
+ font-size: 0.85rem;
130
+ margin-right: 0.5rem;
131
+ }
132
+ .lesson-message { margin-top: 0.5rem; }
133
+ .empty { color: #666; font-style: italic; }
134
+ </style>
135
+ </head>
136
+ <body>
137
+ <div class="container">
138
+ <h1>⚡ PikaKit Dashboard</h1>
139
+ <p class="subtitle">Auto-Learn Knowledge Base • v3.0.1</p>
140
+
141
+ <div class="stats">
142
+ <div class="stat-card">
143
+ <div class="stat-value">${summary.totalLessons}</div>
144
+ <div class="stat-label">Total Lessons</div>
145
+ </div>
146
+ <div class="stat-card">
147
+ <div class="stat-value" style="color: #f87171;">${summary.mistakes}</div>
148
+ <div class="stat-label">Mistakes</div>
149
+ </div>
150
+ <div class="stat-card">
151
+ <div class="stat-value" style="color: #4ade80;">${summary.improvements}</div>
152
+ <div class="stat-label">Improvements</div>
153
+ </div>
154
+ </div>
155
+
156
+ <div class="lessons">
157
+ <h2>📚 Lessons Learned</h2>
158
+ ${lessons.length === 0
159
+ ? '<p class="empty">No lessons learned yet. Start learning from your mistakes!</p>'
160
+ : lessons.map(l => `
161
+ <div class="lesson">
162
+ <span class="lesson-id">${l.id}</span>
163
+ <span>${l.severity || l.type || 'INFO'}</span>
164
+ <p class="lesson-message">${l.message || l.pattern || 'No description'}</p>
165
+ </div>
166
+ `).join('')
167
+ }
168
+ </div>
169
+ </div>
170
+ </body>
171
+ </html>`;
172
+ }
173
+
174
+ /**
175
+ * HTTP Server
176
+ */
177
+ const server = http.createServer((req, res) => {
178
+ const url = req.url;
179
+
180
+ // CORS headers
181
+ res.setHeader("Access-Control-Allow-Origin", "*");
182
+ res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
183
+
184
+ if (url === "/" || url === "/dashboard") {
185
+ res.writeHead(200, { "Content-Type": "text/html" });
186
+ res.end(renderDashboard());
187
+ } else if (url === "/api/summary") {
188
+ res.writeHead(200, { "Content-Type": "application/json" });
189
+ res.end(JSON.stringify(getSummary()));
190
+ } else if (url === "/api/lessons") {
191
+ res.writeHead(200, { "Content-Type": "application/json" });
192
+ const data = loadData("lessons-learned");
193
+ res.end(JSON.stringify(data?.lessons || []));
194
+ } else {
195
+ res.writeHead(404);
196
+ res.end("Not Found");
197
+ }
198
+ });
199
+
200
+ server.listen(PORT, () => {
201
+ console.log(`✅ Dashboard server running at http://localhost:${PORT}`);
202
+ });
@@ -27,7 +27,7 @@ export const RULES_DIR = path.join(AGENT_DIR, "rules");
27
27
  /** CLI version - read from package.json */
28
28
  export const VERSION = (() => {
29
29
  try { return require("../package.json").version; }
30
- catch { return "3.0.0"; }
30
+ catch { return "3.0.2"; }
31
31
  })();
32
32
 
33
33
  /** Debug mode */
@@ -198,12 +198,21 @@ export function loadKnowledge() {
198
198
  return { lessons, version: 4.0 };
199
199
  }
200
200
 
201
- // Fallback to v3.x
202
- if (!fs.existsSync(LESSONS_PATH)) {
203
- return { lessons: [], version: 1 };
201
+ // Fallback to v3.x YAML
202
+ if (fs.existsSync(LESSONS_PATH)) {
203
+ const content = fs.readFileSync(LESSONS_PATH, "utf8");
204
+ return yaml.load(content) || { lessons: [], version: 1 };
204
205
  }
205
- const content = fs.readFileSync(LESSONS_PATH, "utf8");
206
- return yaml.load(content) || { lessons: [], version: 1 };
206
+
207
+ // Fallback to v3.x JSON (lessons-learned.json)
208
+ const jsonPath = LESSONS_PATH.replace('.yaml', '.json');
209
+ if (fs.existsSync(jsonPath)) {
210
+ const content = fs.readFileSync(jsonPath, "utf8");
211
+ const data = JSON.parse(content);
212
+ return { lessons: data.lessons || [], version: 3 };
213
+ }
214
+
215
+ return { lessons: [], version: 1 };
207
216
  } catch (error) {
208
217
  if (DEBUG) console.error("Error loading knowledge:", error.message);
209
218
  return { lessons: [], version: 1 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pikakit",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
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>",