@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.
Files changed (98) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +6 -6
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +6 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/agents.d.ts.map +1 -1
  7. package/dist/commands/agents.js +82 -2
  8. package/dist/commands/agents.js.map +1 -1
  9. package/dist/commands/generate.d.ts.map +1 -1
  10. package/dist/commands/generate.js +20 -1
  11. package/dist/commands/generate.js.map +1 -1
  12. package/dist/commands/hub.d.ts +13 -0
  13. package/dist/commands/hub.d.ts.map +1 -0
  14. package/dist/commands/hub.js +232 -0
  15. package/dist/commands/hub.js.map +1 -0
  16. package/dist/commands/research.d.ts +17 -0
  17. package/dist/commands/research.d.ts.map +1 -0
  18. package/dist/commands/research.js +257 -0
  19. package/dist/commands/research.js.map +1 -0
  20. package/dist/commands/test-gen.d.ts +10 -0
  21. package/dist/commands/test-gen.d.ts.map +1 -0
  22. package/dist/commands/test-gen.js +124 -0
  23. package/dist/commands/test-gen.js.map +1 -0
  24. package/dist/discovery/loader.d.ts.map +1 -1
  25. package/dist/discovery/loader.js +3 -0
  26. package/dist/discovery/loader.js.map +1 -1
  27. package/dist/engine/capability.d.ts +40 -0
  28. package/dist/engine/capability.d.ts.map +1 -0
  29. package/dist/engine/capability.js +191 -0
  30. package/dist/engine/capability.js.map +1 -0
  31. package/dist/engine/endpoint.d.ts +47 -0
  32. package/dist/engine/endpoint.d.ts.map +1 -0
  33. package/dist/engine/endpoint.js +295 -0
  34. package/dist/engine/endpoint.js.map +1 -0
  35. package/dist/engine/framework.d.ts +28 -0
  36. package/dist/engine/framework.d.ts.map +1 -0
  37. package/dist/engine/framework.js +66 -0
  38. package/dist/engine/framework.js.map +1 -0
  39. package/dist/engine/probe.d.ts +19 -0
  40. package/dist/engine/probe.d.ts.map +1 -0
  41. package/dist/engine/probe.js +85 -0
  42. package/dist/engine/probe.js.map +1 -0
  43. package/dist/engine/research.d.ts +38 -0
  44. package/dist/engine/research.d.ts.map +1 -0
  45. package/dist/engine/research.js +414 -0
  46. package/dist/engine/research.js.map +1 -0
  47. package/dist/engine/yaml-runner.d.ts.map +1 -1
  48. package/dist/engine/yaml-runner.js +80 -5
  49. package/dist/engine/yaml-runner.js.map +1 -1
  50. package/dist/manifest.json +403 -1
  51. package/dist/mcp/server.js +59 -1
  52. package/dist/mcp/server.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/adapters/cnn/top.yaml +21 -0
  55. package/src/adapters/cocoapods/search.yaml +16 -0
  56. package/src/adapters/crates-io/search.yaml +27 -0
  57. package/src/adapters/docker-hub/search.yaml +26 -0
  58. package/src/adapters/eastmoney/hot.yaml +23 -0
  59. package/src/adapters/eastmoney/search.yaml +25 -0
  60. package/src/adapters/exchangerate/convert.yaml +19 -0
  61. package/src/adapters/feishu/calendar.yaml +24 -0
  62. package/src/adapters/feishu/docs.yaml +17 -0
  63. package/src/adapters/feishu/send.yaml +29 -0
  64. package/src/adapters/feishu/tasks.yaml +24 -0
  65. package/src/adapters/gitee/search.yaml +25 -0
  66. package/src/adapters/gitee/trending.yaml +22 -0
  67. package/src/adapters/gitlab/search.yaml +24 -0
  68. package/src/adapters/gitlab/trending.yaml +22 -0
  69. package/src/adapters/homebrew/info.yaml +15 -0
  70. package/src/adapters/huggingface-papers/daily.yaml +21 -0
  71. package/src/adapters/infoq/articles.yaml +29 -0
  72. package/src/adapters/ip-info/lookup.yaml +15 -0
  73. package/src/adapters/itch-io/popular.yaml +22 -0
  74. package/src/adapters/ithome/news.yaml +21 -0
  75. package/src/adapters/mastodon/search.yaml +29 -0
  76. package/src/adapters/mastodon/trending.yaml +27 -0
  77. package/src/adapters/meituan/search.yaml +30 -0
  78. package/src/adapters/minimax/chat.yaml +33 -0
  79. package/src/adapters/minimax/models.yaml +18 -0
  80. package/src/adapters/minimax/tts.yaml +33 -0
  81. package/src/adapters/netease-music/hot.yaml +24 -0
  82. package/src/adapters/netease-music/search.yaml +29 -0
  83. package/src/adapters/npm-trends/compare.yaml +19 -0
  84. package/src/adapters/nytimes/top.yaml +26 -0
  85. package/src/adapters/openrouter/models.yaml +22 -0
  86. package/src/adapters/pexels/search.yaml +28 -0
  87. package/src/adapters/pinduoduo/hot.yaml +20 -0
  88. package/src/adapters/pypi/info.yaml +16 -0
  89. package/src/adapters/qweather/now.yaml +16 -0
  90. package/src/adapters/replicate/search.yaml +25 -0
  91. package/src/adapters/replicate/trending.yaml +22 -0
  92. package/src/adapters/sspai/hot.yaml +21 -0
  93. package/src/adapters/sspai/latest.yaml +22 -0
  94. package/src/adapters/techcrunch/latest.yaml +22 -0
  95. package/src/adapters/theverge/latest.yaml +21 -0
  96. package/src/adapters/twitch/top.yaml +26 -0
  97. package/src/adapters/unsplash/search.yaml +28 -0
  98. 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"}