@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,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Endpoint Analysis — combines analysis.ts filters with
|
|
3
|
+
* response body analysis and auth detection for the discover pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Used by: explore.ts, synthesize.ts, generate.ts, discover.ts
|
|
6
|
+
*/
|
|
7
|
+
import { isNoiseUrl, isStaticResource, isUsefulEndpoint, endpointSortKey, detectCapability, } from "./analysis.js";
|
|
8
|
+
// ── Constants ────────────────────────────────────────────────────────────
|
|
9
|
+
const SEARCH_PARAMS = new Set([
|
|
10
|
+
"query",
|
|
11
|
+
"keyword",
|
|
12
|
+
"q",
|
|
13
|
+
"search",
|
|
14
|
+
"s",
|
|
15
|
+
"wd",
|
|
16
|
+
"kw",
|
|
17
|
+
"keywords",
|
|
18
|
+
]);
|
|
19
|
+
const PAGINATION_PARAMS = new Set([
|
|
20
|
+
"page",
|
|
21
|
+
"p",
|
|
22
|
+
"offset",
|
|
23
|
+
"start",
|
|
24
|
+
"from",
|
|
25
|
+
"pageNum",
|
|
26
|
+
"pn",
|
|
27
|
+
]);
|
|
28
|
+
const LIMIT_PARAMS = new Set([
|
|
29
|
+
"limit",
|
|
30
|
+
"count",
|
|
31
|
+
"size",
|
|
32
|
+
"num",
|
|
33
|
+
"per_page",
|
|
34
|
+
"pageSize",
|
|
35
|
+
"ps",
|
|
36
|
+
]);
|
|
37
|
+
const ID_PARAMS = new Set([
|
|
38
|
+
"id",
|
|
39
|
+
"uid",
|
|
40
|
+
"pid",
|
|
41
|
+
"item_id",
|
|
42
|
+
"user_id",
|
|
43
|
+
"mid",
|
|
44
|
+
"aid",
|
|
45
|
+
"bvid",
|
|
46
|
+
]);
|
|
47
|
+
const ARRAY_FIELD_NAMES = new Set([
|
|
48
|
+
"data",
|
|
49
|
+
"items",
|
|
50
|
+
"results",
|
|
51
|
+
"list",
|
|
52
|
+
"records",
|
|
53
|
+
"entries",
|
|
54
|
+
"rows",
|
|
55
|
+
"hits",
|
|
56
|
+
"posts",
|
|
57
|
+
"articles",
|
|
58
|
+
"comments",
|
|
59
|
+
"nodes",
|
|
60
|
+
]);
|
|
61
|
+
/** Role → candidate field names (order = priority) */
|
|
62
|
+
const ROLE_FIELDS = {
|
|
63
|
+
title: ["title", "name", "headline", "subject", "display_name"],
|
|
64
|
+
url: ["url", "link", "href", "web_url", "share_url", "target_url"],
|
|
65
|
+
author: [
|
|
66
|
+
"author",
|
|
67
|
+
"user",
|
|
68
|
+
"username",
|
|
69
|
+
"creator",
|
|
70
|
+
"nickname",
|
|
71
|
+
"screen_name",
|
|
72
|
+
"user_name",
|
|
73
|
+
],
|
|
74
|
+
score: [
|
|
75
|
+
"score",
|
|
76
|
+
"upvotes",
|
|
77
|
+
"likes",
|
|
78
|
+
"hot",
|
|
79
|
+
"digg_count",
|
|
80
|
+
"voteup_count",
|
|
81
|
+
"like_count",
|
|
82
|
+
"reply_count",
|
|
83
|
+
],
|
|
84
|
+
time: [
|
|
85
|
+
"time",
|
|
86
|
+
"created_at",
|
|
87
|
+
"updated_at",
|
|
88
|
+
"date",
|
|
89
|
+
"publish_time",
|
|
90
|
+
"ctime",
|
|
91
|
+
"create_time",
|
|
92
|
+
"pubdate",
|
|
93
|
+
],
|
|
94
|
+
description: [
|
|
95
|
+
"description",
|
|
96
|
+
"desc",
|
|
97
|
+
"summary",
|
|
98
|
+
"abstract",
|
|
99
|
+
"excerpt",
|
|
100
|
+
"content",
|
|
101
|
+
],
|
|
102
|
+
image: ["image", "cover", "thumbnail", "pic", "avatar", "cover_url", "thumb"],
|
|
103
|
+
id: ["id", "uid", "pid", "item_id", "aid", "bvid", "mid"],
|
|
104
|
+
};
|
|
105
|
+
// ── Query Param Classification ──────────────────────────────────────────
|
|
106
|
+
export function classifyQueryParams(url) {
|
|
107
|
+
const params = [];
|
|
108
|
+
let hasSearch = false;
|
|
109
|
+
let hasPagination = false;
|
|
110
|
+
let hasLimit = false;
|
|
111
|
+
let hasId = false;
|
|
112
|
+
try {
|
|
113
|
+
const u = new URL(url);
|
|
114
|
+
for (const key of u.searchParams.keys()) {
|
|
115
|
+
params.push(key);
|
|
116
|
+
if (SEARCH_PARAMS.has(key))
|
|
117
|
+
hasSearch = true;
|
|
118
|
+
if (PAGINATION_PARAMS.has(key))
|
|
119
|
+
hasPagination = true;
|
|
120
|
+
if (LIMIT_PARAMS.has(key))
|
|
121
|
+
hasLimit = true;
|
|
122
|
+
if (ID_PARAMS.has(key))
|
|
123
|
+
hasId = true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
/* invalid URL */
|
|
128
|
+
}
|
|
129
|
+
return { params, hasSearch, hasPagination, hasLimit, hasId };
|
|
130
|
+
}
|
|
131
|
+
// ── Response Body Analysis ──────────────────────────────────────────────
|
|
132
|
+
export function analyzeResponseBody(body) {
|
|
133
|
+
if (body === null || body === undefined) {
|
|
134
|
+
return { itemPath: null, itemCount: 0, detectedFields: {} };
|
|
135
|
+
}
|
|
136
|
+
let items = null;
|
|
137
|
+
let itemPath = null;
|
|
138
|
+
// Direct array
|
|
139
|
+
if (Array.isArray(body)) {
|
|
140
|
+
items = body;
|
|
141
|
+
itemPath = null; // root is the array
|
|
142
|
+
}
|
|
143
|
+
else if (typeof body === "object") {
|
|
144
|
+
const obj = body;
|
|
145
|
+
// Check known array field names
|
|
146
|
+
for (const key of Object.keys(obj)) {
|
|
147
|
+
if (ARRAY_FIELD_NAMES.has(key) && Array.isArray(obj[key])) {
|
|
148
|
+
items = obj[key];
|
|
149
|
+
itemPath = key;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Fallback: check nested .data.list, .data.items patterns
|
|
154
|
+
if (!items &&
|
|
155
|
+
obj.data &&
|
|
156
|
+
typeof obj.data === "object" &&
|
|
157
|
+
!Array.isArray(obj.data)) {
|
|
158
|
+
const nested = obj.data;
|
|
159
|
+
for (const key of Object.keys(nested)) {
|
|
160
|
+
if (Array.isArray(nested[key]) &&
|
|
161
|
+
nested[key].length > 0) {
|
|
162
|
+
items = nested[key];
|
|
163
|
+
itemPath = `data.${key}`;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!items || items.length === 0) {
|
|
170
|
+
return { itemPath, itemCount: 0, detectedFields: {} };
|
|
171
|
+
}
|
|
172
|
+
// Detect semantic fields from first array item
|
|
173
|
+
const firstItem = items[0];
|
|
174
|
+
const detectedFields = {};
|
|
175
|
+
if (firstItem && typeof firstItem === "object" && !Array.isArray(firstItem)) {
|
|
176
|
+
const itemObj = firstItem;
|
|
177
|
+
const flatKeys = Object.keys(itemObj);
|
|
178
|
+
for (const [role, candidates] of Object.entries(ROLE_FIELDS)) {
|
|
179
|
+
for (const candidate of candidates) {
|
|
180
|
+
// Direct match
|
|
181
|
+
if (flatKeys.includes(candidate) && itemObj[candidate] != null) {
|
|
182
|
+
detectedFields[role] = candidate;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
// Nested match: e.g. author.name, owner.login
|
|
186
|
+
for (const key of flatKeys) {
|
|
187
|
+
const val = itemObj[key];
|
|
188
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
189
|
+
const nested = val;
|
|
190
|
+
if (candidate in nested && nested[candidate] != null) {
|
|
191
|
+
detectedFields[role] = `${key}.${candidate}`;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (detectedFields[role])
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return { itemPath, itemCount: items.length, detectedFields };
|
|
202
|
+
}
|
|
203
|
+
// ── Auth Indicators ─────────────────────────────────────────────────────
|
|
204
|
+
export function detectAuthIndicators(headers) {
|
|
205
|
+
const indicators = [];
|
|
206
|
+
const headerStr = JSON.stringify(headers).toLowerCase();
|
|
207
|
+
if (headerStr.includes("bearer"))
|
|
208
|
+
indicators.push("bearer");
|
|
209
|
+
if (headerStr.includes("x-csrf-token") ||
|
|
210
|
+
headerStr.includes("ct0") ||
|
|
211
|
+
headerStr.includes("bili_jct")) {
|
|
212
|
+
indicators.push("csrf");
|
|
213
|
+
}
|
|
214
|
+
if (headerStr.includes("signature") ||
|
|
215
|
+
headerStr.includes("x-signature") ||
|
|
216
|
+
headerStr.includes("_signature")) {
|
|
217
|
+
indicators.push("signature");
|
|
218
|
+
}
|
|
219
|
+
if (headerStr.includes("cookie"))
|
|
220
|
+
indicators.push("cookie");
|
|
221
|
+
return indicators;
|
|
222
|
+
}
|
|
223
|
+
// ── URL Pattern ─────────────────────────────────────────────────────────
|
|
224
|
+
export function urlToPattern(url) {
|
|
225
|
+
try {
|
|
226
|
+
const u = new URL(url);
|
|
227
|
+
const path = u.pathname
|
|
228
|
+
.split("/")
|
|
229
|
+
.map((seg) => (/^\d{4,}$/.test(seg) ? ":id" : seg))
|
|
230
|
+
.join("/");
|
|
231
|
+
const params = [...u.searchParams.keys()].sort().join(",");
|
|
232
|
+
return `${u.host}${path}${params ? "?" + params : ""}`.toLowerCase();
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return url.toLowerCase();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// ── Main Pipeline ───────────────────────────────────────────────────────
|
|
239
|
+
export function analyzeEndpoints(entries, opts) {
|
|
240
|
+
const top = opts?.top ?? 15;
|
|
241
|
+
const seen = new Map();
|
|
242
|
+
for (const entry of entries) {
|
|
243
|
+
if (!entry.url)
|
|
244
|
+
continue;
|
|
245
|
+
if (isNoiseUrl(entry.url))
|
|
246
|
+
continue;
|
|
247
|
+
if (isStaticResource(entry.url, entry.contentType))
|
|
248
|
+
continue;
|
|
249
|
+
if (!isUsefulEndpoint({
|
|
250
|
+
url: entry.url,
|
|
251
|
+
status: entry.status,
|
|
252
|
+
contentType: entry.contentType,
|
|
253
|
+
body: entry.body,
|
|
254
|
+
})) {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
const pattern = urlToPattern(entry.url);
|
|
258
|
+
const key = `${entry.method}:${pattern}`;
|
|
259
|
+
if (seen.has(key))
|
|
260
|
+
continue;
|
|
261
|
+
const queryParams = classifyQueryParams(entry.url);
|
|
262
|
+
const responseAnalysis = entry.body
|
|
263
|
+
? analyzeResponseBody(entry.body)
|
|
264
|
+
: null;
|
|
265
|
+
const authIndicators = entry.requestHeaders
|
|
266
|
+
? detectAuthIndicators(entry.requestHeaders)
|
|
267
|
+
: [];
|
|
268
|
+
const capability = detectCapability(entry.url, entry.body);
|
|
269
|
+
const sortKey = endpointSortKey({ url: entry.url, body: entry.body });
|
|
270
|
+
seen.set(key, {
|
|
271
|
+
url: entry.url,
|
|
272
|
+
method: entry.method,
|
|
273
|
+
status: entry.status,
|
|
274
|
+
contentType: entry.contentType,
|
|
275
|
+
body: entry.body,
|
|
276
|
+
pattern,
|
|
277
|
+
capability,
|
|
278
|
+
sortKey,
|
|
279
|
+
queryParams,
|
|
280
|
+
authIndicators,
|
|
281
|
+
responseAnalysis,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
// Sort descending by sort key
|
|
285
|
+
return [...seen.values()]
|
|
286
|
+
.sort((a, b) => {
|
|
287
|
+
for (let i = 0; i < 4; i++) {
|
|
288
|
+
if (b.sortKey[i] !== a.sortKey[i])
|
|
289
|
+
return b.sortKey[i] - a.sortKey[i];
|
|
290
|
+
}
|
|
291
|
+
return 0;
|
|
292
|
+
})
|
|
293
|
+
.slice(0, top);
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../src/engine/endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend Framework Detection + Store Discovery.
|
|
3
|
+
*
|
|
4
|
+
* Returns JS source strings for page.evaluate() — the caller executes them.
|
|
5
|
+
* Ported from Open-CLI's scripts/store.ts + detectFramework, adapted for
|
|
6
|
+
* Uni-CLI's evaluate API.
|
|
7
|
+
*/
|
|
8
|
+
export interface FrameworkInfo {
|
|
9
|
+
react: boolean;
|
|
10
|
+
vue: boolean;
|
|
11
|
+
next: boolean;
|
|
12
|
+
nuxt: boolean;
|
|
13
|
+
svelte: boolean;
|
|
14
|
+
angular: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface StoreInfo {
|
|
17
|
+
type: "pinia" | "vuex";
|
|
18
|
+
id: string;
|
|
19
|
+
actions: string[];
|
|
20
|
+
stateKeys: string[];
|
|
21
|
+
}
|
|
22
|
+
/** JS string that returns FrameworkInfo when evaluated in page context. */
|
|
23
|
+
export declare function generateFrameworkDetectJs(): string;
|
|
24
|
+
/** JS string that returns StoreInfo[] when evaluated in page context. */
|
|
25
|
+
export declare function generateStoreDiscoverJs(): string;
|
|
26
|
+
/** Check if Vue store discovery should be attempted. */
|
|
27
|
+
export declare function hasVueStores(framework: FrameworkInfo): boolean;
|
|
28
|
+
//# sourceMappingURL=framework.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework.d.ts","sourceRoot":"","sources":["../../src/engine/framework.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,2EAA2E;AAC3E,wBAAgB,yBAAyB,IAAI,MAAM,CAelD;AAED,yEAAyE;AACzE,wBAAgB,uBAAuB,IAAI,MAAM,CAmChD;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAE9D"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend Framework Detection + Store Discovery.
|
|
3
|
+
*
|
|
4
|
+
* Returns JS source strings for page.evaluate() — the caller executes them.
|
|
5
|
+
* Ported from Open-CLI's scripts/store.ts + detectFramework, adapted for
|
|
6
|
+
* Uni-CLI's evaluate API.
|
|
7
|
+
*/
|
|
8
|
+
/** JS string that returns FrameworkInfo when evaluated in page context. */
|
|
9
|
+
export function generateFrameworkDetectJs() {
|
|
10
|
+
return `(() => {
|
|
11
|
+
try {
|
|
12
|
+
return {
|
|
13
|
+
react: !!(document.querySelector('[data-reactroot]') || document.querySelector('[data-reactid]') || window.__REACT_DEVTOOLS_GLOBAL_HOOK__),
|
|
14
|
+
vue: !!(window.__vue_app__ || (document.querySelector('#app') && document.querySelector('#app').__vue_app__) || window.__VUE__),
|
|
15
|
+
next: !!(window.__NEXT_DATA__ || document.querySelector('#__next')),
|
|
16
|
+
nuxt: !!(window.__NUXT__ || window.__nuxt),
|
|
17
|
+
svelte: !!(document.querySelector('[class*="svelte-"]') || window.__svelte),
|
|
18
|
+
angular: !!(window.ng || document.querySelector('[ng-version]') || window.getAllAngularRootElements),
|
|
19
|
+
};
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return { react: false, vue: false, next: false, nuxt: false, svelte: false, angular: false };
|
|
22
|
+
}
|
|
23
|
+
})()`;
|
|
24
|
+
}
|
|
25
|
+
/** JS string that returns StoreInfo[] when evaluated in page context. */
|
|
26
|
+
export function generateStoreDiscoverJs() {
|
|
27
|
+
return `(() => {
|
|
28
|
+
var stores = [];
|
|
29
|
+
try {
|
|
30
|
+
var app = document.querySelector('#app');
|
|
31
|
+
var vueApp = app && app.__vue_app__;
|
|
32
|
+
if (vueApp) {
|
|
33
|
+
var pinia = vueApp.config && vueApp.config.globalProperties && vueApp.config.globalProperties.$pinia;
|
|
34
|
+
if (pinia && pinia._s) {
|
|
35
|
+
pinia._s.forEach(function(store, id) {
|
|
36
|
+
if (id.charAt(0) === '$' || id.charAt(0) === '_') return;
|
|
37
|
+
var actions = [];
|
|
38
|
+
var stateKeys = [];
|
|
39
|
+
Object.keys(store).forEach(function(key) {
|
|
40
|
+
if (key.charAt(0) === '$' || key.charAt(0) === '_') return;
|
|
41
|
+
if (typeof store[key] === 'function') actions.push(key);
|
|
42
|
+
else stateKeys.push(key);
|
|
43
|
+
});
|
|
44
|
+
stores.push({ type: 'pinia', id: id, actions: actions.slice(0, 20), stateKeys: stateKeys.slice(0, 15) });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
var vuexStore = vueApp.config && vueApp.config.globalProperties && vueApp.config.globalProperties.$store;
|
|
48
|
+
if (vuexStore && vuexStore._modules && vuexStore._modules.root && vuexStore._modules.root._children) {
|
|
49
|
+
var children = vuexStore._modules.root._children;
|
|
50
|
+
Object.keys(children).forEach(function(id) {
|
|
51
|
+
var mod = children[id];
|
|
52
|
+
var actions = mod._rawModule && mod._rawModule.actions ? Object.keys(mod._rawModule.actions) : [];
|
|
53
|
+
var stateKeys = mod.state ? Object.keys(mod.state) : [];
|
|
54
|
+
stores.push({ type: 'vuex', id: id, actions: actions.slice(0, 20), stateKeys: stateKeys.slice(0, 15) });
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {}
|
|
59
|
+
return stores;
|
|
60
|
+
})()`;
|
|
61
|
+
}
|
|
62
|
+
/** Check if Vue store discovery should be attempted. */
|
|
63
|
+
export function hasVueStores(framework) {
|
|
64
|
+
return framework.vue;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=framework.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework.js","sourceRoot":"","sources":["../../src/engine/framework.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkBH,2EAA2E;AAC3E,MAAM,UAAU,yBAAyB;IACvC,OAAO;;;;;;;;;;;;;KAaJ,CAAC;AACN,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCJ,CAAC;AACN,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,YAAY,CAAC,SAAwB;IACnD,OAAO,SAAS,CAAC,GAAG,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive Probing — click elements to trigger API calls.
|
|
3
|
+
*
|
|
4
|
+
* Uses accessibility tree snapshot for smart element selection,
|
|
5
|
+
* with role-aware filtering and dangerous element avoidance.
|
|
6
|
+
*/
|
|
7
|
+
import type { IPage } from "../types.js";
|
|
8
|
+
export interface ProbeOptions {
|
|
9
|
+
maxClicks?: number;
|
|
10
|
+
delayMs?: number;
|
|
11
|
+
labels?: string[];
|
|
12
|
+
roles?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface ProbeResult {
|
|
15
|
+
clicked: number;
|
|
16
|
+
labels: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function probeInteractive(page: IPage, opts?: ProbeOptions): Promise<ProbeResult>;
|
|
19
|
+
//# sourceMappingURL=probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../src/engine/probe.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAOD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,KAAK,EACX,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,WAAW,CAAC,CAmFtB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive Probing — click elements to trigger API calls.
|
|
3
|
+
*
|
|
4
|
+
* Uses accessibility tree snapshot for smart element selection,
|
|
5
|
+
* with role-aware filtering and dangerous element avoidance.
|
|
6
|
+
*/
|
|
7
|
+
const SKIP_PATTERNS = /登录|注册|login|sign.?in|sign.?up|close|关闭|下载.?app|download.?app|cookie|privacy|install/i;
|
|
8
|
+
const PREFER_PATTERNS = /更多|热门|推荐|全部|more|all|popular|trending|hot|load.?more|show.?more|expand/i;
|
|
9
|
+
export async function probeInteractive(page, opts) {
|
|
10
|
+
const maxClicks = opts?.maxClicks ?? 12;
|
|
11
|
+
const delayMs = opts?.delayMs ?? 400;
|
|
12
|
+
const preferredRoles = opts?.roles ?? ["tab", "button", "link"];
|
|
13
|
+
const clicked = [];
|
|
14
|
+
// Step 1: Targeted label clicks
|
|
15
|
+
if (opts?.labels?.length) {
|
|
16
|
+
for (const label of opts.labels) {
|
|
17
|
+
try {
|
|
18
|
+
const safeLabel = JSON.stringify(label);
|
|
19
|
+
await page.evaluate(`(() => {
|
|
20
|
+
const el = [...document.querySelectorAll('button, [role="button"], [role="tab"], a, span')]
|
|
21
|
+
.find(e => e.textContent && e.textContent.trim().includes(${safeLabel}));
|
|
22
|
+
if (el) el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
|
|
23
|
+
})()`);
|
|
24
|
+
clicked.push(label);
|
|
25
|
+
await page.wait(delayMs / 1000);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
/* label not found */
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (clicked.length >= maxClicks) {
|
|
33
|
+
return { clicked: clicked.length, labels: clicked };
|
|
34
|
+
}
|
|
35
|
+
// Step 2: Snapshot-based probing
|
|
36
|
+
try {
|
|
37
|
+
const snap = await page.snapshot({ interactive: true, compact: true });
|
|
38
|
+
// Parse interactive refs from snapshot text
|
|
39
|
+
// Format: [ref=N] tag "text" or [N] text
|
|
40
|
+
const refPattern = /\[(?:ref=)?(\d+)\]\s*(\w+)?\s*"?([^"\n]*)"?/g;
|
|
41
|
+
const refs = [];
|
|
42
|
+
let match;
|
|
43
|
+
while ((match = refPattern.exec(snap)) !== null) {
|
|
44
|
+
refs.push({ ref: match[1], tag: match[2] ?? "", text: match[3] ?? "" });
|
|
45
|
+
}
|
|
46
|
+
// Filter and rank
|
|
47
|
+
const candidates = refs
|
|
48
|
+
.filter((r) => !SKIP_PATTERNS.test(r.text))
|
|
49
|
+
.filter((r) => r.text.trim().length > 0)
|
|
50
|
+
.sort((a, b) => {
|
|
51
|
+
const aPrefer = PREFER_PATTERNS.test(a.text) ? -1 : 0;
|
|
52
|
+
const bPrefer = PREFER_PATTERNS.test(b.text) ? -1 : 0;
|
|
53
|
+
if (aPrefer !== bPrefer)
|
|
54
|
+
return aPrefer - bPrefer;
|
|
55
|
+
const aRole = preferredRoles.indexOf(a.tag.toLowerCase());
|
|
56
|
+
const bRole = preferredRoles.indexOf(b.tag.toLowerCase());
|
|
57
|
+
const aIdx = aRole >= 0 ? aRole : preferredRoles.length;
|
|
58
|
+
const bIdx = bRole >= 0 ? bRole : preferredRoles.length;
|
|
59
|
+
return aIdx - bIdx;
|
|
60
|
+
});
|
|
61
|
+
// Click top candidates
|
|
62
|
+
const remaining = maxClicks - clicked.length;
|
|
63
|
+
for (const cand of candidates.slice(0, remaining)) {
|
|
64
|
+
// Validate ref is numeric-only to prevent CSS selector injection
|
|
65
|
+
if (!/^\d+$/.test(cand.ref))
|
|
66
|
+
continue;
|
|
67
|
+
try {
|
|
68
|
+
await page.evaluate(`(() => {
|
|
69
|
+
const el = document.querySelector('[data-unicli-ref="${cand.ref}"]');
|
|
70
|
+
if (el) el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
|
|
71
|
+
})()`);
|
|
72
|
+
clicked.push(cand.text.slice(0, 30));
|
|
73
|
+
await page.wait(delayMs / 1000);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* click failed */
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* snapshot failed — return what we have */
|
|
82
|
+
}
|
|
83
|
+
return { clicked: clicked.length, labels: clicked };
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/engine/probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AutoResearch Engine — Karpathy-style self-improvement loop.
|
|
3
|
+
*
|
|
4
|
+
* 8-phase loop: precondition → review → modify (Claude Code) →
|
|
5
|
+
* commit → verify (eval) → guard → decide (keep/discard) → log.
|
|
6
|
+
*
|
|
7
|
+
* Adapted from Open-CLI's autoresearch concept, scoped to YAML
|
|
8
|
+
* adapter modification and integrated with Uni-CLI's eval harness.
|
|
9
|
+
*/
|
|
10
|
+
export interface ResearchConfig {
|
|
11
|
+
site: string;
|
|
12
|
+
command?: string;
|
|
13
|
+
goal: string;
|
|
14
|
+
verify: string;
|
|
15
|
+
guard?: string;
|
|
16
|
+
scope: string[];
|
|
17
|
+
metric: string;
|
|
18
|
+
direction: "higher" | "lower";
|
|
19
|
+
maxIterations: number;
|
|
20
|
+
minDelta: number;
|
|
21
|
+
}
|
|
22
|
+
export interface IterationResult {
|
|
23
|
+
iteration: number;
|
|
24
|
+
status: "baseline" | "keep" | "discard" | "crash" | "no-op" | "hook-blocked";
|
|
25
|
+
metric: number;
|
|
26
|
+
description: string;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
}
|
|
29
|
+
export interface ResearchCallbacks {
|
|
30
|
+
onStatus?: (msg: string) => void;
|
|
31
|
+
onIteration?: (result: IterationResult) => void;
|
|
32
|
+
}
|
|
33
|
+
export declare function runResearchLoop(config: ResearchConfig, callbacks?: ResearchCallbacks): Promise<IterationResult[]>;
|
|
34
|
+
export declare function readResearchLog(opts?: {
|
|
35
|
+
site?: string;
|
|
36
|
+
since?: number;
|
|
37
|
+
}): IterationResult[];
|
|
38
|
+
//# sourceMappingURL=research.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/engine/research.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkBH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,cAAc,CAAC;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CACjD;AAkQD,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,SAAS,CAAC,EAAE,iBAAiB,GAC5B,OAAO,CAAC,eAAe,EAAE,CAAC,CAyL5B;AAID,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,eAAe,EAAE,CA0BpB"}
|