hunter-mate 0.1.7 → 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 +727 -152
- 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 +8 -1
- 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 +11 -1
- package/dist/assets/server/app.module.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/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 +12 -0
- package/dist/assets/server/extension/extension-control.controller.js +41 -1
- package/dist/assets/server/extension/extension-control.controller.js.map +1 -1
- package/dist/assets/server/extension/extension-control.service.d.ts +6 -1
- package/dist/assets/server/extension/extension-control.service.js +27 -1
- 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 +1 -1
- 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.js +1 -1
- package/dist/assets/server/recording/recording-event-queue.service.js.map +1 -1
- package/dist/assets/server/recording/recording-retention.service.d.ts +19 -2
- package/dist/assets/server/recording/recording-retention.service.js +95 -6
- package/dist/assets/server/recording/recording-retention.service.js.map +1 -1
- 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 +10 -0
- package/dist/assets/server/recording/recording.controller.js +19 -0
- 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 +6 -1
- package/dist/assets/server/recording/recording.module.js.map +1 -1
- package/dist/assets/server/recording/recording.service.d.ts +5 -0
- package/dist/assets/server/recording/recording.service.js +10 -0
- 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 +1 -1
- 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 +33 -9
- package/dist/commands/extension.js +18 -15
- package/dist/commands/extras.d.ts +22 -3
- package/dist/commands/extras.js +114 -5
- 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 +2 -1
- package/dist/commands/job.js +25 -5
- package/dist/commands/login.d.ts +4 -0
- package/dist/commands/login.js +30 -3
- 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 +64 -13
- package/dist/commands/preference.d.ts +6 -0
- package/dist/commands/preference.js +80 -0
- package/dist/commands/record.js +1 -1
- package/dist/commands/report.js +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/server.d.ts +7 -0
- package/dist/commands/server.js +40 -2
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.js +16 -6
- package/dist/commands/update.js +7 -8
- package/dist/config.d.ts +21 -0
- package/dist/config.js +27 -0
- package/dist/i18n/locales/en-US.json +17 -1
- package/dist/i18n/locales/zh-CN.json +17 -1
- package/dist/index.js +14 -0
- package/dist/keychain.d.ts +16 -1
- package/dist/keychain.js +43 -16
- package/dist/logger.js +2 -2
- package/dist/updater.js +2 -2
- package/dist/utils/command-error.d.ts +4 -2
- package/dist/utils/command-error.js +19 -3
- package/dist/utils/link.d.ts +18 -0
- package/dist/utils/link.js +83 -0
- package/dist/version.js +33 -8
- package/dist/watchdog.js +3 -3
- package/dist/web/dist/404.html +1 -1
- package/dist/web/dist/_next/static/chunks/app/logs/page-d478031d49f7ba00.js +1 -0
- package/dist/web/dist/auth/verify.html +1 -1
- package/dist/web/dist/auth/verify.txt +1 -1
- package/dist/web/dist/companies.html +1 -1
- package/dist/web/dist/companies.txt +1 -1
- package/dist/web/dist/entity.html +1 -1
- package/dist/web/dist/entity.txt +1 -1
- package/dist/web/dist/index.html +1 -1
- package/dist/web/dist/index.txt +1 -1
- package/dist/web/dist/jobs.html +1 -1
- package/dist/web/dist/jobs.txt +1 -1
- package/dist/web/dist/logs.html +1 -1
- package/dist/web/dist/logs.txt +2 -2
- package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.txt +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.txt +1 -1
- package/dist/web/dist/parselog.html +1 -1
- package/dist/web/dist/parselog.txt +1 -1
- package/dist/web/dist/recordings.html +1 -1
- package/dist/web/dist/recordings.txt +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +1 -1
- package/dist/web/dist/talents.html +1 -1
- package/dist/web/dist/talents.txt +1 -1
- package/package.json +2 -2
- package/dist/web/dist/_next/static/chunks/app/logs/page-9f41d44fa1add723.js +0 -1
- /package/dist/web/dist/_next/static/{hqJ-7vr4X71DNfzZugHJ- → WdJr3NhHjlu5xN0qOap1k}/_buildManifest.js +0 -0
- /package/dist/web/dist/_next/static/{hqJ-7vr4X71DNfzZugHJ- → WdJr3NhHjlu5xN0qOap1k}/_ssgManifest.js +0 -0
|
@@ -59,5 +59,21 @@
|
|
|
59
59
|
"purge.done.next": "如需重新初始化,请运行",
|
|
60
60
|
"purge.done.nothing": "无需清理",
|
|
61
61
|
"login.serverOfflineSaasFallback": "警告: 本地 server 未运行,已直连 SaaS 登录;本地数据操作需启动 server 后重新 login。",
|
|
62
|
-
"login.serverOfflineReloginHint": "提示: 本次保存的是 SaaS 令牌,本地 server 的受保护路由将返回 401。"
|
|
62
|
+
"login.serverOfflineReloginHint": "提示: 本次保存的是 SaaS 令牌,本地 server 的受保护路由将返回 401。",
|
|
63
|
+
"login.selfCheckOk": "✓ 登录自检通过:受保护接口可达,search/report/job 可直接使用",
|
|
64
|
+
"login.selfCheckFail": "✗ 登录自检失败:新令牌被本地 server 拒绝,请带完整输出反馈,勿反复重试",
|
|
65
|
+
"login.selfCheckSkipped": "⚠ 登录自检跳过:本地 server 暂不可达,恢复后请重新 login",
|
|
66
|
+
"issueEnv.description": "输出提 issue 所需环境块(CLI 版本/安装方式/代码 git HEAD/server buildTime/OS),--format json 可供 agent 直接粘贴",
|
|
67
|
+
"issueEnv.cliVersion": "CLI 版本",
|
|
68
|
+
"issueEnv.installType": "安装方式",
|
|
69
|
+
"issueEnv.installDev": "dev(源码仓 git 工作区)",
|
|
70
|
+
"issueEnv.installPackage": "package(发布包)",
|
|
71
|
+
"issueEnv.gitHead": "代码 HEAD(版本号/buildTime 不说明代码状态,以 HEAD 为准)",
|
|
72
|
+
"issueEnv.gitBranch": "分支",
|
|
73
|
+
"issueEnv.gitDirty": "有未提交改动(dist 可能滞后于 HEAD)",
|
|
74
|
+
"issueEnv.gitClean": "工作区干净",
|
|
75
|
+
"issueEnv.repoRoot": "代码仓",
|
|
76
|
+
"issueEnv.gitUnavailable": "未获取(发布包无 git 信息,用 CLI 版本代替)",
|
|
77
|
+
"issueEnv.serverBuildTime": "server buildTime",
|
|
78
|
+
"issueEnv.serverNotRunning": "server 未运行(未获取)"
|
|
63
79
|
}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { extensionCommand } from './commands/extension.js';
|
|
|
14
14
|
import { reportCommand } from './commands/report.js';
|
|
15
15
|
import { recordCommand } from './commands/record.js';
|
|
16
16
|
import { cacheCommand } from './commands/cache.js';
|
|
17
|
+
import { migrateDataDirCommand } from './commands/migrate.js';
|
|
17
18
|
// 对应 ChromePilot 的新命令(环境管理 / 运维 / 扩展管理)
|
|
18
19
|
import { initCommand } from './commands/init.js';
|
|
19
20
|
import { installCommand } from './commands/install.js';
|
|
@@ -22,6 +23,11 @@ import { doctorCommand } from './commands/doctor.js';
|
|
|
22
23
|
import { reloadCommand, openExtCommand, purgeCommand } from './commands/extras.js';
|
|
23
24
|
import { recordingsCommand, adapterCommand, memoryCommand, traceCommand, autofixCommand } from './commands/ops.js';
|
|
24
25
|
import { pluginCommand, skillCommand, externalCommand } from './commands/addons.js';
|
|
26
|
+
import { customerCommand } from './commands/customer.js';
|
|
27
|
+
import { noteCommand } from './commands/note.js';
|
|
28
|
+
import { preferenceCommand } from './commands/preference.js';
|
|
29
|
+
import { caseCommand } from './commands/case.js';
|
|
30
|
+
import { issueEnvCommand } from './commands/issue-env.js';
|
|
25
31
|
import { i18n } from './i18n/index.js';
|
|
26
32
|
import { initCliLogger, flushCliLogger, getCliLogger } from './logger.js';
|
|
27
33
|
import packageJson from '../package.json' with { type: 'json' };
|
|
@@ -81,6 +87,8 @@ program
|
|
|
81
87
|
const name = thisCommand.name();
|
|
82
88
|
if (name === 'update' || name === 'start' || name === 'stop')
|
|
83
89
|
return;
|
|
90
|
+
if (name === 'migrate-data-dir')
|
|
91
|
+
return; // 迁移过程中一致性检测/自更新会干扰移动与重启
|
|
84
92
|
if (name === 'doctor' || name === 'repair-linkedin-dupes')
|
|
85
93
|
return;
|
|
86
94
|
// fix #30: 命令以 --json(或 --format/-f json)输出时, [auto-update] 提示不得混入 stdout 的 JSON
|
|
@@ -160,4 +168,10 @@ program.addCommand(purgeCommand);
|
|
|
160
168
|
program.addCommand(reportCommand);
|
|
161
169
|
program.addCommand(recordCommand);
|
|
162
170
|
program.addCommand(cacheCommand);
|
|
171
|
+
program.addCommand(migrateDataDirCommand);
|
|
172
|
+
program.addCommand(customerCommand);
|
|
173
|
+
program.addCommand(noteCommand);
|
|
174
|
+
program.addCommand(preferenceCommand);
|
|
175
|
+
program.addCommand(caseCommand);
|
|
176
|
+
program.addCommand(issueEnvCommand);
|
|
163
177
|
program.parse();
|
package/dist/keychain.d.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* token 签发方(hmh#43):
|
|
3
|
+
* - local: 本地 server 自签 UTOKEN(设备码/邮箱代理路径),AuthMiddleware 可直接验签;
|
|
4
|
+
* - saas: 邮箱登录时本地 server 不可达,CLI 直连 SaaS 验证拿到的 token,
|
|
5
|
+
* 由 SaaS 密钥签发,本地 server 的 USER_SESSION_SECRET 验不过 → 数据面 401;
|
|
6
|
+
* - unknown: 旧版本存的裸 token(无 issuer 标记),无法区分签发方。
|
|
7
|
+
*/
|
|
8
|
+
export type TokenIssuer = 'local' | 'saas' | 'unknown';
|
|
9
|
+
export interface TokenInfo {
|
|
10
|
+
token: string;
|
|
11
|
+
issuer: TokenIssuer;
|
|
12
|
+
}
|
|
13
|
+
export declare function saveToken(token: string, issuer?: TokenIssuer): Promise<void>;
|
|
14
|
+
/** 只取 token 字符串(兼容全部历史调用方) */
|
|
2
15
|
export declare function getToken(): Promise<string | null>;
|
|
16
|
+
/** 取 token + 签发方标记(hmh#43 诊断用) */
|
|
17
|
+
export declare function getTokenInfo(): Promise<TokenInfo | null>;
|
|
3
18
|
export declare function deleteToken(): Promise<void>;
|
package/dist/keychain.js
CHANGED
|
@@ -1,30 +1,50 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { resolveDataDir } from './config.js';
|
|
3
4
|
const SERVICE = 'hunter-mate';
|
|
4
5
|
const ACCOUNT = 'user';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
/** token 落盘文件(FID-071:随 dataDir 配置迁移;keytar 可用时不使用) */
|
|
7
|
+
function tokenFile() {
|
|
8
|
+
return path.join(resolveDataDir(), 'token.json');
|
|
9
|
+
}
|
|
10
|
+
/** 兼容旧格式:裸 token 字符串或无 issuer 字段的 JSON */
|
|
11
|
+
function parseStored(raw) {
|
|
12
|
+
if (!raw)
|
|
13
|
+
return null;
|
|
14
|
+
try {
|
|
15
|
+
const data = JSON.parse(raw);
|
|
16
|
+
if (typeof data === 'string')
|
|
17
|
+
return { token: data, issuer: 'unknown' };
|
|
18
|
+
if (data && typeof data.token === 'string') {
|
|
19
|
+
const issuer = data.issuer === 'saas' || data.issuer === 'local' ? data.issuer : 'unknown';
|
|
20
|
+
return { token: data.token, issuer };
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return { token: raw, issuer: 'unknown' };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function fallbackSave(info) {
|
|
29
|
+
fs.mkdirSync(path.dirname(tokenFile()), { recursive: true });
|
|
9
30
|
// POSIX 上 mode 0o600 强制 owner-only;Windows NTFS 上 mode bit 被忽略,
|
|
10
31
|
// 由用户目录 ACL 兜底(%USERPROFILE%\.hunter-mate 默认只有当前用户可访问)。
|
|
11
32
|
// 真正安全的 Windows 路径是走 keytar(Windows Credential Manager)→ setPassword。
|
|
12
|
-
fs.writeFileSync(
|
|
33
|
+
fs.writeFileSync(tokenFile(), JSON.stringify(info), { mode: 0o600 });
|
|
13
34
|
}
|
|
14
35
|
function fallbackGet() {
|
|
15
|
-
if (!fs.existsSync(
|
|
36
|
+
if (!fs.existsSync(tokenFile()))
|
|
16
37
|
return null;
|
|
17
38
|
try {
|
|
18
|
-
|
|
19
|
-
return data.token || null;
|
|
39
|
+
return parseStored(fs.readFileSync(tokenFile(), 'utf-8'));
|
|
20
40
|
}
|
|
21
41
|
catch {
|
|
22
42
|
return null;
|
|
23
43
|
}
|
|
24
44
|
}
|
|
25
45
|
function fallbackDelete() {
|
|
26
|
-
if (fs.existsSync(
|
|
27
|
-
fs.unlinkSync(
|
|
46
|
+
if (fs.existsSync(tokenFile())) {
|
|
47
|
+
fs.unlinkSync(tokenFile());
|
|
28
48
|
}
|
|
29
49
|
}
|
|
30
50
|
async function getKeytar() {
|
|
@@ -41,26 +61,33 @@ async function getKeytar() {
|
|
|
41
61
|
return null;
|
|
42
62
|
}
|
|
43
63
|
}
|
|
44
|
-
export async function saveToken(token) {
|
|
64
|
+
export async function saveToken(token, issuer = 'local') {
|
|
65
|
+
const payload = JSON.stringify({ token, issuer });
|
|
45
66
|
const keytar = await getKeytar();
|
|
46
67
|
if (keytar) {
|
|
47
68
|
try {
|
|
48
|
-
await keytar.setPassword(SERVICE, ACCOUNT,
|
|
69
|
+
await keytar.setPassword(SERVICE, ACCOUNT, payload);
|
|
49
70
|
return;
|
|
50
71
|
}
|
|
51
72
|
catch {
|
|
52
73
|
// 降级到文件
|
|
53
74
|
}
|
|
54
75
|
}
|
|
55
|
-
fallbackSave(token);
|
|
76
|
+
fallbackSave({ token, issuer });
|
|
56
77
|
}
|
|
78
|
+
/** 只取 token 字符串(兼容全部历史调用方) */
|
|
57
79
|
export async function getToken() {
|
|
80
|
+
const info = await getTokenInfo();
|
|
81
|
+
return info?.token ?? null;
|
|
82
|
+
}
|
|
83
|
+
/** 取 token + 签发方标记(hmh#43 诊断用) */
|
|
84
|
+
export async function getTokenInfo() {
|
|
58
85
|
const keytar = await getKeytar();
|
|
59
86
|
if (keytar) {
|
|
60
87
|
try {
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
return
|
|
88
|
+
const raw = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
89
|
+
if (raw)
|
|
90
|
+
return parseStored(raw);
|
|
64
91
|
}
|
|
65
92
|
catch {
|
|
66
93
|
// 降级
|
package/dist/logger.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Logger, createHttpTransport } from "@chromepilot/logger-kit/client";
|
|
2
2
|
import { PersistentLogQueue } from "@chromepilot/logger-kit/queue-node";
|
|
3
|
-
import { loadConfig } from "./config.js";
|
|
3
|
+
import { loadConfig, resolveDataDir } from "./config.js";
|
|
4
4
|
import { getToken } from "./keychain.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
let logger = null;
|
|
@@ -25,7 +25,7 @@ export function getCliLogger() {
|
|
|
25
25
|
return logger;
|
|
26
26
|
}
|
|
27
27
|
function homeDir() {
|
|
28
|
-
return
|
|
28
|
+
return resolveDataDir();
|
|
29
29
|
}
|
|
30
30
|
export async function initCliLogger(options) {
|
|
31
31
|
const cfg = loadConfig();
|
package/dist/updater.js
CHANGED
|
@@ -21,9 +21,9 @@ import { spawnSync } from 'node:child_process';
|
|
|
21
21
|
import { fileURLToPath } from 'node:url';
|
|
22
22
|
import { createCliUpdater } from '@chromepilot/kit';
|
|
23
23
|
import { readInstalledVersions } from './version.js';
|
|
24
|
+
import { resolveDataDir } from './config.js';
|
|
24
25
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
25
|
-
const
|
|
26
|
-
const ROOT = () => path.join(HOME(), '.hunter-mate');
|
|
26
|
+
const ROOT = resolveDataDir;
|
|
27
27
|
const CLI_PREFIX = () => path.join(ROOT(), 'cli');
|
|
28
28
|
/**
|
|
29
29
|
* 判定是否开发软链模式(纯函数,便于单测):
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
* 命令错误统一出口(对应 fix #18/#28):
|
|
3
3
|
* - logger 留痕(后台可检索,与现有 getCliLogger().error 一致)
|
|
4
4
|
* - console.error 落终端(用户能直接看懂,不再静默 exit 1)
|
|
5
|
-
* - 401/403
|
|
5
|
+
* - 401/403 时给出重新登录的中文提示;
|
|
6
|
+
* hmh#43:token 由 SaaS 签发(本地 server 未运行时登录所致)时给出定向诊断,
|
|
7
|
+
* 不再笼统报"登录已过期"
|
|
6
8
|
*
|
|
7
9
|
* 调用方随后自行 process.exit(1)。
|
|
8
10
|
*/
|
|
9
|
-
export declare function printCommandError(scope: string, err: unknown): void
|
|
11
|
+
export declare function printCommandError(scope: string, err: unknown): Promise<void>;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { getCliLogger } from '../logger.js';
|
|
2
|
+
import { getTokenInfo } from '../keychain.js';
|
|
2
3
|
/**
|
|
3
4
|
* 命令错误统一出口(对应 fix #18/#28):
|
|
4
5
|
* - logger 留痕(后台可检索,与现有 getCliLogger().error 一致)
|
|
5
6
|
* - console.error 落终端(用户能直接看懂,不再静默 exit 1)
|
|
6
|
-
* - 401/403
|
|
7
|
+
* - 401/403 时给出重新登录的中文提示;
|
|
8
|
+
* hmh#43:token 由 SaaS 签发(本地 server 未运行时登录所致)时给出定向诊断,
|
|
9
|
+
* 不再笼统报"登录已过期"
|
|
7
10
|
*
|
|
8
11
|
* 调用方随后自行 process.exit(1)。
|
|
9
12
|
*/
|
|
10
|
-
export function printCommandError(scope, err) {
|
|
13
|
+
export async function printCommandError(scope, err) {
|
|
11
14
|
const e = err;
|
|
12
15
|
const status = e?.response?.status;
|
|
13
16
|
const body = e?.response?.data;
|
|
@@ -21,7 +24,20 @@ export function printCommandError(scope, err) {
|
|
|
21
24
|
}
|
|
22
25
|
if (status === 401 || status === 403) {
|
|
23
26
|
console.error(`✗ ${message} (HTTP ${status})`);
|
|
24
|
-
|
|
27
|
+
let issuer = 'unknown';
|
|
28
|
+
try {
|
|
29
|
+
issuer = (await getTokenInfo())?.issuer ?? 'unknown';
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// keychain 不可用时按 unknown 处理
|
|
33
|
+
}
|
|
34
|
+
if (issuer === 'saas') {
|
|
35
|
+
console.error('当前 token 由 SaaS 签发(登录时本地 server 未运行),本地 server 拒绝使用。\n' +
|
|
36
|
+
'请先启动本地 server(hunter-mate start),再重新执行 hunter-mate login。');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.error('登录已过期或无权访问,请运行 hunter-mate login 后重试');
|
|
40
|
+
}
|
|
25
41
|
return;
|
|
26
42
|
}
|
|
27
43
|
console.error(`✗ ${scope}: ${message}${status ? ` (HTTP ${status})` : ''}`);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type LinkKind = 'dir' | 'file';
|
|
2
|
+
export interface LinkResult {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
fallback?: 'copy+marker';
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* linkDev: cross-platform "point at the build artifact" dev-link helper.
|
|
9
|
+
* 实现对齐 chromepilot packages/cli/src/utils/link.ts(SSOT,同构复制)。
|
|
10
|
+
*
|
|
11
|
+
* - POSIX: fs.symlinkSync(target, linkPath, type)
|
|
12
|
+
* - Windows directory: NTFS junction (no admin needed; cannot cross drives)。
|
|
13
|
+
* 跨盘或 junction 失败退化 copy + `<linkPath>.devlink` marker。
|
|
14
|
+
* - Windows file: copy + marker(Windows 文件软链需要 SeCreateSymbolicLink 权限,避免使用)。
|
|
15
|
+
*/
|
|
16
|
+
export declare function linkDev(target: string, linkPath: string, kind?: LinkKind): LinkResult;
|
|
17
|
+
/** lstat 对悬空软链会抛异常而不是返回 false;包一层保证调用方拿到 boolean */
|
|
18
|
+
export declare function isSymbolicLinkSafe(p: string): boolean;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* linkDev: cross-platform "point at the build artifact" dev-link helper.
|
|
5
|
+
* 实现对齐 chromepilot packages/cli/src/utils/link.ts(SSOT,同构复制)。
|
|
6
|
+
*
|
|
7
|
+
* - POSIX: fs.symlinkSync(target, linkPath, type)
|
|
8
|
+
* - Windows directory: NTFS junction (no admin needed; cannot cross drives)。
|
|
9
|
+
* 跨盘或 junction 失败退化 copy + `<linkPath>.devlink` marker。
|
|
10
|
+
* - Windows file: copy + marker(Windows 文件软链需要 SeCreateSymbolicLink 权限,避免使用)。
|
|
11
|
+
*/
|
|
12
|
+
export function linkDev(target, linkPath, kind = 'dir') {
|
|
13
|
+
if (fs.existsSync(linkPath)) {
|
|
14
|
+
try {
|
|
15
|
+
fs.rmSync(linkPath, { recursive: true, force: true });
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
const e = err;
|
|
19
|
+
return { ok: false, error: `清理已存在目标失败: ${e.message}` };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (process.platform !== 'win32') {
|
|
23
|
+
try {
|
|
24
|
+
fs.symlinkSync(target, linkPath, kind);
|
|
25
|
+
return { ok: true };
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const e = err;
|
|
29
|
+
return { ok: false, error: `symlink 失败: ${e.message}` };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Windows + directory: try junction
|
|
33
|
+
if (kind === 'dir') {
|
|
34
|
+
const linkDrive = path.parse(path.resolve(linkPath)).root;
|
|
35
|
+
const targetDrive = path.parse(path.resolve(target)).root;
|
|
36
|
+
if (linkDrive && targetDrive && linkDrive !== targetDrive) {
|
|
37
|
+
try {
|
|
38
|
+
fs.cpSync(target, linkPath, { recursive: true });
|
|
39
|
+
fs.writeFileSync(`${linkPath}.devlink`, path.resolve(target), 'utf-8');
|
|
40
|
+
return { ok: true, fallback: 'copy+marker' };
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const e = err;
|
|
44
|
+
return { ok: false, error: `junction 跨盘符退化失败: ${e.message}` };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
fs.symlinkSync(target, linkPath, 'junction');
|
|
49
|
+
return { ok: true };
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
const e = err;
|
|
53
|
+
try {
|
|
54
|
+
fs.cpSync(target, linkPath, { recursive: true });
|
|
55
|
+
fs.writeFileSync(`${linkPath}.devlink`, path.resolve(target), 'utf-8');
|
|
56
|
+
return { ok: true, fallback: 'copy+marker' };
|
|
57
|
+
}
|
|
58
|
+
catch (err2) {
|
|
59
|
+
const e2 = err2;
|
|
60
|
+
return { ok: false, error: `junction 与 copy 兜底均失败: ${e.message} / ${e2.message}` };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Windows + file: copy + marker
|
|
65
|
+
try {
|
|
66
|
+
fs.copyFileSync(target, linkPath);
|
|
67
|
+
fs.writeFileSync(`${linkPath}.devlink`, path.resolve(target), 'utf-8');
|
|
68
|
+
return { ok: true, fallback: 'copy+marker' };
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const e = err;
|
|
72
|
+
return { ok: false, error: `copy+marker 失败: ${e.message}` };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** lstat 对悬空软链会抛异常而不是返回 false;包一层保证调用方拿到 boolean */
|
|
76
|
+
export function isSymbolicLinkSafe(p) {
|
|
77
|
+
try {
|
|
78
|
+
return fs.lstatSync(p).isSymbolicLink();
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
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 算法完全等价
|
|
@@ -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.js
CHANGED
|
@@ -2,9 +2,9 @@ import { spawn } from 'child_process';
|
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import * as http from 'http';
|
|
5
|
-
import { isMainModule } from './utils/script-path';
|
|
6
|
-
|
|
7
|
-
const ROOT =
|
|
5
|
+
import { isMainModule } from './utils/script-path.js';
|
|
6
|
+
import { resolveDataDir } from './config.js';
|
|
7
|
+
const ROOT = resolveDataDir;
|
|
8
8
|
const SERVER_PID_FILE = () => path.join(ROOT(), 'server.pid');
|
|
9
9
|
const WATCHDOG_PID_FILE = () => path.join(ROOT(), 'watchdog.pid');
|
|
10
10
|
const CRASH_LOG_FILE = () => path.join(ROOT(), 'server-crash.log');
|
package/dist/web/dist/404.html
CHANGED
|
@@ -1 +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\":\"
|
|
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
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="3670dc30-7b94-42ec-8ee2-03949c228709",e._sentryDebugIdIdentifier="sentry-dbid-3670dc30-7b94-42ec-8ee2-03949c228709")}catch(e){}}(),(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[745],{6452:function(e,t,s){Promise.resolve().then(s.bind(s,1266))},1266:function(e,t,s){"use strict";s.r(t),s.d(t,{default:function(){return n}});var r=s(2835),l=s(635);function a(e){let{apiUrl:t,pollIntervalMs:s}=e,{logs:a,loading:n,error:c,paused:d,filters:i,setFilters:o,pause:u,resume:x,refresh:m}=function(e){let{apiUrl:t,pollIntervalMs:s=2500}=e,[r,a]=(0,l.useState)([]),[n,c]=(0,l.useState)(!1),[d,i]=(0,l.useState)(null),[o,u]=(0,l.useState)(!1),[x,m]=(0,l.useState)({}),h=(0,l.useRef)(void 0),p=t.replace(/\/$/,""),f=(0,l.useCallback)(async(e=!0)=>{if(!o||!e){c(!0);try{let t=new URLSearchParams;x.sessionId&&t.set("sessionId",x.sessionId),x.context&&t.set("context",x.context),x.level&&t.set("level",x.level),e&&h.current&&t.set("lastId",String(h.current)),t.set("limit","200");let s=await fetch(`${p}/logs?${t.toString()}`);if(!s.ok)throw Error(`HTTP ${s.status}`);let r=(await s.json()).items||[];e&&r.length?a(e=>{let t=new Set(e.map(e=>e.id));return[...r.filter(e=>!t.has(e.id)),...e].slice(0,1e3)}):a(r),r.length&&(h.current=Math.max(...r.map(e=>e.id||0))),i(null)}catch(e){i(e.message||String(e))}finally{c(!1)}}},[p,x,o]);return(0,l.useEffect)(()=>{h.current=void 0,a([]),f(!1)},[x.sessionId,x.context,x.level]),(0,l.useEffect)(()=>{if(o)return;let e=setInterval(()=>f(!0),s);return()=>clearInterval(e)},[f,o,s]),{logs:r,loading:n,error:d,paused:o,filters:x,setFilters:m,pause:()=>u(!0),resume:()=>u(!1),refresh:()=>f(!1)}}({apiUrl:t,pollIntervalMs:s}),h=(0,l.useRef)(null);return(0,l.useEffect)(()=>{!d&&h.current&&h.current.scrollIntoView({behavior:"smooth"})},[a,d]),(0,r.jsx)("div",{className:"min-h-screen bg-gray-50 p-4 text-sm",children:(0,r.jsxs)("div",{className:"mx-auto max-w-7xl",children:[(0,r.jsxs)("div",{className:"mb-4 flex flex-wrap items-center gap-3 rounded-lg bg-white p-3 shadow",children:[(0,r.jsx)("input",{type:"text",placeholder:"sessionId",value:i.sessionId||"",onChange:e=>o({...i,sessionId:e.target.value}),className:"rounded border border-gray-300 px-2 py-1"}),(0,r.jsx)("select",{value:i.context||"",onChange:e=>o({...i,context:e.target.value}),className:"rounded border border-gray-300 px-2 py-1",children:["","cli","server","content","background","sidepanel"].map(e=>(0,r.jsx)("option",{value:e,children:e||"all contexts"},e))}),(0,r.jsx)("select",{value:i.level||"",onChange:e=>o({...i,level:e.target.value}),className:"rounded border border-gray-300 px-2 py-1",children:["","debug","info","warn","error"].map(e=>(0,r.jsx)("option",{value:e,children:e||"all levels"},e))}),(0,r.jsx)("button",{onClick:()=>d?x():u(),className:`rounded px-3 py-1 font-medium ${d?"bg-green-600 text-white":"bg-yellow-500 text-white"}`,children:d?"Resume":"Pause"}),(0,r.jsx)("button",{onClick:m,className:"rounded bg-blue-600 px-3 py-1 font-medium text-white",children:"Refresh"}),n&&(0,r.jsx)("span",{className:"text-gray-500",children:"Loading..."}),c&&(0,r.jsxs)("span",{className:"text-red-600",children:["Error: ",c]})]}),(0,r.jsx)("div",{className:"rounded-lg bg-white shadow",children:(0,r.jsxs)("div",{className:"max-h-[70vh] overflow-auto",children:[(0,r.jsxs)("table",{className:"w-full table-auto border-collapse",children:[(0,r.jsx)("thead",{className:"sticky top-0 bg-gray-100",children:(0,r.jsxs)("tr",{children:[(0,r.jsx)("th",{className:"px-3 py-2 text-left font-semibold text-gray-700",children:"Time"}),(0,r.jsx)("th",{className:"px-3 py-2 text-left font-semibold text-gray-700",children:"Context"}),(0,r.jsx)("th",{className:"px-3 py-2 text-left font-semibold text-gray-700",children:"Level"}),(0,r.jsx)("th",{className:"px-3 py-2 text-left font-semibold text-gray-700",children:"Message"}),(0,r.jsx)("th",{className:"px-3 py-2 text-left font-semibold text-gray-700",children:"Meta"})]})}),(0,r.jsx)("tbody",{children:a.map(e=>(0,r.jsxs)("tr",{className:"border-b border-gray-100 hover:bg-gray-50",children:[(0,r.jsx)("td",{className:"px-3 py-2 whitespace-nowrap text-gray-500",children:new Date(e.timestamp).toLocaleTimeString()}),(0,r.jsx)("td",{className:"px-3 py-2",children:e.context}),(0,r.jsx)("td",{className:"px-3 py-2",children:(0,r.jsx)("span",{className:function(e){let t="rounded px-2 py-0.5 text-xs font-medium ";switch(e){case"error":return t+"bg-red-100 text-red-700";case"warn":return t+"bg-yellow-100 text-yellow-700";case"info":return t+"bg-blue-100 text-blue-700";default:return t+"bg-gray-100 text-gray-600"}}(e.level),children:e.level})}),(0,r.jsx)("td",{className:"px-3 py-2 max-w-md truncate",title:e.message,children:e.message}),(0,r.jsx)("td",{className:"px-3 py-2",children:e.meta?(0,r.jsxs)("details",{children:[(0,r.jsx)("summary",{className:"cursor-pointer text-blue-600",children:"meta"}),(0,r.jsx)("pre",{className:"mt-1 max-w-xs overflow-auto rounded bg-gray-100 p-1 text-xs",children:JSON.stringify(e.meta,null,2)})]}):"-"})]},e.id))})]}),(0,r.jsx)("div",{ref:h})]})})]})})}function n(){return(0,r.jsx)(a,{apiUrl:"",pollIntervalMs:2500})}}},function(e){e.O(0,[400,935,744],function(){return e(e.s=6452)}),_N_E=e.O()}]);
|
|
@@ -1 +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/app/auth/verify/page-8e5cff53d6f7d8e1.js" async=""></script><script src="/_next/static/chunks/589-d632233641f35681.js" async=""></script><script src="/_next/static/chunks/app/layout-83e623e973c1693f.js" async=""></script><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"><!--$!--><template data-dgst="BAILOUT_TO_CLIENT_SIDE_RENDERING"></template><div class="flex min-h-screen items-center justify-center">加载中...</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:\"$Sreact.suspense\"\n5:I[1332,[\"937\",\"static/chunks/app/auth/verify/page-8e5cff53d6f7d8e1.js\"],\"default\"]\n6:I[4268,[],\"\"]\n7:I[1050,[],\"\"]\n8:I[4798,[\"589\",\"static/chunks/589-d632233641f35681.js\",\"185\",\"static/chunks/app/layout-83e623e973c1693f.js\"],\"SystemSidebar\"]\na:I[2319,[],\"\"]\nb:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"
|
|
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/app/auth/verify/page-8e5cff53d6f7d8e1.js" async=""></script><script src="/_next/static/chunks/589-d632233641f35681.js" async=""></script><script src="/_next/static/chunks/app/layout-83e623e973c1693f.js" async=""></script><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"><!--$!--><template data-dgst="BAILOUT_TO_CLIENT_SIDE_RENDERING"></template><div class="flex min-h-screen items-center justify-center">加载中...</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:\"$Sreact.suspense\"\n5:I[1332,[\"937\",\"static/chunks/app/auth/verify/page-8e5cff53d6f7d8e1.js\"],\"default\"]\n6:I[4268,[],\"\"]\n7:I[1050,[],\"\"]\n8:I[4798,[\"589\",\"static/chunks/589-d632233641f35681.js\",\"185\",\"static/chunks/app/layout-83e623e973c1693f.js\"],\"SystemSidebar\"]\na:I[2319,[],\"\"]\nb:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"WdJr3NhHjlu5xN0qOap1k\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"auth\",\"verify\"],\"initialTree\":[\"\",{\"children\":[\"auth\",{\"children\":[\"verify\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"auth\",{\"children\":[\"verify\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[\"$\",\"$4\",null,{\"fallback\":[\"$\",\"div\",null,{\"className\":\"flex min-h-screen items-center justify-center\",\"children\":\"加载中...\"}],\"children\":[\"$\",\"$L5\",null,{}]}],null],null],null]},[null,[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"auth\",\"children\",\"verify\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[null,[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"auth\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",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\":[[\"$\",\"$L8\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 overflow-hidden\",\"children\":[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"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.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$L9\"],\"globalErrorComponent\":\"$a\",\"missingSlots\":\"$Wb\"}]\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"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>
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
4:I[4268,[],""]
|
|
4
4
|
5:I[1050,[],""]
|
|
5
5
|
6:I[4798,["589","static/chunks/589-d632233641f35681.js","185","static/chunks/app/layout-83e623e973c1693f.js"],"SystemSidebar"]
|
|
6
|
-
0:["
|
|
6
|
+
0:["WdJr3NhHjlu5xN0qOap1k",[[["",{"children":["auth",{"children":["verify",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["auth",{"children":["verify",{"children":["__PAGE__",{},[["$L1",["$","$2",null,{"fallback":["$","div",null,{"className":"flex min-h-screen items-center justify-center","children":"加载中..."}],"children":["$","$L3",null,{}]}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","auth","children","verify","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","auth","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":{"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."}]}]]}]}]],"notFoundStyles":[]}]}]]}]}]],null],null],["$L7",null]]]]
|
|
7
7
|
7:[["$","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 采集/解析/入库仪表盘"}]]
|
|
8
8
|
1:null
|