hunter-mate 0.1.6 → 0.1.8
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/dist/assets/extension/background/service-worker.js +911 -159
- package/dist/assets/extension/build-info.json +1 -0
- package/dist/assets/extension/content/index.js +22 -4
- package/dist/assets/extension/manifest.json +5 -4
- package/dist/assets/extension/offscreen/offscreen.html +8 -0
- package/dist/assets/extension/offscreen/offscreen.js +149 -0
- package/dist/assets/extension/package.json +12 -4
- package/dist/assets/extension/sidepanel/index.css +2 -0
- package/dist/assets/extension/sidepanel/index.html +7 -394
- package/dist/assets/extension/sidepanel/index.js +53 -923
- package/dist/assets/server/app.module.js +12 -1
- package/dist/assets/server/app.module.js.map +1 -1
- package/dist/assets/server/auth/auth.controller.d.ts +7 -0
- package/dist/assets/server/auth/auth.controller.js +20 -0
- package/dist/assets/server/auth/auth.controller.js.map +1 -1
- package/dist/assets/server/auth/auth.middleware.js +9 -1
- package/dist/assets/server/auth/auth.middleware.js.map +1 -1
- package/dist/assets/server/auth/auth.service.d.ts +11 -0
- package/dist/assets/server/auth/auth.service.js +58 -1
- package/dist/assets/server/auth/auth.service.js.map +1 -1
- package/dist/assets/server/build-info.json +1 -1
- package/dist/assets/server/customer/customer.controller.d.ts +18 -0
- package/dist/assets/server/customer/customer.controller.js +81 -0
- package/dist/assets/server/customer/customer.controller.js.map +1 -0
- package/dist/assets/server/customer/customer.entity.d.ts +17 -0
- package/dist/assets/server/customer/customer.entity.js +82 -0
- package/dist/assets/server/customer/customer.entity.js.map +1 -0
- package/dist/assets/server/customer/customer.module.d.ts +2 -0
- package/dist/assets/server/customer/customer.module.js +28 -0
- package/dist/assets/server/customer/customer.module.js.map +1 -0
- package/dist/assets/server/customer/customer.service.d.ts +36 -0
- package/dist/assets/server/customer/customer.service.js +200 -0
- package/dist/assets/server/customer/customer.service.js.map +1 -0
- package/dist/assets/server/db/schema-validator.service.d.ts +2 -0
- package/dist/assets/server/db/schema-validator.service.js +32 -1
- package/dist/assets/server/db/schema-validator.service.js.map +1 -1
- package/dist/assets/server/db/sqlite.module.d.ts +1 -0
- package/dist/assets/server/db/sqlite.module.js +12 -2
- package/dist/assets/server/db/sqlite.module.js.map +1 -1
- package/dist/assets/server/devops/devops-sink-init.d.ts +1 -14
- package/dist/assets/server/devops/devops-sink-init.js +3 -8
- package/dist/assets/server/devops/devops-sink-init.js.map +1 -1
- package/dist/assets/server/extension/extension-control.controller.d.ts +15 -0
- package/dist/assets/server/extension/extension-control.controller.js +42 -2
- package/dist/assets/server/extension/extension-control.controller.js.map +1 -1
- package/dist/assets/server/extension/extension-control.service.d.ts +14 -1
- package/dist/assets/server/extension/extension-control.service.js +65 -2
- package/dist/assets/server/extension/extension-control.service.js.map +1 -1
- package/dist/assets/server/extraction/adapter.service.d.ts +3 -0
- package/dist/assets/server/extraction/adapter.service.js +127 -6
- package/dist/assets/server/extraction/adapter.service.js.map +1 -1
- package/dist/assets/server/extraction/anomaly-report.service.js +1 -1
- package/dist/assets/server/extraction/anomaly-report.service.js.map +1 -1
- package/dist/assets/server/extraction/entities/adapter-rule.entity.d.ts +2 -0
- package/dist/assets/server/extraction/entities/adapter-rule.entity.js +10 -0
- package/dist/assets/server/extraction/entities/adapter-rule.entity.js.map +1 -1
- package/dist/assets/server/extraction/extraction-entity.controller.d.ts +21 -3
- package/dist/assets/server/extraction/extraction-entity.controller.js +44 -9
- package/dist/assets/server/extraction/extraction-entity.controller.js.map +1 -1
- package/dist/assets/server/extraction/extraction.module.js +13 -3
- package/dist/assets/server/extraction/extraction.module.js.map +1 -1
- package/dist/assets/server/extraction/extraction.service.d.ts +4 -1
- package/dist/assets/server/extraction/extraction.service.js +59 -4
- package/dist/assets/server/extraction/extraction.service.js.map +1 -1
- package/dist/assets/server/extraction/harness-overlay.service.d.ts +41 -0
- package/dist/assets/server/extraction/harness-overlay.service.js +319 -0
- package/dist/assets/server/extraction/harness-overlay.service.js.map +1 -0
- package/dist/assets/server/extraction/liepin-extractor.d.ts +1 -0
- package/dist/assets/server/extraction/liepin-extractor.js +172 -0
- package/dist/assets/server/extraction/liepin-extractor.js.map +1 -0
- package/dist/assets/server/extraction/script-rule.js +4 -0
- package/dist/assets/server/extraction/script-rule.js.map +1 -1
- package/dist/assets/server/governance/action-audit.entity.d.ts +12 -0
- package/dist/assets/server/governance/action-audit.entity.js +66 -0
- package/dist/assets/server/governance/action-audit.entity.js.map +1 -0
- package/dist/assets/server/governance/governance.controller.d.ts +14 -0
- package/dist/assets/server/governance/governance.controller.js +77 -0
- package/dist/assets/server/governance/governance.controller.js.map +1 -0
- package/dist/assets/server/governance/governance.ingester.d.ts +20 -0
- package/dist/assets/server/governance/governance.ingester.js +114 -0
- package/dist/assets/server/governance/governance.ingester.js.map +1 -0
- package/dist/assets/server/governance/governance.module.d.ts +2 -0
- package/dist/assets/server/governance/governance.module.js +26 -0
- package/dist/assets/server/governance/governance.module.js.map +1 -0
- package/dist/assets/server/governance/governance.service.d.ts +114 -0
- package/dist/assets/server/governance/governance.service.js +356 -0
- package/dist/assets/server/governance/governance.service.js.map +1 -0
- package/dist/assets/server/jobcase/jobcase.controller.d.ts +1 -0
- package/dist/assets/server/jobcase/jobcase.entity.d.ts +1 -0
- package/dist/assets/server/jobcase/jobcase.entity.js +6 -0
- package/dist/assets/server/jobcase/jobcase.entity.js.map +1 -1
- package/dist/assets/server/jobcase/jobcase.service.d.ts +2 -0
- package/dist/assets/server/jobcase/jobcase.service.js +2 -1
- package/dist/assets/server/jobcase/jobcase.service.js.map +1 -1
- package/dist/assets/server/main.js +1 -0
- package/dist/assets/server/main.js.map +1 -1
- package/dist/assets/server/package.json +5 -4
- package/dist/assets/server/preference/preference.controller.d.ts +14 -0
- package/dist/assets/server/preference/preference.controller.js +66 -0
- package/dist/assets/server/preference/preference.controller.js.map +1 -0
- package/dist/assets/server/preference/preference.entity.d.ts +13 -0
- package/dist/assets/server/preference/preference.entity.js +77 -0
- package/dist/assets/server/preference/preference.entity.js.map +1 -0
- package/dist/assets/server/preference/preference.module.d.ts +2 -0
- package/dist/assets/server/preference/preference.module.js +26 -0
- package/dist/assets/server/preference/preference.module.js.map +1 -0
- package/dist/assets/server/preference/preference.service.d.ts +33 -0
- package/dist/assets/server/preference/preference.service.js +122 -0
- package/dist/assets/server/preference/preference.service.js.map +1 -0
- package/dist/assets/server/recording/recording-event-queue.service.d.ts +26 -0
- package/dist/assets/server/recording/recording-event-queue.service.js +115 -0
- package/dist/assets/server/recording/recording-event-queue.service.js.map +1 -0
- package/dist/assets/server/recording/recording-retention.service.d.ts +38 -0
- package/dist/assets/server/recording/recording-retention.service.js +174 -0
- package/dist/assets/server/recording/recording-retention.service.js.map +1 -0
- package/dist/assets/server/recording/recording-snapshot.service.d.ts +1 -0
- package/dist/assets/server/recording/recording-snapshot.service.js +4 -0
- package/dist/assets/server/recording/recording-snapshot.service.js.map +1 -1
- package/dist/assets/server/recording/recording.controller.d.ts +21 -1
- package/dist/assets/server/recording/recording.controller.js +37 -2
- package/dist/assets/server/recording/recording.controller.js.map +1 -1
- package/dist/assets/server/recording/recording.gateway.js +11 -0
- package/dist/assets/server/recording/recording.gateway.js.map +1 -1
- package/dist/assets/server/recording/recording.module.js +16 -2
- package/dist/assets/server/recording/recording.module.js.map +1 -1
- package/dist/assets/server/recording/recording.service.d.ts +10 -1
- package/dist/assets/server/recording/recording.service.js +31 -6
- package/dist/assets/server/recording/recording.service.js.map +1 -1
- package/dist/assets/server/remark/remark.controller.d.ts +1 -1
- package/dist/assets/server/remark/remark.controller.js +1 -10
- package/dist/assets/server/remark/remark.controller.js.map +1 -1
- package/dist/assets/server/remark/remark.entity.d.ts +1 -1
- package/dist/assets/server/remark/remark.entity.js.map +1 -1
- package/dist/assets/server/site/entities/site-registry.entity.d.ts +1 -1
- package/dist/assets/server/site/entities/site-registry.entity.js +1 -1
- package/dist/assets/server/site/entities/site-registry.entity.js.map +1 -1
- package/dist/assets/server/site/site.controller.d.ts +1 -1
- package/dist/assets/server/site/site.service.d.ts +5 -1
- package/dist/assets/server/site/site.service.js +13 -0
- package/dist/assets/server/site/site.service.js.map +1 -1
- package/dist/assets/server/system/system.controller.d.ts +1 -0
- package/dist/assets/server/system/system.controller.js +1 -1
- package/dist/assets/server/system/system.controller.js.map +1 -1
- package/dist/assets/server/system/system.service.d.ts +1 -0
- package/dist/assets/server/system/system.service.js +3 -2
- package/dist/assets/server/system/system.service.js.map +1 -1
- package/dist/cache/db.js +6 -6
- package/dist/commands/addons.js +2 -1
- package/dist/commands/cache.js +3 -4
- package/dist/commands/case.d.ts +67 -0
- package/dist/commands/case.js +101 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.js +8 -1
- package/dist/commands/customer.d.ts +25 -0
- package/dist/commands/customer.js +137 -0
- package/dist/commands/doctor.js +119 -13
- package/dist/commands/extension.js +26 -32
- package/dist/commands/extras.d.ts +22 -3
- package/dist/commands/extras.js +116 -7
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +3 -4
- package/dist/commands/issue-env.d.ts +23 -0
- package/dist/commands/issue-env.js +101 -0
- package/dist/commands/job.d.ts +6 -2
- package/dist/commands/job.js +75 -20
- package/dist/commands/login.d.ts +19 -0
- package/dist/commands/login.js +85 -13
- package/dist/commands/migrate.d.ts +32 -0
- package/dist/commands/migrate.js +116 -0
- package/dist/commands/note.d.ts +3 -0
- package/dist/commands/note.js +75 -0
- package/dist/commands/ops.js +82 -15
- package/dist/commands/preference.d.ts +6 -0
- package/dist/commands/preference.js +80 -0
- package/dist/commands/record.js +2 -4
- package/dist/commands/report.js +2 -4
- package/dist/commands/search.js +9 -2
- package/dist/commands/server.d.ts +9 -2
- package/dist/commands/server.js +118 -19
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.js +16 -6
- package/dist/commands/update.js +8 -9
- package/dist/config.d.ts +21 -0
- package/dist/config.js +27 -0
- package/dist/i18n/locales/en-US.json +19 -1
- package/dist/i18n/locales/zh-CN.json +19 -1
- package/dist/index.js +52 -2
- package/dist/keychain.d.ts +16 -1
- package/dist/keychain.js +43 -16
- package/dist/logger.js +2 -2
- package/dist/updater.d.ts +1 -1
- package/dist/updater.js +24 -7
- package/dist/utils/command-error.d.ts +11 -0
- package/dist/utils/command-error.js +47 -0
- package/dist/utils/link.d.ts +18 -0
- package/dist/utils/link.js +83 -0
- package/dist/utils/proxy-detect.d.ts +20 -0
- package/dist/utils/proxy-detect.js +96 -0
- package/dist/utils/script-path.d.ts +5 -0
- package/dist/utils/script-path.js +27 -0
- package/dist/version.js +34 -9
- package/dist/watchdog.d.ts +23 -1
- package/dist/watchdog.js +97 -6
- package/dist/web/dist/404.html +1 -0
- package/dist/web/dist/_next/static/WdJr3NhHjlu5xN0qOap1k/_buildManifest.js +1 -0
- package/dist/web/dist/_next/static/WdJr3NhHjlu5xN0qOap1k/_ssgManifest.js +1 -0
- package/dist/web/dist/_next/static/chunks/166.f30be223f694f8ee.js +1 -0
- package/dist/web/dist/_next/static/chunks/1e6d5a0c.0488932e17ecdf24.js +15 -0
- package/dist/web/dist/_next/static/chunks/539-5d0e8c5c238c56f8.js +1 -0
- package/dist/web/dist/_next/static/chunks/589-d632233641f35681.js +1 -0
- package/dist/web/dist/_next/static/chunks/671.3b8e9cc96b25b6ea.js +1 -0
- package/dist/web/dist/_next/static/chunks/935-99f57b7d4151d9e7.js +5 -0
- package/dist/web/dist/_next/static/chunks/a7067448-96dd4b8457c447e8.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/_not-found/page-fdf1a13a7656886a.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/auth/verify/page-8e5cff53d6f7d8e1.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/companies/page-e38a69e1929d0953.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/entity/page-250f8a9b6d91ab19.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/jobs/page-6a281776fec065f6.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/layout-83e623e973c1693f.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/logs/page-d478031d49f7ba00.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/matching/jobs/[id]/talents/page-f57f4b7529823601.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/matching/portraits/[id]/jobs/page-614d1e62d7b9d215.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/page-e3392de08ae81fba.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/parselog/page-58d3acece95b4089.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/recordings/page-e2e2e3c3a64083fb.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/snapshots/[id]/agent-prompt/page-fd3b7d7373b8f8b7.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/talents/page-30748338da20d7e0.js +1 -0
- package/dist/web/dist/_next/static/chunks/framework-b3a558b17a070965.js +1 -0
- package/dist/web/dist/_next/static/chunks/main-5a4e0cd75dd7f04b.js +1 -0
- package/dist/web/dist/_next/static/chunks/main-app-80b038a312917d90.js +1 -0
- package/dist/web/dist/_next/static/chunks/pages/_app-da7d628f49271ece.js +4 -0
- package/dist/web/dist/_next/static/chunks/pages/_error-17756f67e0a11350.js +1 -0
- package/dist/web/dist/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/web/dist/_next/static/chunks/webpack-1784baecc6fdcf0b.js +1 -0
- package/dist/web/dist/_next/static/css/db881c5b3072b88a.css +3 -0
- package/dist/web/dist/_next/static/css/f60d210841fab76b.css +1 -0
- package/dist/web/dist/auth/verify.html +1 -0
- package/dist/web/dist/auth/verify.txt +8 -0
- package/dist/web/dist/companies.html +1 -0
- package/dist/web/dist/companies.txt +7 -0
- package/dist/web/dist/entity.html +1 -0
- package/dist/web/dist/entity.txt +8 -0
- package/dist/web/dist/index.html +1 -0
- package/dist/web/dist/index.txt +8 -0
- package/dist/web/dist/jobs.html +1 -0
- package/dist/web/dist/jobs.txt +7 -0
- package/dist/web/dist/logs.html +1 -0
- package/dist/web/dist/logs.txt +8 -0
- package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -0
- package/dist/web/dist/matching/jobs/placeholder/talents.txt +8 -0
- package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -0
- package/dist/web/dist/matching/portraits/placeholder/jobs.txt +8 -0
- package/dist/web/dist/parselog.html +1 -0
- package/dist/web/dist/parselog.txt +8 -0
- package/dist/web/dist/recordings.html +1 -0
- package/dist/web/dist/recordings.txt +8 -0
- package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -0
- package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +8 -0
- package/dist/web/dist/talents.html +1 -0
- package/dist/web/dist/talents.txt +7 -0
- package/package.json +26 -6
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ProxyEnvEntry {
|
|
2
|
+
varName: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
export interface DeadProxyFinding {
|
|
6
|
+
varName: string;
|
|
7
|
+
value: string;
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
reason: 'refused' | 'timeout' | 'unreachable';
|
|
11
|
+
}
|
|
12
|
+
/** 收集四个代理环境变量中已设置的项 */
|
|
13
|
+
export declare function collectProxyEnv(): ProxyEnvEntry[];
|
|
14
|
+
/**
|
|
15
|
+
* 找出指向 loopback 但端口不通的死代理。
|
|
16
|
+
* 远程代理(非 loopback)不探测,直接视为有效(由网络栈自己处理)。
|
|
17
|
+
*/
|
|
18
|
+
export declare function findDeadProxies(timeoutMs?: number): Promise<DeadProxyFinding[]>;
|
|
19
|
+
/** 生成各 shell 的清除指令提示(用户直接复制执行) */
|
|
20
|
+
export declare function buildUnsetHint(findings: DeadProxyFinding[]): string;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 死代理检测 — Windows/终端现场高频坑。
|
|
3
|
+
*
|
|
4
|
+
* 背景:用户的 shell 环境变量里可能残留指向已关闭本地代理的
|
|
5
|
+
* HTTP_PROXY / HTTPS_PROXY / http_proxy / https_proxy(如 http://127.0.0.1:1962)。
|
|
6
|
+
* 后果链(2026-09-02 现场):
|
|
7
|
+
* npm registry 查询失败 → CLI 自更新误判"已是最新"或报错;
|
|
8
|
+
* better-sqlite3 prebuild 下载失败 → 回退 node-gyp 源码编译 7 分钟+。
|
|
9
|
+
* 本模块只检测 loopback 代理(远程代理探测需要出网,不属于"死代理"语义),
|
|
10
|
+
* 且永不 throw —— 检测结果用于告警,不影响主流程。
|
|
11
|
+
*/
|
|
12
|
+
import net from 'node:net';
|
|
13
|
+
const PROXY_VARS = ['HTTP_PROXY', 'HTTPS_PROXY', 'http_proxy', 'https_proxy'];
|
|
14
|
+
/** 收集四个代理环境变量中已设置的项 */
|
|
15
|
+
export function collectProxyEnv() {
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const varName of PROXY_VARS) {
|
|
18
|
+
const value = process.env[varName];
|
|
19
|
+
if (value)
|
|
20
|
+
out.push({ varName, value });
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
/** 解析代理值为 {host, port}(仅处理显式端口的 http(s) 代理) */
|
|
25
|
+
function parseProxyUrl(value) {
|
|
26
|
+
try {
|
|
27
|
+
const u = new URL(value);
|
|
28
|
+
if ((u.protocol !== 'http:' && u.protocol !== 'https:') || !u.port)
|
|
29
|
+
return null;
|
|
30
|
+
return { host: u.hostname, port: Number(u.port) };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function isLoopback(host) {
|
|
37
|
+
return host === '127.0.0.1' || host === 'localhost' || host === '::1' || host === '[::1]';
|
|
38
|
+
}
|
|
39
|
+
function probePort(host, port, timeoutMs) {
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const socket = new net.Socket();
|
|
42
|
+
let settled = false;
|
|
43
|
+
const done = (r) => {
|
|
44
|
+
if (settled)
|
|
45
|
+
return;
|
|
46
|
+
settled = true;
|
|
47
|
+
socket.destroy();
|
|
48
|
+
resolve(r);
|
|
49
|
+
};
|
|
50
|
+
socket.setTimeout(timeoutMs);
|
|
51
|
+
socket.once('connect', () => done('open'));
|
|
52
|
+
socket.once('timeout', () => done('timeout'));
|
|
53
|
+
socket.once('error', (err) => done(err.code === 'ECONNREFUSED' ? 'refused' : 'unreachable'));
|
|
54
|
+
try {
|
|
55
|
+
socket.connect(port, host);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
done('unreachable');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 找出指向 loopback 但端口不通的死代理。
|
|
64
|
+
* 远程代理(非 loopback)不探测,直接视为有效(由网络栈自己处理)。
|
|
65
|
+
*/
|
|
66
|
+
export async function findDeadProxies(timeoutMs = 800) {
|
|
67
|
+
const findings = [];
|
|
68
|
+
for (const { varName, value } of collectProxyEnv()) {
|
|
69
|
+
const parsed = parseProxyUrl(value);
|
|
70
|
+
if (!parsed || !isLoopback(parsed.host))
|
|
71
|
+
continue;
|
|
72
|
+
const result = await probePort(parsed.host, parsed.port, timeoutMs);
|
|
73
|
+
if (result !== 'open') {
|
|
74
|
+
findings.push({
|
|
75
|
+
varName,
|
|
76
|
+
value,
|
|
77
|
+
host: parsed.host,
|
|
78
|
+
port: parsed.port,
|
|
79
|
+
reason: result === 'refused' ? 'refused' : result === 'timeout' ? 'timeout' : 'unreachable',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return findings;
|
|
84
|
+
}
|
|
85
|
+
/** 生成各 shell 的清除指令提示(用户直接复制执行) */
|
|
86
|
+
export function buildUnsetHint(findings) {
|
|
87
|
+
const vars = [...new Set(findings.map((f) => f.varName))].join(', ');
|
|
88
|
+
return [
|
|
89
|
+
`死代理告警: ${findings.map((f) => `${f.varName}=${f.value} (${f.reason === 'refused' ? '连接被拒绝' : f.reason === 'timeout' ? '连接超时' : '不可达'})`).join('; ')}`,
|
|
90
|
+
`该代理端口已不可用,会导致 npm registry 查询失败 / prebuild 下载失败回退源码编译。清除(当前会话):`,
|
|
91
|
+
` PowerShell: Remove-Item Env:${vars.replace(/, /g, ', Env:')}`,
|
|
92
|
+
` CMD: set ${findings.map((f) => f.varName).join('= && set ')}=`,
|
|
93
|
+
` bash/zsh: unset ${findings.map((f) => f.varName).join(' ')}`,
|
|
94
|
+
` npm 专用: npm config delete proxy && npm config delete https-proxy`,
|
|
95
|
+
].join('\n');
|
|
96
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function resolveScriptPath(p: string | undefined): string | undefined;
|
|
2
|
+
/** 可测形式:传入 argv[1] 判定入口(单测用,业务代码请用 isMainModule) */
|
|
3
|
+
export declare function isInvokedAsEntry(metaUrl: string, argv1: string | undefined): boolean;
|
|
4
|
+
/** 当前模块是否作为 node 独立入口执行(import 时不触发);argv 读取只应发生在本模块 */
|
|
5
|
+
export declare function isMainModule(metaUrl: string): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// utils/script-path.ts — 跨平台入口脚本路径解析(Windows .cmd shim 兼容)
|
|
2
|
+
// Windows 下 node 经 .cmd shim 调用时 process.argv[1] 可能是 shim 路径/8.3 短路径,
|
|
3
|
+
// 必须 realpath 后再与 import.meta.url 比对(AGENTS.md 平台兼容红线)
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
export function resolveScriptPath(p) {
|
|
8
|
+
if (!p)
|
|
9
|
+
return undefined;
|
|
10
|
+
try {
|
|
11
|
+
return fs.realpathSync(p);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return path.resolve(p);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** 可测形式:传入 argv[1] 判定入口(单测用,业务代码请用 isMainModule) */
|
|
18
|
+
export function isInvokedAsEntry(metaUrl, argv1) {
|
|
19
|
+
const entryPath = resolveScriptPath(argv1);
|
|
20
|
+
if (!entryPath)
|
|
21
|
+
return false;
|
|
22
|
+
return entryPath === resolveScriptPath(fileURLToPath(metaUrl));
|
|
23
|
+
}
|
|
24
|
+
/** 当前模块是否作为 node 独立入口执行(import 时不触发);argv 读取只应发生在本模块 */
|
|
25
|
+
export function isMainModule(metaUrl) {
|
|
26
|
+
return isInvokedAsEntry(metaUrl, process.argv[1]);
|
|
27
|
+
}
|
package/dist/version.js
CHANGED
|
@@ -4,18 +4,21 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import { createHash } from 'crypto';
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
-
import { loadConfig } from './config.js';
|
|
7
|
+
import { loadConfig, resolveDataDir } from './config.js';
|
|
8
8
|
import { runStop, runStart, tryReadPid, findServerRoot } from './commands/server.js';
|
|
9
9
|
import { runReload } from './commands/extras.js';
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname = path.dirname(__filename);
|
|
12
|
-
const
|
|
13
|
-
const ROOT = () => path.join(HOME(), '.hunter-mate');
|
|
12
|
+
const ROOT = resolveDataDir;
|
|
14
13
|
const PLUGINS_DIR = () => path.join(ROOT(), 'plugins');
|
|
15
14
|
const EXTENSION_MANIFEST = () => path.join(ROOT(), 'extension', 'manifest.json');
|
|
16
15
|
const EXTENSION_DIR = () => path.join(ROOT(), 'extension');
|
|
17
16
|
const RUNTIME_FILE = () => path.join(ROOT(), 'runtime.json');
|
|
18
17
|
const LAST_CHECK_FILE = () => path.join(ROOT(), '.last-consistency-check');
|
|
18
|
+
// D5(R3 定案):extension reload 广播边沿触发 —— 同一 checksum 只广播一次。
|
|
19
|
+
// 原逻辑只要 disk≠bootSnapshot 每次 CLI 调用都广播,dev 频繁构建态下
|
|
20
|
+
// 每个命令都杀死在途长命令(linkedin search 分钟级编排反复横死)。
|
|
21
|
+
const LAST_EXT_RELOAD_BROADCAST_FILE = () => path.join(ROOT(), '.last-ext-reload-broadcast');
|
|
19
22
|
const CHECK_THROTTLE_MS = 60_000;
|
|
20
23
|
// ---------------------------------------------------------------------------
|
|
21
24
|
// 三层指纹工具(version + checksum + mtime/linked)— 与 chromepilot version-manager / server SystemService 算法完全等价
|
|
@@ -301,7 +304,7 @@ export async function ensureRuntimeConsistency(opts = {}) {
|
|
|
301
304
|
// 2) server 重启(stop + start)
|
|
302
305
|
if (actions.serverRestart) {
|
|
303
306
|
try {
|
|
304
|
-
runStop();
|
|
307
|
+
await runStop();
|
|
305
308
|
const r = await runStart({});
|
|
306
309
|
performed.push(r.started
|
|
307
310
|
? `server restarted (${actions.serverReason}) — new pid=${r.pid}`
|
|
@@ -311,14 +314,36 @@ export async function ensureRuntimeConsistency(opts = {}) {
|
|
|
311
314
|
performed.push(`server restart FAILED: ${err.message}`);
|
|
312
315
|
}
|
|
313
316
|
}
|
|
314
|
-
// 3) 浏览器扩展 reload 广播
|
|
317
|
+
// 3) 浏览器扩展 reload 广播(D5: checksum 边沿触发,同值不重播)
|
|
315
318
|
if (actions.extensionReload) {
|
|
319
|
+
const currentChecksum = installed.artifacts?.extension?.checksum ?? '';
|
|
320
|
+
let lastBroadcast = '';
|
|
316
321
|
try {
|
|
317
|
-
|
|
318
|
-
performed.push(`extension reload broadcast: ${actions.extensionReason ?? 'version mismatch'} — broadcast=${r.broadcast}, msg=${r.msg}`);
|
|
322
|
+
lastBroadcast = fs.readFileSync(LAST_EXT_RELOAD_BROADCAST_FILE(), 'utf8').trim();
|
|
319
323
|
}
|
|
320
|
-
catch
|
|
321
|
-
|
|
324
|
+
catch {
|
|
325
|
+
/* 首次 */
|
|
326
|
+
}
|
|
327
|
+
if (currentChecksum && lastBroadcast === currentChecksum) {
|
|
328
|
+
performed.push(`extension reload skipped (checksum 已广播过, D5 边沿去重): ${actions.extensionReason}`);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
try {
|
|
332
|
+
const r = await runReload(3000);
|
|
333
|
+
performed.push(`extension reload broadcast: ${actions.extensionReason ?? 'version mismatch'} — broadcast=${r.broadcast}, msg=${r.msg}`);
|
|
334
|
+
if (currentChecksum) {
|
|
335
|
+
try {
|
|
336
|
+
fs.mkdirSync(ROOT(), { recursive: true });
|
|
337
|
+
fs.writeFileSync(LAST_EXT_RELOAD_BROADCAST_FILE(), currentChecksum);
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
/* 尽力 */
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (e) {
|
|
345
|
+
performed.push(`extension reload FAILED: ${e.message}. Tip: chrome://extensions → 点 HunterMate 卡片的刷新图标`);
|
|
346
|
+
}
|
|
322
347
|
}
|
|
323
348
|
}
|
|
324
349
|
markChecked();
|
package/dist/watchdog.d.ts
CHANGED
|
@@ -1 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* server 活性探针(FID-057 #17-A3):子进程不退但假活(事件循环被拖死)时,
|
|
3
|
+
* exit 监听永远等不到触发。探针定时 GET /health,连续失败达到阈值判定假活,
|
|
4
|
+
* 由 watchdog kill 子进程走正常重启路径。
|
|
5
|
+
*/
|
|
6
|
+
export declare class LivenessProbe {
|
|
7
|
+
private readonly opts;
|
|
8
|
+
private failCount;
|
|
9
|
+
private timer;
|
|
10
|
+
constructor(opts: {
|
|
11
|
+
healthUrl: string;
|
|
12
|
+
intervalMs: number;
|
|
13
|
+
threshold: number;
|
|
14
|
+
onFailure: (lastError: string) => void;
|
|
15
|
+
/** 可注入的探测实现(测试用),默认 HTTP GET /health */
|
|
16
|
+
check?: (url: string) => Promise<void>;
|
|
17
|
+
});
|
|
18
|
+
private doCheck;
|
|
19
|
+
/** 立即探测一次并更新失败计数;达到阈值时回调 onFailure 并清零 */
|
|
20
|
+
checkNow(): Promise<void>;
|
|
21
|
+
start(): void;
|
|
22
|
+
stop(): void;
|
|
23
|
+
}
|
package/dist/watchdog.js
CHANGED
|
@@ -1,11 +1,75 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import * as http from 'http';
|
|
5
|
+
import { isMainModule } from './utils/script-path.js';
|
|
6
|
+
import { resolveDataDir } from './config.js';
|
|
7
|
+
const ROOT = resolveDataDir;
|
|
6
8
|
const SERVER_PID_FILE = () => path.join(ROOT(), 'server.pid');
|
|
7
9
|
const WATCHDOG_PID_FILE = () => path.join(ROOT(), 'watchdog.pid');
|
|
8
10
|
const CRASH_LOG_FILE = () => path.join(ROOT(), 'server-crash.log');
|
|
11
|
+
/**
|
|
12
|
+
* server 活性探针(FID-057 #17-A3):子进程不退但假活(事件循环被拖死)时,
|
|
13
|
+
* exit 监听永远等不到触发。探针定时 GET /health,连续失败达到阈值判定假活,
|
|
14
|
+
* 由 watchdog kill 子进程走正常重启路径。
|
|
15
|
+
*/
|
|
16
|
+
export class LivenessProbe {
|
|
17
|
+
opts;
|
|
18
|
+
failCount = 0;
|
|
19
|
+
timer = null;
|
|
20
|
+
constructor(opts) {
|
|
21
|
+
this.opts = opts;
|
|
22
|
+
}
|
|
23
|
+
async doCheck() {
|
|
24
|
+
const check = this.opts.check ||
|
|
25
|
+
((url) => new Promise((resolve, reject) => {
|
|
26
|
+
const req = http.get(url, { timeout: 5000 }, (res) => {
|
|
27
|
+
res.resume();
|
|
28
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 500) {
|
|
29
|
+
resolve();
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
reject(new Error(`HTTP ${res.statusCode}`));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
req.on('timeout', () => {
|
|
36
|
+
req.destroy(new Error('probe timeout'));
|
|
37
|
+
});
|
|
38
|
+
req.on('error', reject);
|
|
39
|
+
}));
|
|
40
|
+
await check(this.opts.healthUrl);
|
|
41
|
+
}
|
|
42
|
+
/** 立即探测一次并更新失败计数;达到阈值时回调 onFailure 并清零 */
|
|
43
|
+
async checkNow() {
|
|
44
|
+
try {
|
|
45
|
+
await this.doCheck();
|
|
46
|
+
this.failCount = 0;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
this.failCount++;
|
|
50
|
+
if (this.failCount >= this.opts.threshold) {
|
|
51
|
+
const lastError = err.message;
|
|
52
|
+
this.failCount = 0;
|
|
53
|
+
this.opts.onFailure(lastError);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
start() {
|
|
58
|
+
if (this.timer)
|
|
59
|
+
return;
|
|
60
|
+
this.timer = setInterval(() => {
|
|
61
|
+
void this.checkNow().catch(() => undefined);
|
|
62
|
+
}, this.opts.intervalMs);
|
|
63
|
+
this.timer.unref?.();
|
|
64
|
+
}
|
|
65
|
+
stop() {
|
|
66
|
+
if (this.timer) {
|
|
67
|
+
clearInterval(this.timer);
|
|
68
|
+
this.timer = null;
|
|
69
|
+
}
|
|
70
|
+
this.failCount = 0;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
9
73
|
function writePid(file, pid) {
|
|
10
74
|
try {
|
|
11
75
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
@@ -32,10 +96,11 @@ function cleanPid(file) {
|
|
|
32
96
|
}
|
|
33
97
|
catch { /* ignore */ }
|
|
34
98
|
}
|
|
35
|
-
function logCrash(code, signal, restartCount) {
|
|
99
|
+
function logCrash(code, signal, restartCount, reason) {
|
|
36
100
|
try {
|
|
37
101
|
fs.mkdirSync(ROOT(), { recursive: true });
|
|
38
|
-
const
|
|
102
|
+
const reasonPart = reason ? ` reason=${reason}` : '';
|
|
103
|
+
const line = `[${new Date().toISOString()}] exit code=${code} signal=${signal}${reasonPart} restartCount=${restartCount}\n`;
|
|
39
104
|
fs.appendFileSync(CRASH_LOG_FILE(), line);
|
|
40
105
|
}
|
|
41
106
|
catch { /* ignore */ }
|
|
@@ -66,6 +131,23 @@ function runWatchdog() {
|
|
|
66
131
|
let restartCount = 0;
|
|
67
132
|
let restartTimer = null;
|
|
68
133
|
let stopping = false;
|
|
134
|
+
let crashReason; // 探针假活击杀时写入,exit 回调带入 crash log
|
|
135
|
+
// 活性探针:子进程活着但假活(事件循环冻结)时 kill 重启(FID-057 #17-A3)
|
|
136
|
+
const probe = new LivenessProbe({
|
|
137
|
+
healthUrl: process.env.HM_SERVER_HEALTH_URL || `http://127.0.0.1:${process.env.PORT || 34570}/health`,
|
|
138
|
+
intervalMs: Number(process.env.HM_WATCHDOG_PROBE_INTERVAL_MS || 30_000),
|
|
139
|
+
threshold: Number(process.env.HM_WATCHDOG_PROBE_THRESHOLD || 3),
|
|
140
|
+
onFailure: (lastError) => {
|
|
141
|
+
if (stopping || !child || child.killed)
|
|
142
|
+
return;
|
|
143
|
+
console.error(`[HunterMate watchdog] server unresponsive (last error: ${lastError}), killing for restart`);
|
|
144
|
+
crashReason = `liveness probe failed: ${lastError}`;
|
|
145
|
+
try {
|
|
146
|
+
child.kill('SIGKILL');
|
|
147
|
+
}
|
|
148
|
+
catch { /* ignore: exit handler will restart */ }
|
|
149
|
+
},
|
|
150
|
+
});
|
|
69
151
|
function startChild() {
|
|
70
152
|
if (stopping)
|
|
71
153
|
return;
|
|
@@ -84,14 +166,17 @@ function runWatchdog() {
|
|
|
84
166
|
});
|
|
85
167
|
if (child.pid)
|
|
86
168
|
writePid(SERVER_PID_FILE(), child.pid);
|
|
169
|
+
probe.start();
|
|
87
170
|
child.on('exit', (code, signal) => {
|
|
88
171
|
try {
|
|
89
172
|
fs.closeSync(logFd);
|
|
90
173
|
}
|
|
91
174
|
catch { /* ignore */ }
|
|
175
|
+
probe.stop();
|
|
92
176
|
if (stopping)
|
|
93
177
|
return;
|
|
94
|
-
logCrash(code ?? null, signal, restartCount);
|
|
178
|
+
logCrash(code ?? null, signal, restartCount, crashReason);
|
|
179
|
+
crashReason = undefined;
|
|
95
180
|
child = null;
|
|
96
181
|
restartCount++;
|
|
97
182
|
const delay = Math.min(1000 * Math.pow(2, restartCount), maxRestartDelayMs);
|
|
@@ -113,6 +198,7 @@ function runWatchdog() {
|
|
|
113
198
|
clearTimeout(restartTimer);
|
|
114
199
|
restartTimer = null;
|
|
115
200
|
}
|
|
201
|
+
probe.stop();
|
|
116
202
|
if (child && !child.killed) {
|
|
117
203
|
child.kill('SIGTERM');
|
|
118
204
|
}
|
|
@@ -125,4 +211,9 @@ function runWatchdog() {
|
|
|
125
211
|
});
|
|
126
212
|
startChild();
|
|
127
213
|
}
|
|
128
|
-
|
|
214
|
+
// 仅作为独立入口(node watchdog.js,由 `server start` 拉起)时启动;
|
|
215
|
+
// 被单测 import 时不触发,避免缺 env 直接退出测试进程
|
|
216
|
+
const invokedAsEntry = isMainModule(import.meta.url);
|
|
217
|
+
if (invokedAsEntry) {
|
|
218
|
+
runWatchdog();
|
|
219
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/db881c5b3072b88a.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-1784baecc6fdcf0b.js"/><script src="/_next/static/chunks/a7067448-96dd4b8457c447e8.js" async=""></script><script src="/_next/static/chunks/935-99f57b7d4151d9e7.js" async=""></script><script src="/_next/static/chunks/main-app-80b038a312917d90.js" async=""></script><script src="/_next/static/chunks/589-d632233641f35681.js" async=""></script><script src="/_next/static/chunks/app/layout-83e623e973c1693f.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>HunterMate 采集仪表盘</title><meta name="description" content="HunterMate 采集/解析/入库仪表盘"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="flex h-screen overflow-hidden bg-gray-50 text-gray-900"><aside class="flex h-screen w-56 flex-col border-r border-gray-200 bg-white"><div class="flex items-center gap-2 border-b border-gray-200 px-4 py-3"><span class="text-xl">🤝</span><span class="font-semibold text-gray-900">HunterMate</span></div><nav class="flex-1 overflow-auto py-3"><a class="mx-2 flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors text-gray-600 hover:bg-gray-50 hover:text-gray-900" href="/"><span class="text-base">📊</span>仪表盘</a><a class="mx-2 flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors text-gray-600 hover:bg-gray-50 hover:text-gray-900" href="/talents"><span class="text-base">👤</span>人才</a><a class="mx-2 flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors text-gray-600 hover:bg-gray-50 hover:text-gray-900" href="/jobs"><span class="text-base">💼</span>职位</a><a class="mx-2 flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors text-gray-600 hover:bg-gray-50 hover:text-gray-900" href="/companies"><span class="text-base">🏢</span>公司</a><a class="mx-2 flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors text-gray-600 hover:bg-gray-50 hover:text-gray-900" href="/parselog"><span class="text-base">📋</span>解析日志</a><a class="mx-2 flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors text-gray-600 hover:bg-gray-50 hover:text-gray-900" href="/recordings"><span class="text-base">🔴</span>录制</a></nav></aside><main class="flex-1 overflow-hidden"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div></main><script src="/_next/static/chunks/webpack-1784baecc6fdcf0b.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/db881c5b3072b88a.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[6939,[],\"\"]\n4:I[4268,[],\"\"]\n5:I[1050,[],\"\"]\n6:I[4798,[\"589\",\"static/chunks/589-d632233641f35681.js\",\"185\",\"static/chunks/app/layout-83e623e973c1693f.js\"],\"SystemSidebar\"]\nc:I[2319,[],\"\"]\n7:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n8:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n9:{\"display\":\"inline-block\"}\na:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nd:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"WdJr3NhHjlu5xN0qOap1k\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/db881c5b3072b88a.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"zh-CN\",\"children\":[\"$\",\"body\",null,{\"className\":\"flex h-screen overflow-hidden bg-gray-50 text-gray-900\",\"children\":[[\"$\",\"$L6\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 overflow-hidden\",\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$7\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$8\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$9\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$a\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lb\"],\"globalErrorComponent\":\"$c\",\"missingSlots\":\"$Wd\"}]\n"])</script><script>self.__next_f.push([1,"b:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"HunterMate 采集仪表盘\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"HunterMate 采集/解析/入库仪表盘\"}]]\n3:null\n"])</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/_error":["static/chunks/pages/_error-17756f67e0a11350.js"],sortedPages:["/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__SSG_MANIFEST=new Set(["\u002Fmatching\u002Fjobs\u002F[id]\u002Ftalents","\u002Fmatching\u002Fportraits\u002F[id]\u002Fjobs","\u002Fsnapshots\u002F[id]\u002Fagent-prompt"]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3f320bd5-6c8f-4684-8ab0-ca437c6aa2ad",e._sentryDebugIdIdentifier="sentry-dbid-3f320bd5-6c8f-4684-8ab0-ca437c6aa2ad")}catch(e){}}(),(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[166],{166:function(){}}]);
|