@zenalexa/unicli 0.208.0 → 0.209.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/AGENTS.md +1 -1
- package/README.md +6 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +82 -2
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +20 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/hub.d.ts +13 -0
- package/dist/commands/hub.d.ts.map +1 -0
- package/dist/commands/hub.js +232 -0
- package/dist/commands/hub.js.map +1 -0
- package/dist/commands/research.d.ts +17 -0
- package/dist/commands/research.d.ts.map +1 -0
- package/dist/commands/research.js +257 -0
- package/dist/commands/research.js.map +1 -0
- package/dist/commands/test-gen.d.ts +10 -0
- package/dist/commands/test-gen.d.ts.map +1 -0
- package/dist/commands/test-gen.js +124 -0
- package/dist/commands/test-gen.js.map +1 -0
- package/dist/discovery/loader.d.ts.map +1 -1
- package/dist/discovery/loader.js +3 -0
- package/dist/discovery/loader.js.map +1 -1
- package/dist/engine/capability.d.ts +40 -0
- package/dist/engine/capability.d.ts.map +1 -0
- package/dist/engine/capability.js +191 -0
- package/dist/engine/capability.js.map +1 -0
- package/dist/engine/endpoint.d.ts +47 -0
- package/dist/engine/endpoint.d.ts.map +1 -0
- package/dist/engine/endpoint.js +295 -0
- package/dist/engine/endpoint.js.map +1 -0
- package/dist/engine/framework.d.ts +28 -0
- package/dist/engine/framework.d.ts.map +1 -0
- package/dist/engine/framework.js +66 -0
- package/dist/engine/framework.js.map +1 -0
- package/dist/engine/probe.d.ts +19 -0
- package/dist/engine/probe.d.ts.map +1 -0
- package/dist/engine/probe.js +85 -0
- package/dist/engine/probe.js.map +1 -0
- package/dist/engine/research.d.ts +38 -0
- package/dist/engine/research.d.ts.map +1 -0
- package/dist/engine/research.js +414 -0
- package/dist/engine/research.js.map +1 -0
- package/dist/engine/yaml-runner.d.ts.map +1 -1
- package/dist/engine/yaml-runner.js +80 -5
- package/dist/engine/yaml-runner.js.map +1 -1
- package/dist/manifest.json +403 -1
- package/dist/mcp/server.js +59 -1
- package/dist/mcp/server.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/cnn/top.yaml +21 -0
- package/src/adapters/cocoapods/search.yaml +16 -0
- package/src/adapters/crates-io/search.yaml +27 -0
- package/src/adapters/docker-hub/search.yaml +26 -0
- package/src/adapters/eastmoney/hot.yaml +23 -0
- package/src/adapters/eastmoney/search.yaml +25 -0
- package/src/adapters/exchangerate/convert.yaml +19 -0
- package/src/adapters/feishu/calendar.yaml +24 -0
- package/src/adapters/feishu/docs.yaml +17 -0
- package/src/adapters/feishu/send.yaml +29 -0
- package/src/adapters/feishu/tasks.yaml +24 -0
- package/src/adapters/gitee/search.yaml +25 -0
- package/src/adapters/gitee/trending.yaml +22 -0
- package/src/adapters/gitlab/search.yaml +24 -0
- package/src/adapters/gitlab/trending.yaml +22 -0
- package/src/adapters/homebrew/info.yaml +15 -0
- package/src/adapters/huggingface-papers/daily.yaml +21 -0
- package/src/adapters/infoq/articles.yaml +29 -0
- package/src/adapters/ip-info/lookup.yaml +15 -0
- package/src/adapters/itch-io/popular.yaml +22 -0
- package/src/adapters/ithome/news.yaml +21 -0
- package/src/adapters/mastodon/search.yaml +29 -0
- package/src/adapters/mastodon/trending.yaml +27 -0
- package/src/adapters/meituan/search.yaml +30 -0
- package/src/adapters/minimax/chat.yaml +33 -0
- package/src/adapters/minimax/models.yaml +18 -0
- package/src/adapters/minimax/tts.yaml +33 -0
- package/src/adapters/netease-music/hot.yaml +24 -0
- package/src/adapters/netease-music/search.yaml +29 -0
- package/src/adapters/npm-trends/compare.yaml +19 -0
- package/src/adapters/nytimes/top.yaml +26 -0
- package/src/adapters/openrouter/models.yaml +22 -0
- package/src/adapters/pexels/search.yaml +28 -0
- package/src/adapters/pinduoduo/hot.yaml +20 -0
- package/src/adapters/pypi/info.yaml +16 -0
- package/src/adapters/qweather/now.yaml +16 -0
- package/src/adapters/replicate/search.yaml +25 -0
- package/src/adapters/replicate/trending.yaml +22 -0
- package/src/adapters/sspai/hot.yaml +21 -0
- package/src/adapters/sspai/latest.yaml +22 -0
- package/src/adapters/techcrunch/latest.yaml +22 -0
- package/src/adapters/theverge/latest.yaml +21 -0
- package/src/adapters/twitch/top.yaml +26 -0
- package/src/adapters/unsplash/search.yaml +28 -0
- package/src/adapters/ycombinator/launches.yaml +20 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hub CLI command — git-based adapter registry.
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* unicli hub search <query> — search community adapters
|
|
6
|
+
* unicli hub install <site>/<command> — install adapter from hub
|
|
7
|
+
* unicli hub publish <site> [command] — submit adapter to hub
|
|
8
|
+
* unicli hub update — pull latest adapter index
|
|
9
|
+
* unicli hub verify <site> — verify installed hub adapters
|
|
10
|
+
*/
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
|
|
13
|
+
import { join, basename } from "node:path";
|
|
14
|
+
import { homedir } from "node:os";
|
|
15
|
+
import { execFileSync } from "node:child_process";
|
|
16
|
+
const HUB_REPO = "olo-dot-io/unicli-hub";
|
|
17
|
+
const HUB_DIR = join(homedir(), ".unicli", "hub");
|
|
18
|
+
const INDEX_PATH = join(HUB_DIR, "index.json");
|
|
19
|
+
const ADAPTERS_DIR = join(homedir(), ".unicli", "adapters");
|
|
20
|
+
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
21
|
+
function ghApiJson(endpoint) {
|
|
22
|
+
const raw = execFileSync("gh", ["api", endpoint], {
|
|
23
|
+
encoding: "utf-8",
|
|
24
|
+
timeout: 15_000,
|
|
25
|
+
});
|
|
26
|
+
return JSON.parse(raw);
|
|
27
|
+
}
|
|
28
|
+
function ensureHubDir() {
|
|
29
|
+
mkdirSync(HUB_DIR, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
function loadIndex() {
|
|
32
|
+
if (!existsSync(INDEX_PATH))
|
|
33
|
+
return null;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(readFileSync(INDEX_PATH, "utf-8"));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// ── Command Registration ────────────────────────────────────────────────
|
|
42
|
+
export function registerHubCommand(program) {
|
|
43
|
+
const hub = program.command("hub").description("Community adapter registry");
|
|
44
|
+
// Search
|
|
45
|
+
hub
|
|
46
|
+
.command("search <query>")
|
|
47
|
+
.description("Search community adapters")
|
|
48
|
+
.option("--json", "JSON output")
|
|
49
|
+
.action((query, opts) => {
|
|
50
|
+
const index = loadIndex();
|
|
51
|
+
if (!index) {
|
|
52
|
+
console.error(chalk.yellow("No hub index. Run `unicli hub update` first."));
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const q = query.toLowerCase();
|
|
57
|
+
const matches = index.entries.filter((e) => e.site.includes(q) ||
|
|
58
|
+
e.command.includes(q) ||
|
|
59
|
+
e.description.toLowerCase().includes(q));
|
|
60
|
+
if (opts.json) {
|
|
61
|
+
console.log(JSON.stringify(matches, null, 2));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (matches.length === 0) {
|
|
65
|
+
console.log(chalk.dim(`No adapters matching "${query}".`));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.log(chalk.cyan(`Found ${matches.length} adapter(s):`));
|
|
69
|
+
for (const m of matches) {
|
|
70
|
+
console.log(` ${chalk.green(m.site)}/${m.command} — ${m.description} (${m.strategy})`);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// Install
|
|
74
|
+
hub
|
|
75
|
+
.command("install <path>")
|
|
76
|
+
.description("Install adapter from hub (site/command)")
|
|
77
|
+
.action(async (adapterPath) => {
|
|
78
|
+
const [site, command] = adapterPath.split("/");
|
|
79
|
+
if (!site || !command) {
|
|
80
|
+
console.error(chalk.red("Usage: unicli hub install <site>/<command>"));
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Validate names to prevent path traversal (CWE-22)
|
|
85
|
+
const SAFE_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
86
|
+
if (!SAFE_NAME.test(site) || !SAFE_NAME.test(command)) {
|
|
87
|
+
console.error(chalk.red("Invalid site/command name. Only alphanumeric, hyphens, and underscores allowed."));
|
|
88
|
+
process.exitCode = 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
// Fetch adapter YAML from GitHub repo
|
|
93
|
+
const apiPath = `/repos/${HUB_REPO}/contents/adapters/${site}/${command}.yaml`;
|
|
94
|
+
const response = ghApiJson(apiPath);
|
|
95
|
+
if (!response.content) {
|
|
96
|
+
console.error(chalk.red(`Adapter not found: ${site}/${command}`));
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const content = Buffer.from(response.content, "base64").toString("utf-8");
|
|
101
|
+
// Install to user adapter directory
|
|
102
|
+
const targetDir = join(ADAPTERS_DIR, site);
|
|
103
|
+
mkdirSync(targetDir, { recursive: true });
|
|
104
|
+
const targetPath = join(targetDir, `${command}.yaml`);
|
|
105
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
106
|
+
console.log(chalk.green(`Installed ${site}/${command} → ${targetPath}`));
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
110
|
+
console.error(chalk.red(`Install failed: ${msg}`));
|
|
111
|
+
console.error(chalk.dim("Make sure `gh` is installed and authenticated."));
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
// Publish
|
|
116
|
+
hub
|
|
117
|
+
.command("publish <site> [command]")
|
|
118
|
+
.description("Submit adapter to community hub")
|
|
119
|
+
.action((site, command) => {
|
|
120
|
+
const SAFE_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
121
|
+
if (!SAFE_NAME.test(site) || (command && !SAFE_NAME.test(command))) {
|
|
122
|
+
console.error(chalk.red("Invalid name. Only alphanumeric, hyphens, underscores."));
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// Find adapter files
|
|
127
|
+
const siteDir = join("src", "adapters", site);
|
|
128
|
+
if (!existsSync(siteDir)) {
|
|
129
|
+
// Try user override directory
|
|
130
|
+
const userDir = join(ADAPTERS_DIR, site);
|
|
131
|
+
if (!existsSync(userDir)) {
|
|
132
|
+
console.error(chalk.red(`Adapter directory not found: ${site}`));
|
|
133
|
+
process.exitCode = 1;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// For now, just print instructions. Full automation would need gh pr create.
|
|
138
|
+
console.log(chalk.cyan(`To publish ${site} adapters to the hub:`));
|
|
139
|
+
console.log("");
|
|
140
|
+
console.log(` 1. Fork ${HUB_REPO} on GitHub`);
|
|
141
|
+
console.log(` 2. Copy your adapter YAML to adapters/${site}/${command ?? "*"}.yaml`);
|
|
142
|
+
console.log(` 3. Add meta.json with author, description, and strategy`);
|
|
143
|
+
console.log(` 4. Create a pull request`);
|
|
144
|
+
console.log("");
|
|
145
|
+
console.log(chalk.dim(`Or use: gh repo fork ${HUB_REPO} && ...`));
|
|
146
|
+
});
|
|
147
|
+
// Update
|
|
148
|
+
hub
|
|
149
|
+
.command("update")
|
|
150
|
+
.description("Pull latest adapter index from hub")
|
|
151
|
+
.action(async () => {
|
|
152
|
+
ensureHubDir();
|
|
153
|
+
try {
|
|
154
|
+
// Fetch directory listing from GitHub API
|
|
155
|
+
const response = ghApiJson(`/repos/${HUB_REPO}/contents/adapters`);
|
|
156
|
+
if (!Array.isArray(response)) {
|
|
157
|
+
console.error(chalk.red("Failed to fetch hub index."));
|
|
158
|
+
process.exitCode = 1;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const entries = [];
|
|
162
|
+
for (const dir of response) {
|
|
163
|
+
if (dir.type !== "dir")
|
|
164
|
+
continue;
|
|
165
|
+
const site = dir.name;
|
|
166
|
+
// Fetch commands for this site
|
|
167
|
+
try {
|
|
168
|
+
const files = ghApiJson(`/repos/${HUB_REPO}/contents/adapters/${site}`);
|
|
169
|
+
for (const file of files) {
|
|
170
|
+
if (!file.name.endsWith(".yaml"))
|
|
171
|
+
continue;
|
|
172
|
+
const cmd = basename(file.name, ".yaml");
|
|
173
|
+
entries.push({
|
|
174
|
+
site,
|
|
175
|
+
command: cmd,
|
|
176
|
+
description: "",
|
|
177
|
+
author: "",
|
|
178
|
+
strategy: "public",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
/* skip site on error */
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const index = {
|
|
187
|
+
updatedAt: new Date().toISOString(),
|
|
188
|
+
entries,
|
|
189
|
+
};
|
|
190
|
+
writeFileSync(INDEX_PATH, JSON.stringify(index, null, 2), "utf-8");
|
|
191
|
+
console.log(chalk.green(`Hub index updated: ${entries.length} adapters from ${response.filter((d) => d.type === "dir").length} sites.`));
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
195
|
+
console.error(chalk.red(`Update failed: ${msg}`));
|
|
196
|
+
console.error(chalk.dim("Make sure `gh` is installed and authenticated."));
|
|
197
|
+
process.exitCode = 1;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
// Verify
|
|
201
|
+
hub
|
|
202
|
+
.command("verify <site>")
|
|
203
|
+
.description("Verify installed hub adapters")
|
|
204
|
+
.action((site) => {
|
|
205
|
+
const SAFE_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
206
|
+
if (!SAFE_NAME.test(site)) {
|
|
207
|
+
console.error(chalk.red("Invalid site name."));
|
|
208
|
+
process.exitCode = 1;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const siteDir = join(ADAPTERS_DIR, site);
|
|
212
|
+
if (!existsSync(siteDir)) {
|
|
213
|
+
console.error(chalk.red(`No hub adapters installed for: ${site}`));
|
|
214
|
+
process.exitCode = 1;
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
console.log(chalk.cyan(`Verifying ${site} adapters...`));
|
|
218
|
+
try {
|
|
219
|
+
// Use execFileSync with args — no shell injection
|
|
220
|
+
const result = execFileSync("unicli", ["eval", "run", site, "--json"], {
|
|
221
|
+
encoding: "utf-8",
|
|
222
|
+
timeout: 60_000,
|
|
223
|
+
});
|
|
224
|
+
console.log(result);
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
228
|
+
console.error(chalk.yellow(`Verification: ${msg}`));
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/commands/hub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAClD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAC/C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAmB5D,4EAA4E;AAE5E,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE;QAChD,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,MAAM;KAChB,CAAW,CAAC;IACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,YAAY;IACnB,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAa,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2EAA2E;AAE3E,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;IAE7E,SAAS;IACT,GAAG;SACA,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;SAC/B,MAAM,CAAC,CAAC,KAAa,EAAE,IAAwB,EAAE,EAAE;QAClD,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,MAAM,CAAC,8CAA8C,CAAC,CAC7D,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC1C,CAAC;QAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,KAAK,IAAI,CAAC,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC;QAC/D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,QAAQ,GAAG,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,UAAU;IACV,GAAG;SACA,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,EAAE;QACpC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC,CAAC;YACvE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,oDAAoD;QACpD,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,iFAAiF,CAClF,CACF,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,sCAAsC;YACtC,MAAM,OAAO,GAAG,UAAU,QAAQ,sBAAsB,IAAI,IAAI,OAAO,OAAO,CAAC;YAC/E,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAGjC,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC;gBAClE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAC9D,OAAO,CACR,CAAC;YAEF,oCAAoC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YAC3C,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC;YACtD,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAE5C,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,OAAO,MAAM,UAAU,EAAE,CAAC,CAC5D,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC,CAAC;YACnD,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAC5D,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,UAAU;IACV,GAAG;SACA,OAAO,CAAC,0BAA0B,CAAC;SACnC,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE;QACzC,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YACnE,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,wDAAwD,CAAC,CACpE,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,qBAAqB;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,8BAA8B;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACjE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAED,6EAA6E;QAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,uBAAuB,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,aAAa,QAAQ,YAAY,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CACT,2CAA2C,IAAI,IAAI,OAAO,IAAI,GAAG,OAAO,CACzE,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,QAAQ,SAAS,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEL,SAAS;IACT,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,oCAAoC,CAAC;SACjD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,YAAY,EAAE,CAAC;QAEf,IAAI,CAAC;YACH,0CAA0C;YAC1C,MAAM,QAAQ,GAAG,SAAS,CACxB,UAAU,QAAQ,oBAAoB,CACE,CAAC;YAE3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;gBACvD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAe,EAAE,CAAC;YAE/B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;oBAAE,SAAS;gBACjC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBAEtB,+BAA+B;gBAC/B,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,SAAS,CACrB,UAAU,QAAQ,sBAAsB,IAAI,EAAE,CACpB,CAAC;oBAE7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;wBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;4BAAE,SAAS;wBAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;wBACzC,OAAO,CAAC,IAAI,CAAC;4BACX,IAAI;4BACJ,OAAO,EAAE,GAAG;4BACZ,WAAW,EAAE,EAAE;4BACf,MAAM,EAAE,EAAE;4BACV,QAAQ,EAAE,QAAQ;yBACnB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAa;gBACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,OAAO;aACR,CAAC;YACF,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAEnE,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CACT,sBAAsB,OAAO,CAAC,MAAM,kBAAkB,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,MAAM,SAAS,CAC/G,CACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAC5D,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,SAAS;IACT,GAAG;SACA,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC/C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC,CAAC;YACnE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,cAAc,CAAC,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,kDAAkD;YAClD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;gBACrE,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,MAAM;aAChB,CAAW,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research CLI command — Karpathy-style self-improvement loop.
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* unicli research <site> [command] — improve a specific adapter
|
|
6
|
+
* unicli research log [--since 7d] — show improvement history
|
|
7
|
+
* unicli research report — aggregate stats
|
|
8
|
+
*
|
|
9
|
+
* Options:
|
|
10
|
+
* --goal <goal> — what to improve (default: "increase eval score")
|
|
11
|
+
* --iterations <n> — max iterations (default: 10)
|
|
12
|
+
* --preset <name> — use preset config (reliability, coverage, freshness, security)
|
|
13
|
+
* --guard <cmd> — regression guard command
|
|
14
|
+
*/
|
|
15
|
+
import { Command } from "commander";
|
|
16
|
+
export declare function registerResearchCommand(program: Command): void;
|
|
17
|
+
//# sourceMappingURL=research.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/commands/research.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgEpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4P9D"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research CLI command — Karpathy-style self-improvement loop.
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* unicli research <site> [command] — improve a specific adapter
|
|
6
|
+
* unicli research log [--since 7d] — show improvement history
|
|
7
|
+
* unicli research report — aggregate stats
|
|
8
|
+
*
|
|
9
|
+
* Options:
|
|
10
|
+
* --goal <goal> — what to improve (default: "increase eval score")
|
|
11
|
+
* --iterations <n> — max iterations (default: 10)
|
|
12
|
+
* --preset <name> — use preset config (reliability, coverage, freshness, security)
|
|
13
|
+
* --guard <cmd> — regression guard command
|
|
14
|
+
*/
|
|
15
|
+
import chalk from "chalk";
|
|
16
|
+
import { existsSync } from "node:fs";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
import { runResearchLoop, readResearchLog, } from "../engine/research.js";
|
|
19
|
+
function buildPresetConfig(preset, site) {
|
|
20
|
+
switch (preset) {
|
|
21
|
+
case "reliability":
|
|
22
|
+
return {
|
|
23
|
+
goal: "Improve eval pass rate — fix failing assertions, update selectors, handle empty responses",
|
|
24
|
+
verify: `unicli eval run ${site} --json 2>&1`,
|
|
25
|
+
scope: [`src/adapters/${site}/*.yaml`, `src/adapters/${site}/*.ts`],
|
|
26
|
+
};
|
|
27
|
+
case "coverage":
|
|
28
|
+
return {
|
|
29
|
+
goal: "Add more capabilities — discover new endpoints and generate adapters for them",
|
|
30
|
+
verify: `unicli eval run ${site} --json 2>&1`,
|
|
31
|
+
scope: [`src/adapters/${site}/*.yaml`],
|
|
32
|
+
};
|
|
33
|
+
case "freshness":
|
|
34
|
+
return {
|
|
35
|
+
goal: "Update stale selectors and API endpoints — fix any 404, 403, or empty results",
|
|
36
|
+
verify: `unicli eval run ${site} --json 2>&1`,
|
|
37
|
+
scope: [`src/adapters/${site}/*.yaml`],
|
|
38
|
+
};
|
|
39
|
+
case "security":
|
|
40
|
+
return {
|
|
41
|
+
goal: "Audit for shell injection vectors — ensure no raw arg interpolation in exec steps",
|
|
42
|
+
verify: `unicli eval run ${site} --json 2>&1`,
|
|
43
|
+
scope: [`src/adapters/${site}/*.yaml`],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ── Duration Formatting ─────────────────────────────────────────────────
|
|
48
|
+
function parseSinceDuration(since) {
|
|
49
|
+
const match = /^(\d+)([dhm])$/.exec(since);
|
|
50
|
+
if (!match)
|
|
51
|
+
return Date.now() - 7 * 24 * 60 * 60 * 1000; // default 7d
|
|
52
|
+
const val = parseInt(match[1], 10);
|
|
53
|
+
const unit = match[2];
|
|
54
|
+
const ms = unit === "d"
|
|
55
|
+
? val * 86_400_000
|
|
56
|
+
: unit === "h"
|
|
57
|
+
? val * 3_600_000
|
|
58
|
+
: val * 60_000;
|
|
59
|
+
return Date.now() - ms;
|
|
60
|
+
}
|
|
61
|
+
// ── Command Registration ────────────────────────────────────────────────
|
|
62
|
+
export function registerResearchCommand(program) {
|
|
63
|
+
const research = program
|
|
64
|
+
.command("research")
|
|
65
|
+
.description("Self-improvement loop for adapter quality");
|
|
66
|
+
// Main research command
|
|
67
|
+
research
|
|
68
|
+
.command("run <site> [command]")
|
|
69
|
+
.description("Run research loop to improve an adapter")
|
|
70
|
+
.option("--goal <goal>", "improvement goal")
|
|
71
|
+
.option("--iterations <n>", "max iterations", "10")
|
|
72
|
+
.option("--preset <name>", "preset config (reliability|coverage|freshness|security)")
|
|
73
|
+
.option("--guard <cmd>", "regression guard command")
|
|
74
|
+
.option("--json", "JSON output")
|
|
75
|
+
.action(async (site, command, opts) => {
|
|
76
|
+
// Validate site name to prevent shell injection
|
|
77
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(site)) {
|
|
78
|
+
console.error(chalk.red("Invalid site name. Only alphanumeric, hyphens, and underscores allowed."));
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const maxIterations = parseInt(opts.iterations, 10) || 10;
|
|
83
|
+
const jsonOnly = opts.json ?? false;
|
|
84
|
+
// Build config from preset or explicit options
|
|
85
|
+
let config;
|
|
86
|
+
if (opts.preset) {
|
|
87
|
+
const presetName = opts.preset;
|
|
88
|
+
if (!["reliability", "coverage", "freshness", "security"].includes(presetName)) {
|
|
89
|
+
console.error(chalk.red(`Unknown preset: ${presetName}. Available: reliability, coverage, freshness, security`));
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const preset = buildPresetConfig(presetName, site);
|
|
94
|
+
config = {
|
|
95
|
+
site,
|
|
96
|
+
command,
|
|
97
|
+
goal: opts.goal ?? preset.goal ?? "improve adapter",
|
|
98
|
+
verify: preset.verify ?? `unicli eval run ${site} --json 2>&1`,
|
|
99
|
+
guard: opts.guard,
|
|
100
|
+
scope: preset.scope ?? [`src/adapters/${site}/*.yaml`],
|
|
101
|
+
metric: "SCORE=(\\d+)",
|
|
102
|
+
direction: "higher",
|
|
103
|
+
maxIterations,
|
|
104
|
+
minDelta: 0,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
config = {
|
|
109
|
+
site,
|
|
110
|
+
command,
|
|
111
|
+
goal: opts.goal ??
|
|
112
|
+
"Increase eval score — fix failing adapters, improve data quality",
|
|
113
|
+
verify: `unicli eval run ${site} --json 2>&1`,
|
|
114
|
+
guard: opts.guard,
|
|
115
|
+
scope: [`src/adapters/${site}/*.yaml`, `src/adapters/${site}/*.ts`],
|
|
116
|
+
metric: "SCORE=(\\d+)",
|
|
117
|
+
direction: "higher",
|
|
118
|
+
maxIterations,
|
|
119
|
+
minDelta: 0,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// Validate adapter exists
|
|
123
|
+
const adapterDir = join("src", "adapters", site);
|
|
124
|
+
if (!existsSync(adapterDir)) {
|
|
125
|
+
console.error(chalk.red(`Adapter directory not found: ${adapterDir}`));
|
|
126
|
+
process.exitCode = 1;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (!jsonOnly) {
|
|
130
|
+
console.error(chalk.cyan(`Research: ${site}`));
|
|
131
|
+
console.error(chalk.dim(`Goal: ${config.goal}`));
|
|
132
|
+
console.error(chalk.dim(`Iterations: ${maxIterations}`));
|
|
133
|
+
console.error("");
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const results = await runResearchLoop(config, {
|
|
137
|
+
onStatus: (msg) => {
|
|
138
|
+
if (!jsonOnly)
|
|
139
|
+
console.error(chalk.dim(` ${msg}`));
|
|
140
|
+
},
|
|
141
|
+
onIteration: (result) => {
|
|
142
|
+
if (jsonOnly)
|
|
143
|
+
return;
|
|
144
|
+
const icon = result.status === "keep"
|
|
145
|
+
? chalk.green("✓")
|
|
146
|
+
: result.status === "discard"
|
|
147
|
+
? chalk.red("✗")
|
|
148
|
+
: chalk.yellow("·");
|
|
149
|
+
console.error(` ${icon} #${result.iteration} ${result.status} metric=${result.metric} ${chalk.dim(result.description)}`);
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
// Summary
|
|
153
|
+
const kept = results.filter((r) => r.status === "keep").length;
|
|
154
|
+
const discarded = results.filter((r) => r.status === "discard").length;
|
|
155
|
+
const finalMetric = results[results.length - 1]?.metric ?? 0;
|
|
156
|
+
const baselineMetric = results[0]?.metric ?? 0;
|
|
157
|
+
if (jsonOnly) {
|
|
158
|
+
console.log(JSON.stringify({
|
|
159
|
+
site,
|
|
160
|
+
iterations: results.length - 1,
|
|
161
|
+
kept,
|
|
162
|
+
discarded,
|
|
163
|
+
baselineMetric,
|
|
164
|
+
finalMetric,
|
|
165
|
+
improvement: finalMetric - baselineMetric,
|
|
166
|
+
results,
|
|
167
|
+
}, null, 2));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.error("");
|
|
171
|
+
console.error(chalk.cyan(`Done: ${kept} kept, ${discarded} discarded, metric ${baselineMetric} → ${finalMetric}`));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
176
|
+
if (jsonOnly) {
|
|
177
|
+
console.error(JSON.stringify({ error: msg }));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
console.error(chalk.red(`Research failed: ${msg}`));
|
|
181
|
+
}
|
|
182
|
+
process.exitCode = 1;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
// Log subcommand
|
|
186
|
+
research
|
|
187
|
+
.command("log")
|
|
188
|
+
.description("Show research improvement history")
|
|
189
|
+
.option("--since <duration>", "time range (e.g. 7d, 24h)", "7d")
|
|
190
|
+
.option("--site <site>", "filter by site")
|
|
191
|
+
.option("--json", "JSON output")
|
|
192
|
+
.action((opts) => {
|
|
193
|
+
const sinceMs = parseSinceDuration(opts.since);
|
|
194
|
+
const log = readResearchLog({ site: opts.site, since: sinceMs });
|
|
195
|
+
if (opts.json) {
|
|
196
|
+
console.log(JSON.stringify(log, null, 2));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (log.length === 0) {
|
|
200
|
+
console.log(chalk.dim("No research history found."));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
console.log(chalk.cyan(`Research log (since ${opts.since}):`));
|
|
204
|
+
console.log("");
|
|
205
|
+
for (const entry of log) {
|
|
206
|
+
const icon = entry.status === "keep"
|
|
207
|
+
? chalk.green("✓")
|
|
208
|
+
: entry.status === "baseline"
|
|
209
|
+
? chalk.blue("◎")
|
|
210
|
+
: chalk.red("✗");
|
|
211
|
+
console.log(` ${icon} #${entry.iteration} ${entry.status.padEnd(12)} metric=${entry.metric} ${chalk.dim(entry.description)}`);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
// Report subcommand
|
|
215
|
+
research
|
|
216
|
+
.command("report")
|
|
217
|
+
.description("Aggregate research statistics")
|
|
218
|
+
.option("--json", "JSON output")
|
|
219
|
+
.action((opts) => {
|
|
220
|
+
const log = readResearchLog();
|
|
221
|
+
if (log.length === 0) {
|
|
222
|
+
if (opts.json) {
|
|
223
|
+
console.log(JSON.stringify({ totalIterations: 0 }));
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.log(chalk.dim("No research history found."));
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const kept = log.filter((r) => r.status === "keep").length;
|
|
231
|
+
const discarded = log.filter((r) => r.status === "discard").length;
|
|
232
|
+
const crashed = log.filter((r) => r.status === "crash").length;
|
|
233
|
+
const totalMs = log.reduce((sum, r) => sum + r.durationMs, 0);
|
|
234
|
+
const report = {
|
|
235
|
+
totalIterations: log.length,
|
|
236
|
+
kept,
|
|
237
|
+
discarded,
|
|
238
|
+
crashed,
|
|
239
|
+
successRate: log.length > 0 ? ((kept / log.length) * 100).toFixed(1) + "%" : "0%",
|
|
240
|
+
totalTimeMs: totalMs,
|
|
241
|
+
avgIterationMs: Math.round(totalMs / log.length),
|
|
242
|
+
};
|
|
243
|
+
if (opts.json) {
|
|
244
|
+
console.log(JSON.stringify(report, null, 2));
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
console.log(chalk.cyan("Research Report:"));
|
|
248
|
+
console.log(` Total iterations: ${report.totalIterations}`);
|
|
249
|
+
console.log(` Kept: ${chalk.green(String(kept))}`);
|
|
250
|
+
console.log(` Discarded: ${chalk.red(String(discarded))}`);
|
|
251
|
+
console.log(` Crashed: ${chalk.yellow(String(crashed))}`);
|
|
252
|
+
console.log(` Success rate: ${report.successRate}`);
|
|
253
|
+
console.log(` Total time: ${Math.round(totalMs / 1000)}s`);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=research.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/commands/research.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,eAAe,EACf,eAAe,GAEhB,MAAM,uBAAuB,CAAC;AAM/B,SAAS,iBAAiB,CACxB,MAAkB,EAClB,IAAY;IAEZ,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,aAAa;YAChB,OAAO;gBACL,IAAI,EAAE,2FAA2F;gBACjG,MAAM,EAAE,mBAAmB,IAAI,cAAc;gBAC7C,KAAK,EAAE,CAAC,gBAAgB,IAAI,SAAS,EAAE,gBAAgB,IAAI,OAAO,CAAC;aACpE,CAAC;QACJ,KAAK,UAAU;YACb,OAAO;gBACL,IAAI,EAAE,+EAA+E;gBACrF,MAAM,EAAE,mBAAmB,IAAI,cAAc;gBAC7C,KAAK,EAAE,CAAC,gBAAgB,IAAI,SAAS,CAAC;aACvC,CAAC;QACJ,KAAK,WAAW;YACd,OAAO;gBACL,IAAI,EAAE,+EAA+E;gBACrF,MAAM,EAAE,mBAAmB,IAAI,cAAc;gBAC7C,KAAK,EAAE,CAAC,gBAAgB,IAAI,SAAS,CAAC;aACvC,CAAC;QACJ,KAAK,UAAU;YACb,OAAO;gBACL,IAAI,EAAE,mFAAmF;gBACzF,MAAM,EAAE,mBAAmB,IAAI,cAAc;gBAC7C,KAAK,EAAE,CAAC,gBAAgB,IAAI,SAAS,CAAC;aACvC,CAAC;IACN,CAAC;AACH,CAAC;AAED,2EAA2E;AAE3E,SAAS,kBAAkB,CAAC,KAAa;IACvC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IACtE,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,EAAE,GACN,IAAI,KAAK,GAAG;QACV,CAAC,CAAC,GAAG,GAAG,UAAU;QAClB,CAAC,CAAC,IAAI,KAAK,GAAG;YACZ,CAAC,CAAC,GAAG,GAAG,SAAS;YACjB,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC;IACrB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;AACzB,CAAC;AAED,2EAA2E;AAE3E,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,2CAA2C,CAAC,CAAC;IAE5D,wBAAwB;IACxB,QAAQ;SACL,OAAO,CAAC,sBAAsB,CAAC;SAC/B,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC;SAC3C,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,IAAI,CAAC;SAClD,MAAM,CACL,iBAAiB,EACjB,yDAAyD,CAC1D;SACA,MAAM,CAAC,eAAe,EAAE,0BAA0B,CAAC;SACnD,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;SAC/B,MAAM,CACL,KAAK,EACH,IAAY,EACZ,OAA2B,EAC3B,IAMC,EACD,EAAE;QACF,gDAAgD;QAChD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,yEAAyE,CAC1E,CACF,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;QAEpC,+CAA+C;QAC/C,IAAI,MAAsB,CAAC;QAE3B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAoB,CAAC;YAC7C,IACE,CAAC,CAAC,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,QAAQ,CAC5D,UAAU,CACX,EACD,CAAC;gBACD,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,mBAAmB,UAAU,yDAAyD,CACvF,CACF,CAAC;gBACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACnD,MAAM,GAAG;gBACP,IAAI;gBACJ,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,IAAI,iBAAiB;gBACnD,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,mBAAmB,IAAI,cAAc;gBAC9D,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,gBAAgB,IAAI,SAAS,CAAC;gBACtD,MAAM,EAAE,cAAc;gBACtB,SAAS,EAAE,QAAQ;gBACnB,aAAa;gBACb,QAAQ,EAAE,CAAC;aACZ,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,GAAG;gBACP,IAAI;gBACJ,OAAO;gBACP,IAAI,EACF,IAAI,CAAC,IAAI;oBACT,kEAAkE;gBACpE,MAAM,EAAE,mBAAmB,IAAI,cAAc;gBAC7C,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,CAAC,gBAAgB,IAAI,SAAS,EAAE,gBAAgB,IAAI,OAAO,CAAC;gBACnE,MAAM,EAAE,cAAc;gBACtB,SAAS,EAAE,QAAQ;gBACnB,aAAa;gBACb,QAAQ,EAAE,CAAC;aACZ,CAAC;QACJ,CAAC;QAED,0BAA0B;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,gCAAgC,UAAU,EAAE,CAAC,CACxD,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACjD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,aAAa,EAAE,CAAC,CAAC,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE;gBAC5C,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;oBAChB,IAAI,CAAC,QAAQ;wBAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;gBACtD,CAAC;gBACD,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE;oBACtB,IAAI,QAAQ;wBAAE,OAAO;oBACrB,MAAM,IAAI,GACR,MAAM,CAAC,MAAM,KAAK,MAAM;wBACtB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;wBAClB,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS;4BAC3B,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;4BAChB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC1B,OAAO,CAAC,KAAK,CACX,KAAK,IAAI,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAC3G,CAAC;gBACJ,CAAC;aACF,CAAC,CAAC;YAEH,UAAU;YACV,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;YAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAC9B,CAAC,MAAM,CAAC;YACT,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;YAC7D,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;YAE/C,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;oBACE,IAAI;oBACJ,UAAU,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC;oBAC9B,IAAI;oBACJ,SAAS;oBACT,cAAc;oBACd,WAAW;oBACX,WAAW,EAAE,WAAW,GAAG,cAAc;oBACzC,OAAO;iBACR,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAClB,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,IAAI,CACR,SAAS,IAAI,UAAU,SAAS,sBAAsB,cAAc,MAAM,WAAW,EAAE,CACxF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CACF,CAAC;IAEJ,iBAAiB;IACjB,QAAQ;SACL,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,EAAE,IAAI,CAAC;SAC/D,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;SACzC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;SAC/B,MAAM,CAAC,CAAC,IAAsD,EAAE,EAAE;QACjE,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAEjE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,MAAM;gBACrB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;gBAClB,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU;oBAC3B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;oBACjB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,CACT,KAAK,IAAI,KAAK,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAClH,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,oBAAoB;IACpB,QAAQ;SACL,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;SAC/B,MAAM,CAAC,CAAC,IAAwB,EAAE,EAAE;QACnC,MAAM,GAAG,GAAG,eAAe,EAAE,CAAC;QAE9B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACvD,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAC3D,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;QAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QAE9D,MAAM,MAAM,GAAG;YACb,eAAe,EAAE,GAAG,CAAC,MAAM;YAC3B,IAAI;YACJ,SAAS;YACT,OAAO;YACP,WAAW,EACT,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI;YACtE,WAAW,EAAE,OAAO;YACpB,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC;SACjD,CAAC;QAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test generation command — auto-generate Vitest tests from evals.
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* unicli test generate <site> — auto-generate test from eval + current output
|
|
6
|
+
* unicli test ci --changed — test only adapters changed in current commit
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
export declare function registerTestGenCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=test-gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-gen.d.ts","sourceRoot":"","sources":["../../src/commands/test-gen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8I7D"}
|