@zenalexa/unicli 0.207.1 → 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 (155) hide show
  1. package/AGENTS.md +4 -4
  2. package/README.md +30 -17
  3. package/dist/browser/observe.d.ts +80 -0
  4. package/dist/browser/observe.d.ts.map +1 -0
  5. package/dist/browser/observe.js +144 -0
  6. package/dist/browser/observe.js.map +1 -0
  7. package/dist/browser/snapshot.d.ts.map +1 -1
  8. package/dist/browser/snapshot.js +29 -9
  9. package/dist/browser/snapshot.js.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +59 -2
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/agents.d.ts.map +1 -1
  14. package/dist/commands/agents.js +82 -2
  15. package/dist/commands/agents.js.map +1 -1
  16. package/dist/commands/eval.d.ts +112 -0
  17. package/dist/commands/eval.d.ts.map +1 -0
  18. package/dist/commands/eval.js +485 -0
  19. package/dist/commands/eval.js.map +1 -0
  20. package/dist/commands/generate.d.ts.map +1 -1
  21. package/dist/commands/generate.js +20 -1
  22. package/dist/commands/generate.js.map +1 -1
  23. package/dist/commands/hub.d.ts +13 -0
  24. package/dist/commands/hub.d.ts.map +1 -0
  25. package/dist/commands/hub.js +232 -0
  26. package/dist/commands/hub.js.map +1 -0
  27. package/dist/commands/mcp.d.ts +16 -0
  28. package/dist/commands/mcp.d.ts.map +1 -0
  29. package/dist/commands/mcp.js +135 -0
  30. package/dist/commands/mcp.js.map +1 -0
  31. package/dist/commands/operate.d.ts.map +1 -1
  32. package/dist/commands/operate.js +66 -1
  33. package/dist/commands/operate.js.map +1 -1
  34. package/dist/commands/research.d.ts +17 -0
  35. package/dist/commands/research.d.ts.map +1 -0
  36. package/dist/commands/research.js +257 -0
  37. package/dist/commands/research.js.map +1 -0
  38. package/dist/commands/skills.d.ts +91 -0
  39. package/dist/commands/skills.d.ts.map +1 -0
  40. package/dist/commands/skills.js +266 -0
  41. package/dist/commands/skills.js.map +1 -0
  42. package/dist/commands/test-gen.d.ts +10 -0
  43. package/dist/commands/test-gen.d.ts.map +1 -0
  44. package/dist/commands/test-gen.js +124 -0
  45. package/dist/commands/test-gen.js.map +1 -0
  46. package/dist/commands/usage.d.ts +17 -0
  47. package/dist/commands/usage.d.ts.map +1 -0
  48. package/dist/commands/usage.js +87 -0
  49. package/dist/commands/usage.js.map +1 -0
  50. package/dist/discovery/loader.d.ts +8 -1
  51. package/dist/discovery/loader.d.ts.map +1 -1
  52. package/dist/discovery/loader.js +103 -6
  53. package/dist/discovery/loader.js.map +1 -1
  54. package/dist/engine/capability.d.ts +40 -0
  55. package/dist/engine/capability.d.ts.map +1 -0
  56. package/dist/engine/capability.js +191 -0
  57. package/dist/engine/capability.js.map +1 -0
  58. package/dist/engine/endpoint.d.ts +47 -0
  59. package/dist/engine/endpoint.d.ts.map +1 -0
  60. package/dist/engine/endpoint.js +295 -0
  61. package/dist/engine/endpoint.js.map +1 -0
  62. package/dist/engine/framework.d.ts +28 -0
  63. package/dist/engine/framework.d.ts.map +1 -0
  64. package/dist/engine/framework.js +66 -0
  65. package/dist/engine/framework.js.map +1 -0
  66. package/dist/engine/probe.d.ts +19 -0
  67. package/dist/engine/probe.d.ts.map +1 -0
  68. package/dist/engine/probe.js +85 -0
  69. package/dist/engine/probe.js.map +1 -0
  70. package/dist/engine/research.d.ts +38 -0
  71. package/dist/engine/research.d.ts.map +1 -0
  72. package/dist/engine/research.js +414 -0
  73. package/dist/engine/research.js.map +1 -0
  74. package/dist/engine/update-check.js +1 -1
  75. package/dist/engine/update-check.js.map +1 -1
  76. package/dist/engine/yaml-runner.d.ts.map +1 -1
  77. package/dist/engine/yaml-runner.js +115 -6
  78. package/dist/engine/yaml-runner.js.map +1 -1
  79. package/dist/main.d.ts +1 -4
  80. package/dist/main.d.ts.map +1 -1
  81. package/dist/main.js +1 -4
  82. package/dist/main.js.map +1 -1
  83. package/dist/manifest.json +519 -1
  84. package/dist/mcp/server.d.ts +19 -6
  85. package/dist/mcp/server.d.ts.map +1 -1
  86. package/dist/mcp/server.js +459 -115
  87. package/dist/mcp/server.js.map +1 -1
  88. package/dist/permissions/sensitive-paths.d.ts +92 -0
  89. package/dist/permissions/sensitive-paths.d.ts.map +1 -0
  90. package/dist/permissions/sensitive-paths.js +174 -0
  91. package/dist/permissions/sensitive-paths.js.map +1 -0
  92. package/dist/runtime/usage-ledger.d.ts +86 -0
  93. package/dist/runtime/usage-ledger.d.ts.map +1 -0
  94. package/dist/runtime/usage-ledger.js +173 -0
  95. package/dist/runtime/usage-ledger.js.map +1 -0
  96. package/package.json +8 -7
  97. package/src/adapters/autoagent/eval-run.yaml +36 -0
  98. package/src/adapters/cnn/top.yaml +21 -0
  99. package/src/adapters/cocoapods/search.yaml +16 -0
  100. package/src/adapters/crates-io/search.yaml +27 -0
  101. package/src/adapters/cua/bench-list.yaml +20 -0
  102. package/src/adapters/cua/bench-run.yaml +32 -0
  103. package/src/adapters/docker-hub/search.yaml +26 -0
  104. package/src/adapters/eastmoney/hot.yaml +23 -0
  105. package/src/adapters/eastmoney/search.yaml +25 -0
  106. package/src/adapters/exchangerate/convert.yaml +19 -0
  107. package/src/adapters/feishu/calendar.yaml +24 -0
  108. package/src/adapters/feishu/docs.yaml +17 -0
  109. package/src/adapters/feishu/send.yaml +29 -0
  110. package/src/adapters/feishu/tasks.yaml +24 -0
  111. package/src/adapters/gitee/search.yaml +25 -0
  112. package/src/adapters/gitee/trending.yaml +22 -0
  113. package/src/adapters/gitlab/search.yaml +24 -0
  114. package/src/adapters/gitlab/trending.yaml +22 -0
  115. package/src/adapters/godot/project-run.yaml +31 -0
  116. package/src/adapters/godot/scene-export.yaml +39 -0
  117. package/src/adapters/hermes/sessions-search.yaml +61 -0
  118. package/src/adapters/hermes/skills-list.yaml +30 -0
  119. package/src/adapters/hermes/skills-read.yaml +46 -0
  120. package/src/adapters/homebrew/info.yaml +15 -0
  121. package/src/adapters/huggingface-papers/daily.yaml +21 -0
  122. package/src/adapters/infoq/articles.yaml +29 -0
  123. package/src/adapters/ip-info/lookup.yaml +15 -0
  124. package/src/adapters/itch-io/popular.yaml +22 -0
  125. package/src/adapters/ithome/news.yaml +21 -0
  126. package/src/adapters/mastodon/search.yaml +29 -0
  127. package/src/adapters/mastodon/trending.yaml +27 -0
  128. package/src/adapters/meituan/search.yaml +30 -0
  129. package/src/adapters/minimax/chat.yaml +33 -0
  130. package/src/adapters/minimax/models.yaml +18 -0
  131. package/src/adapters/minimax/tts.yaml +33 -0
  132. package/src/adapters/motion-studio/component-get.yaml +35 -0
  133. package/src/adapters/netease-music/hot.yaml +24 -0
  134. package/src/adapters/netease-music/search.yaml +29 -0
  135. package/src/adapters/npm-trends/compare.yaml +19 -0
  136. package/src/adapters/nytimes/top.yaml +26 -0
  137. package/src/adapters/openharness/memory-read.yaml +51 -0
  138. package/src/adapters/openharness/skills-list.yaml +28 -0
  139. package/src/adapters/openrouter/models.yaml +22 -0
  140. package/src/adapters/pexels/search.yaml +28 -0
  141. package/src/adapters/pinduoduo/hot.yaml +20 -0
  142. package/src/adapters/pypi/info.yaml +16 -0
  143. package/src/adapters/qweather/now.yaml +16 -0
  144. package/src/adapters/renderdoc/capture-list.yaml +42 -0
  145. package/src/adapters/renderdoc/frame-export.yaml +32 -0
  146. package/src/adapters/replicate/search.yaml +25 -0
  147. package/src/adapters/replicate/trending.yaml +22 -0
  148. package/src/adapters/sspai/hot.yaml +21 -0
  149. package/src/adapters/sspai/latest.yaml +22 -0
  150. package/src/adapters/stagehand/wrap-observe.yaml +42 -0
  151. package/src/adapters/techcrunch/latest.yaml +22 -0
  152. package/src/adapters/theverge/latest.yaml +21 -0
  153. package/src/adapters/twitch/top.yaml +26 -0
  154. package/src/adapters/unsplash/search.yaml +28 -0
  155. package/src/adapters/ycombinator/launches.yaml +20 -0
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Capability Inference — map analyzed endpoints to CLI capabilities.
3
+ *
4
+ * Determines what a site can do (search, hot, feed, detail, etc.),
5
+ * what columns to display, what arguments to accept, and which
6
+ * pipeline pattern to use for adapter generation.
7
+ */
8
+ // ── Goal Aliases (EN + ZH, 12 capabilities) ─────────────────────────────
9
+ const CAPABILITY_ALIASES = {
10
+ search: ["search", "query", "find", "搜索", "查找", "检索"],
11
+ hot: [
12
+ "hot",
13
+ "trending",
14
+ "popular",
15
+ "rank",
16
+ "top",
17
+ "热门",
18
+ "热榜",
19
+ "排行",
20
+ "榜单",
21
+ ],
22
+ feed: ["feed", "timeline", "latest", "new", "stream", "最新", "动态", "推荐"],
23
+ profile: ["profile", "user", "me", "account", "个人", "用户", "我的"],
24
+ detail: ["detail", "item", "article", "post", "详情", "文章"],
25
+ comments: ["comments", "replies", "review", "评论", "回复"],
26
+ history: ["history", "recent", "历史", "最近"],
27
+ favorite: ["favorite", "bookmark", "star", "like", "收藏", "点赞"],
28
+ download: ["download", "save", "export", "下载", "导出"],
29
+ create: ["create", "post", "publish", "write", "发布", "创建"],
30
+ list: ["list", "index", "all", "列表", "全部"],
31
+ follow: ["follow", "subscribe", "关注", "订阅"],
32
+ };
33
+ // ── Goal Matching ───────────────────────────────────────────────────────
34
+ export function normalizeGoal(goal) {
35
+ if (!goal)
36
+ return null;
37
+ const lower = goal.toLowerCase().trim();
38
+ for (const [key, aliases] of Object.entries(CAPABILITY_ALIASES)) {
39
+ if (aliases.some((a) => lower.includes(a)))
40
+ return key;
41
+ }
42
+ return null;
43
+ }
44
+ export function selectBestCapability(capabilities, goal) {
45
+ if (capabilities.length === 0)
46
+ return null;
47
+ const normalized = normalizeGoal(goal);
48
+ if (normalized) {
49
+ // Exact match
50
+ const exact = capabilities.find((c) => c.name === normalized);
51
+ if (exact)
52
+ return exact;
53
+ // Substring match (bidirectional)
54
+ const partial = capabilities.find((c) => c.name.includes(normalized) || normalized.includes(c.name));
55
+ if (partial)
56
+ return partial;
57
+ }
58
+ // Default: first capability (highest-scored endpoint)
59
+ return capabilities[0];
60
+ }
61
+ // ── Strategy Inference ──────────────────────────────────────────────────
62
+ function inferStrategy(authIndicators) {
63
+ if (authIndicators.includes("signature"))
64
+ return "intercept";
65
+ if (authIndicators.includes("bearer") || authIndicators.includes("csrf"))
66
+ return "header";
67
+ if (authIndicators.includes("cookie"))
68
+ return "cookie";
69
+ return "public";
70
+ }
71
+ function inferPipelinePattern(strategy, hasStoreHint) {
72
+ if (hasStoreHint)
73
+ return "store-action";
74
+ switch (strategy) {
75
+ case "public":
76
+ return "public-fetch";
77
+ case "cookie":
78
+ return "cookie-fetch";
79
+ case "header":
80
+ return "browser-evaluate";
81
+ case "intercept":
82
+ return "intercept";
83
+ default:
84
+ return "public-fetch";
85
+ }
86
+ }
87
+ // ── Capability Inference ────────────────────────────────────────────────
88
+ const COLUMN_ROLE_ORDER = [
89
+ "title",
90
+ "url",
91
+ "author",
92
+ "score",
93
+ "time",
94
+ "description",
95
+ "image",
96
+ ];
97
+ export function inferCapabilities(endpoints, stores, options) {
98
+ const capabilities = [];
99
+ const usedNames = new Set();
100
+ for (const ep of endpoints.slice(0, 8)) {
101
+ // Capability name
102
+ let capName = ep.capability ?? "data";
103
+ if (usedNames.has(capName)) {
104
+ const suffix = ep.pattern
105
+ .split("/")
106
+ .filter((s) => s && !s.startsWith(":") && !s.includes("."))
107
+ .pop();
108
+ capName = suffix
109
+ ? `${capName}-${suffix}`
110
+ : `${capName}-${usedNames.size}`;
111
+ }
112
+ usedNames.add(capName);
113
+ // Columns from detected fields
114
+ const columns = [];
115
+ if (ep.responseAnalysis?.detectedFields) {
116
+ for (const role of COLUMN_ROLE_ORDER) {
117
+ if (ep.responseAnalysis.detectedFields[role]) {
118
+ columns.push(role);
119
+ }
120
+ }
121
+ }
122
+ if (columns.length === 0)
123
+ columns.push("title", "url");
124
+ // Args from query params
125
+ const args = [];
126
+ if (ep.queryParams.hasSearch) {
127
+ args.push({
128
+ name: "query",
129
+ type: "string",
130
+ required: true,
131
+ positional: true,
132
+ description: "Search keyword",
133
+ });
134
+ }
135
+ args.push({
136
+ name: "limit",
137
+ type: "int",
138
+ required: false,
139
+ default: 20,
140
+ description: "Number of items to return",
141
+ });
142
+ if (ep.queryParams.hasPagination) {
143
+ args.push({
144
+ name: "page",
145
+ type: "int",
146
+ required: false,
147
+ default: 1,
148
+ description: "Page number",
149
+ });
150
+ }
151
+ if (ep.queryParams.hasId) {
152
+ args.push({
153
+ name: "id",
154
+ type: "string",
155
+ required: true,
156
+ positional: true,
157
+ description: "Item ID",
158
+ });
159
+ }
160
+ // Strategy
161
+ const strategy = inferStrategy(ep.authIndicators);
162
+ // Store hint matching
163
+ let storeHint;
164
+ if ((strategy === "intercept" || ep.authIndicators.includes("signature")) &&
165
+ stores.length > 0) {
166
+ for (const s of stores) {
167
+ const matchingAction = s.actions.find((a) => capName.split("-").some((part) => a.toLowerCase().includes(part)) ||
168
+ a.toLowerCase().includes("fetch") ||
169
+ a.toLowerCase().includes("get"));
170
+ if (matchingAction) {
171
+ storeHint = { store: s.id, action: matchingAction };
172
+ break;
173
+ }
174
+ }
175
+ }
176
+ const pipelinePattern = inferPipelinePattern(strategy, !!storeHint);
177
+ capabilities.push({
178
+ name: capName,
179
+ description: `${options.site} ${capName}`,
180
+ strategy: storeHint ? "intercept" : strategy,
181
+ endpoint: ep,
182
+ itemPath: ep.responseAnalysis?.itemPath ?? null,
183
+ columns,
184
+ args,
185
+ storeHint,
186
+ pipelinePattern,
187
+ });
188
+ }
189
+ return capabilities;
190
+ }
191
+ //# sourceMappingURL=capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability.js","sourceRoot":"","sources":["../../src/engine/capability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
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
+ export interface NetworkEntry {
8
+ url: string;
9
+ method: string;
10
+ status: number;
11
+ contentType: string;
12
+ body?: unknown;
13
+ requestHeaders?: Record<string, string>;
14
+ }
15
+ export interface QueryParamClassification {
16
+ params: string[];
17
+ hasSearch: boolean;
18
+ hasPagination: boolean;
19
+ hasLimit: boolean;
20
+ hasId: boolean;
21
+ }
22
+ export interface ResponseAnalysis {
23
+ itemPath: string | null;
24
+ itemCount: number;
25
+ detectedFields: Record<string, string>;
26
+ }
27
+ export interface AnalyzedEndpoint {
28
+ url: string;
29
+ method: string;
30
+ status: number;
31
+ contentType: string;
32
+ body?: unknown;
33
+ pattern: string;
34
+ capability: string | null;
35
+ sortKey: [number, number, number, number];
36
+ queryParams: QueryParamClassification;
37
+ authIndicators: string[];
38
+ responseAnalysis: ResponseAnalysis | null;
39
+ }
40
+ export declare function classifyQueryParams(url: string): QueryParamClassification;
41
+ export declare function analyzeResponseBody(body: unknown): ResponseAnalysis;
42
+ export declare function detectAuthIndicators(headers: Record<string, string>): string[];
43
+ export declare function urlToPattern(url: string): string;
44
+ export declare function analyzeEndpoints(entries: NetworkEntry[], opts?: {
45
+ top?: number;
46
+ }): AnalyzedEndpoint[];
47
+ //# sourceMappingURL=endpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../../src/engine/endpoint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,WAAW,EAAE,wBAAwB,CAAC;IACtC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC3C;AAyGD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,wBAAwB,CAqBzE;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CA+EnE;AAID,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,EAAE,CAsBV;AAID,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYhD;AAID,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EAAE,EACvB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,gBAAgB,EAAE,CAyDpB"}
@@ -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"}