hunter-mate 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/assets/extension/background/{service-worker.20261017012007.js → service-worker.20261019161523.js} +56 -4
  2. package/dist/assets/extension/background/service-worker.js +56 -4
  3. package/dist/assets/extension/build-info.json +1 -1
  4. package/dist/assets/extension/manifest.json +3 -3
  5. package/dist/assets/server/chunks/{chunk-SAJB6JRK.mjs → chunk-VL7WHUEV.mjs} +556 -8
  6. package/dist/assets/server/chunks/{script-rule-ZJN6CEYX.mjs → script-rule-4RZQ2PQE.mjs} +1 -2
  7. package/dist/assets/server/main.mjs +1038 -870
  8. package/dist/index.js +178 -24
  9. package/dist/watchdog.js +14 -3
  10. package/dist/web/dist/404.html +1 -1
  11. package/dist/web/dist/_next/static/chunks/187-f067914dcd1330c2.js +32 -0
  12. package/dist/web/dist/_next/static/chunks/253-9278ce6c4d446329.js +1 -0
  13. package/dist/web/dist/_next/static/chunks/{589-f984bff035a1cb85.js → 589-cc56950ae4117cdd.js} +1 -1
  14. package/dist/web/dist/_next/static/chunks/659-122057f46f941df7.js +1 -0
  15. package/dist/web/dist/_next/static/chunks/{686-9f419b70feea9470.js → 686-05b99d3674f45bf7.js} +1 -1
  16. package/dist/web/dist/_next/static/chunks/728-cffab7e836020551.js +12 -0
  17. package/dist/web/dist/_next/static/chunks/{865-0ed23dd43c0832a2.js → 865-8e1d8c34192526ed.js} +1 -1
  18. package/dist/web/dist/_next/static/chunks/{935-7be3e60dd8bc29d2.js → 935-efb30b9f6f558e3f.js} +1 -1
  19. package/dist/web/dist/_next/static/chunks/{a7067448-e416655baf443992.js → a7067448-3f2b194cfadb91fb.js} +1 -1
  20. package/dist/web/dist/_next/static/chunks/app/_not-found/{page-5b7249eb3c9a6cb9.js → page-d939b40bb8878d26.js} +1 -1
  21. package/dist/web/dist/_next/static/chunks/app/admin/data/{page-14698e9c4ddaa6d9.js → page-df1d84c14e85f294.js} +1 -1
  22. package/dist/web/dist/_next/static/chunks/app/auth/verify/{page-05304d5803008d61.js → page-cfeb844e1b72ccaa.js} +1 -1
  23. package/dist/web/dist/_next/static/chunks/app/companies/{page-e8d02fe997579315.js → page-57b1ef0b12134ce0.js} +1 -1
  24. package/dist/web/dist/_next/static/chunks/app/company/admin/{page-c2584183bc4b34d1.js → page-010928306f8df0ed.js} +1 -1
  25. package/dist/web/dist/_next/static/chunks/app/entity/{page-08755f96102f0565.js → page-fa96319650d38e78.js} +1 -1
  26. package/dist/web/dist/_next/static/chunks/app/jobs/page-5ba0bdc881b98d42.js +1 -0
  27. package/dist/web/dist/_next/static/chunks/app/{layout-af39afc7866e74db.js → layout-bd9a7e5e4474b692.js} +1 -1
  28. package/dist/web/dist/_next/static/chunks/app/logs/{page-be50a4e10b1a0024.js → page-bcdbb3885abda5a2.js} +1 -1
  29. package/dist/web/dist/_next/static/chunks/app/matching/jobs/[id]/talents/{page-cf445b0cb8c2cb0a.js → page-8aca89db1e666a49.js} +1 -1
  30. package/dist/web/dist/_next/static/chunks/app/matching/portraits/[id]/jobs/{page-c7ff0d79b6a75915.js → page-7086f1b773e57511.js} +1 -1
  31. package/dist/web/dist/_next/static/chunks/app/{page-bd282e1e5f0965f1.js → page-49fe1e8630d2237e.js} +1 -1
  32. package/dist/web/dist/_next/static/chunks/app/parselog/{page-9814e75d6900a743.js → page-fcdfdd41cf1f86f7.js} +1 -1
  33. package/dist/web/dist/_next/static/chunks/app/recordings/{page-441016638b43c4f8.js → page-7ba5d89391c9dace.js} +1 -1
  34. package/dist/web/dist/_next/static/chunks/app/resource-usage/{page-f6fa06bfe21bcd32.js → page-7b939cf673d764e6.js} +1 -1
  35. package/dist/web/dist/_next/static/chunks/app/shared/[token]/{page-c9c5042a2d07c0bc.js → page-df87328c52f862f1.js} +1 -1
  36. package/dist/web/dist/_next/static/chunks/app/snapshots/[id]/agent-prompt/{page-f54cf2f0058035ca.js → page-7d4d25de2c6704e9.js} +1 -1
  37. package/dist/web/dist/_next/static/chunks/app/talents/{page-0edef6d07b3cf69d.js → page-5a2caa7a503ee041.js} +1 -1
  38. package/dist/web/dist/_next/static/chunks/app/team/insights/{page-8b3934df3e292368.js → page-f097b4b8578a6e5d.js} +1 -1
  39. package/dist/web/dist/_next/static/css/a8f0a381a2372781.css +3 -0
  40. package/dist/web/dist/admin/data.html +1 -1
  41. package/dist/web/dist/admin/data.txt +5 -5
  42. package/dist/web/dist/auth/verify.html +1 -1
  43. package/dist/web/dist/auth/verify.txt +5 -5
  44. package/dist/web/dist/companies.html +1 -1
  45. package/dist/web/dist/companies.txt +5 -5
  46. package/dist/web/dist/company/admin.html +1 -1
  47. package/dist/web/dist/company/admin.txt +5 -5
  48. package/dist/web/dist/entity.html +1 -1
  49. package/dist/web/dist/entity.txt +5 -5
  50. package/dist/web/dist/index.html +1 -1
  51. package/dist/web/dist/index.txt +5 -5
  52. package/dist/web/dist/jobs.html +1 -1
  53. package/dist/web/dist/jobs.txt +5 -5
  54. package/dist/web/dist/logs.html +1 -1
  55. package/dist/web/dist/logs.txt +5 -5
  56. package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -1
  57. package/dist/web/dist/matching/jobs/placeholder/talents.txt +5 -5
  58. package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -1
  59. package/dist/web/dist/matching/portraits/placeholder/jobs.txt +5 -5
  60. package/dist/web/dist/parselog.html +1 -1
  61. package/dist/web/dist/parselog.txt +5 -5
  62. package/dist/web/dist/recordings.html +1 -1
  63. package/dist/web/dist/recordings.txt +5 -5
  64. package/dist/web/dist/resource-usage.html +1 -1
  65. package/dist/web/dist/resource-usage.txt +5 -5
  66. package/dist/web/dist/shared/placeholder.html +1 -1
  67. package/dist/web/dist/shared/placeholder.txt +5 -5
  68. package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -1
  69. package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +5 -5
  70. package/dist/web/dist/talents.html +1 -1
  71. package/dist/web/dist/talents.txt +5 -5
  72. package/dist/web/dist/team/insights.html +1 -1
  73. package/dist/web/dist/team/insights.txt +5 -5
  74. package/package.json +1 -1
  75. package/dist/assets/server/chunks/chunk-BLXHCSZD.mjs +0 -565
  76. package/dist/assets/server/chunks/esm-4U746B76.mjs +0 -29
  77. package/dist/web/dist/_next/static/chunks/105-dcd8f6d5867c8995.js +0 -32
  78. package/dist/web/dist/_next/static/chunks/253-a05d05b94bfbd7a4.js +0 -1
  79. package/dist/web/dist/_next/static/chunks/555-e2a871b9d2eccb03.js +0 -12
  80. package/dist/web/dist/_next/static/chunks/852-ad19b97821a4cf9e.js +0 -1
  81. package/dist/web/dist/_next/static/chunks/app/jobs/page-4827a9ef286b6483.js +0 -1
  82. package/dist/web/dist/_next/static/css/10ba1fa1d6ce23a7.css +0 -3
  83. /package/dist/web/dist/_next/static/{hBLezfvVOMiGqm4V9F15i → m0UGHVTGvtvb9mn4-uzJJ}/_buildManifest.js +0 -0
  84. /package/dist/web/dist/_next/static/{hBLezfvVOMiGqm4V9F15i → m0UGHVTGvtvb9mn4-uzJJ}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -63698,6 +63698,26 @@ function processCmdline(pid) {
63698
63698
  return "";
63699
63699
  }
63700
63700
  }
63701
+ function parentPid(pid) {
63702
+ try {
63703
+ if (process.platform === "win32") {
63704
+ const r2 = spawnSync2(
63705
+ "wmic",
63706
+ ["process", "where", `processId=${pid}`, "get", "ParentProcessId"],
63707
+ { encoding: "utf-8" }
63708
+ );
63709
+ if (r2.status !== 0) return null;
63710
+ const ppid2 = Number((r2.stdout ?? "").trim().split(/\s+/).pop());
63711
+ return Number.isInteger(ppid2) && ppid2 > 0 ? ppid2 : null;
63712
+ }
63713
+ const r = spawnSync2("ps", ["-p", String(pid), "-o", "ppid="], { encoding: "utf-8" });
63714
+ if (r.status !== 0) return null;
63715
+ const ppid = Number((r.stdout ?? "").trim());
63716
+ return Number.isInteger(ppid) && ppid > 0 ? ppid : null;
63717
+ } catch {
63718
+ return null;
63719
+ }
63720
+ }
63701
63721
  async function waitPortFree(port, timeoutMs) {
63702
63722
  const deadline = Date.now() + timeoutMs;
63703
63723
  while (Date.now() < deadline) {
@@ -63769,12 +63789,17 @@ __export(server_exports, {
63769
63789
  acquireStartLock: () => acquireStartLock,
63770
63790
  defaultPortFromConfig: () => defaultPortFromConfig,
63771
63791
  findServerRoot: () => findServerRoot,
63792
+ isHmServerCmd: () => isHmServerCmd,
63793
+ isHmWatchdogCmd: () => isHmWatchdogCmd,
63794
+ probeHealthPid: () => probeHealthPid,
63772
63795
  probeServerHealth: () => probeServerHealth,
63773
63796
  reclaimPortIfOurs: () => reclaimPortIfOurs,
63797
+ restartCommand: () => restartCommand,
63774
63798
  rotateLogIfNeeded: () => rotateLogIfNeeded,
63775
63799
  runStart: () => runStart,
63776
63800
  runStop: () => runStop,
63777
63801
  startCommand: () => startCommand,
63802
+ stopByPortDiscovery: () => stopByPortDiscovery,
63778
63803
  stopCommand: () => stopCommand,
63779
63804
  tryReadPid: () => tryReadPid
63780
63805
  });
@@ -63936,8 +63961,6 @@ async function runStart(opts) {
63936
63961
  }
63937
63962
  }
63938
63963
  async function reclaimPortIfOurs(port, notes) {
63939
- const isHmServerCmd = (cmd) => /packages[/\\]server[/\\]dist[/\\]main|assets[/\\]server[/\\]main/.test(cmd);
63940
- const isHmWatchdogCmd = (cmd) => /watchdog\.js/.test(cmd) && /hunter-mate|packages[/\\]cli|cli[/\\]dist/.test(cmd);
63941
63964
  for (let round = 1; round <= 3; round++) {
63942
63965
  const occupant = findListeningPid(port);
63943
63966
  if (!occupant) return { ok: true, pid: null, msg: "" };
@@ -63968,6 +63991,103 @@ async function reclaimPortIfOurs(port, notes) {
63968
63991
  msg: `\u2717 \u7AEF\u53E3 ${port} \u88AB\u8FDB\u7A0B(pid=${still ?? "\u672A\u77E5"})\u53CD\u590D\u5360\u7528,\u5DF2\u91CD\u8BD5 3 \u8F6E\u4ECD\u65E0\u6CD5\u91CA\u653E,\u8BF7\u624B\u5DE5\u6392\u67E5`
63969
63992
  };
63970
63993
  }
63994
+ async function probeHealthPid(url2, timeoutMs = 1500) {
63995
+ try {
63996
+ const res = await fetch(`${url2}/health`, { signal: AbortSignal.timeout(timeoutMs) });
63997
+ if (!res.ok) return null;
63998
+ const body = await res.json();
63999
+ const pid = Number(body?.pid);
64000
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
64001
+ } catch {
64002
+ return null;
64003
+ }
64004
+ }
64005
+ async function stopByPortDiscovery(port, opts, io = {}) {
64006
+ const findPid = io.findListeningPidFn ?? findListeningPid;
64007
+ const cmdline = io.processCmdlineFn ?? processCmdline;
64008
+ const getPpid = io.parentPidFn ?? parentPid;
64009
+ const probePid = io.probeHealthPidFn ?? probeHealthPid;
64010
+ const kill = io.killGracefullyFn ?? killGracefully;
64011
+ const waitFree = io.waitPortFreeFn ?? waitPortFree;
64012
+ const occupant = findPid(port);
64013
+ if (!occupant) {
64014
+ return { stopped: false, pid: null, via: null, msg: "(server \u672A\u8FD0\u884C,\u65E0\u9700\u505C\u6B62)" };
64015
+ }
64016
+ const cmd = cmdline(occupant);
64017
+ if (!isHmServerCmd(cmd)) {
64018
+ return {
64019
+ stopped: false,
64020
+ pid: occupant,
64021
+ via: null,
64022
+ msg: `\u2717 \u7AEF\u53E3 ${port} \u88AB\u5176\u4ED6\u7A0B\u5E8F\u5360\u7528(pid=${occupant}: ${cmd.slice(0, 80) || "\u547D\u4EE4\u884C\u4E0D\u53EF\u8BFB"}),\u672A\u6267\u884C\u505C\u6B62;\u8BF7\u5148\u91CA\u653E\u8BE5\u7AEF\u53E3`
64023
+ };
64024
+ }
64025
+ const healthPid = await probePid(opts.url);
64026
+ if (healthPid === null) {
64027
+ return {
64028
+ stopped: false,
64029
+ pid: occupant,
64030
+ via: null,
64031
+ msg: `\u2717 \u7AEF\u53E3 ${port} \u4E0A\u7684 server(pid=${occupant})\u65E0 /health \u54CD\u5E94,\u672A\u6267\u884C\u505C\u6B62;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B\u8FDB\u7A0B\u8BF7\u624B\u5DE5 kill pid=${occupant}`
64032
+ };
64033
+ }
64034
+ if (healthPid !== occupant) {
64035
+ return {
64036
+ stopped: false,
64037
+ pid: occupant,
64038
+ via: null,
64039
+ msg: `\u2717 \u7AEF\u53E3 ${port} \u4E0A\u7684 server \u8EAB\u4EFD\u65E0\u6CD5\u786E\u8BA4(/health \u81EA\u62A5 pid=${healthPid} \u4E0E\u76D1\u542C\u8FDB\u7A0B pid=${occupant} \u4E0D\u4E00\u81F4),\u672A\u6267\u884C\u505C\u6B62;\u8BF7\u5148\u91CA\u653E\u8BE5\u7AEF\u53E3`
64040
+ };
64041
+ }
64042
+ const found = (() => {
64043
+ const fromFile = tryReadPidFile(WATCHDOG_PID_FILE());
64044
+ if (fromFile && fromFile !== occupant && fromFile !== 1 && isHmWatchdogCmd(cmdline(fromFile))) {
64045
+ return { wdPid: fromFile };
64046
+ }
64047
+ const ppid = getPpid(occupant);
64048
+ if (ppid && ppid !== 1 && ppid !== process.pid && isHmWatchdogCmd(cmdline(ppid))) {
64049
+ return { wdPid: ppid };
64050
+ }
64051
+ return null;
64052
+ })();
64053
+ const intro = `\u26A0 \u672A\u627E\u5230 pid \u6587\u4EF6,\u5DF2\u4ECE\u7AEF\u53E3 ${port} \u53D1\u73B0\u8FD0\u884C\u4E2D\u7684 server (pid=${occupant})`;
64054
+ if (found) {
64055
+ await kill(found.wdPid, 5e3);
64056
+ if (await waitFree(port, 8e3)) {
64057
+ cleanPidFile(WATCHDOG_PID_FILE());
64058
+ cleanPidFile(PID_FILE());
64059
+ return {
64060
+ stopped: true,
64061
+ pid: occupant,
64062
+ via: "watchdog",
64063
+ msg: `${intro}
64064
+ \u26A0 \u68C0\u6D4B\u5230\u5176 watchdog (pid=${found.wdPid}),\u5DF2\u4E00\u5E76\u505C\u6B62
64065
+ \u2713 server \u5DF2\u505C\u6B62 (pid=${occupant})`
64066
+ };
64067
+ }
64068
+ await kill(occupant, 5e3);
64069
+ if (await waitFree(port, 4e3)) {
64070
+ cleanPidFile(WATCHDOG_PID_FILE());
64071
+ cleanPidFile(PID_FILE());
64072
+ return {
64073
+ stopped: true,
64074
+ pid: occupant,
64075
+ via: "server",
64076
+ msg: `${intro}
64077
+ \u26A0 watchdog (pid=${found.wdPid}) \u5DF2\u505C\u6B62,\u4F46\u5176\u6258\u7BA1\u7684 server \u672A\u8FDE\u5E26\u9000\u51FA,\u5DF2\u8865\u6740
64078
+ \u2713 server \u5DF2\u505C\u6B62 (pid=${occupant})`
64079
+ };
64080
+ }
64081
+ return { stopped: false, pid: occupant, via: null, msg: `\u2717 \u7AEF\u53E3 ${port} \u957F\u65F6\u95F4\u672A\u91CA\u653E,\u8BF7\u624B\u5DE5\u6392\u67E5(pid=${occupant})` };
64082
+ }
64083
+ await kill(occupant, 5e3);
64084
+ if (await waitFree(port, 8e3)) {
64085
+ cleanPidFile(PID_FILE());
64086
+ return { stopped: true, pid: occupant, via: "server", msg: `${intro}
64087
+ \u2713 server \u5DF2\u505C\u6B62 (pid=${occupant})` };
64088
+ }
64089
+ return { stopped: false, pid: occupant, via: null, msg: `\u2717 \u7AEF\u53E3 ${port} \u957F\u65F6\u95F4\u672A\u91CA\u653E,\u8BF7\u624B\u5DE5\u6392\u67E5(pid=${occupant})` };
64090
+ }
63971
64091
  async function runStartLocked(opts, ctx) {
63972
64092
  const { url: url2, port, host, notes } = ctx;
63973
64093
  const config = loadConfig();
@@ -64113,14 +64233,14 @@ async function runStartLocked(opts, ctx) {
64113
64233
  tail = log3.split("\n").slice(-30).join("\n").trim();
64114
64234
  } catch {
64115
64235
  }
64116
- cleanPidFile(WATCHDOG_PID_FILE());
64236
+ const wdAlive = watchdogAlive(wd.pid ?? null);
64117
64237
  return {
64118
64238
  started: false,
64119
64239
  pid: wd.pid ?? null,
64120
64240
  url: url2,
64121
- msg: (notes.length ? notes.join("\n") + "\n" : "") + `\u2717 server watchdog \u542F\u52A8\u540E ${probeDeadlineMs / 1e3}s \u5185\u672A\u5C31\u7EEA(pid=${wd.pid}),\u65E5\u5FD7\u5C3E\u90E8:
64241
+ msg: (notes.length ? notes.join("\n") + "\n" : "") + `\u23F3 server \u5C1A\u672A\u5C31\u7EEA(\u5DF2\u7B49\u5F85 ${probeDeadlineMs / 1e3}s${wdAlive ? ",watchdog \u4ECD\u5728\u540E\u53F0\u62C9\u8D77" : ",watchdog \u5DF2\u9000\u51FA"}),\u65E5\u5FD7\u5C3E\u90E8:
64122
64242
  ${tail || "(server.log \u4E3A\u7A7A)"}
64123
- \u6392\u969C: hunter-mate doctor \u6216 TROUBLESHOOTING.md#server-\u542F\u52A8\u5373\u5D29abi`
64243
+ ` + (wdAlive ? `\u5EFA\u8BAE:\u7A0D\u5019\u6267\u884C hunter-mate status \u786E\u8BA4\u5C31\u7EEA;\u9AD8\u8D1F\u8F7D\u673A\u5668\u9996\u6B21\u542F\u52A8\u53EF\u80FD\u9700\u8981 1-2 \u5206\u949F` : `\u6392\u969C: hunter-mate doctor \u6216 TROUBLESHOOTING.md#server-\u542F\u52A8\u5373\u5D29`)
64124
64244
  };
64125
64245
  }
64126
64246
  try {
@@ -64152,9 +64272,9 @@ async function runStop() {
64152
64272
  msg: `\u2717 server \u65E0\u54CD\u5E94(${url2}/health \u4E0D\u53EF\u8FBE),watchdog pid=${wdPid} \u672A\u6740(\u7591\u4F3C stale pid,\u53EF\u80FD\u5DF2\u88AB\u5176\u4ED6\u8FDB\u7A0B\u590D\u7528)\u3002pid \u6587\u4EF6\u4FDD\u7559\u4EE5\u4FBF\u590D\u63A2;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B\u8FDB\u7A0B\u8BF7\u624B\u5DE5 kill`
64153
64273
  };
64154
64274
  }
64155
- const ok2 = killGracefullySync(wdPid);
64275
+ const ok = killGracefullySync(wdPid);
64156
64276
  cleanPidFile(WATCHDOG_PID_FILE());
64157
- if (ok2) {
64277
+ if (ok) {
64158
64278
  try {
64159
64279
  const pid2 = tryReadPid();
64160
64280
  if (pid2) {
@@ -64167,22 +64287,25 @@ async function runStop() {
64167
64287
  }
64168
64288
  }
64169
64289
  const pid = tryReadPid();
64170
- if (!pid) return { stopped: false, pid: null, msg: "no server.pid found or process dead" };
64171
- if (!healthy) {
64172
- return {
64173
- stopped: false,
64174
- pid,
64175
- msg: `\u2717 pid=${pid} \u5B58\u6D3B\u4F46 server \u65E0\u54CD\u5E94,\u672A\u53D1\u9001 kill \u4FE1\u53F7(\u7591\u4F3C stale pid,\u53EF\u80FD\u5C5E\u4E8E\u5176\u4ED6\u8FDB\u7A0B)\u3002pid \u6587\u4EF6\u4FDD\u7559\u4EE5\u4FBF\u590D\u63A2;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B server \u8BF7\u624B\u5DE5 kill`
64176
- };
64177
- }
64178
- const ok = killGracefullySync(pid);
64179
- if (!ok) {
64180
- return { stopped: false, pid, msg: `failed to signal ${pid}` };
64290
+ if (pid) {
64291
+ if (!healthy) {
64292
+ return {
64293
+ stopped: false,
64294
+ pid,
64295
+ msg: `\u2717 pid=${pid} \u5B58\u6D3B\u4F46 server \u65E0\u54CD\u5E94,\u672A\u53D1\u9001 kill \u4FE1\u53F7(\u7591\u4F3C stale pid,\u53EF\u80FD\u5C5E\u4E8E\u5176\u4ED6\u8FDB\u7A0B)\u3002pid \u6587\u4EF6\u4FDD\u7559\u4EE5\u4FBF\u590D\u63A2;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B server \u8BF7\u624B\u5DE5 kill`
64296
+ };
64297
+ }
64298
+ const ok = killGracefullySync(pid);
64299
+ if (!ok) {
64300
+ return { stopped: false, pid, msg: `failed to signal ${pid}` };
64301
+ }
64302
+ cleanPidFile(PID_FILE());
64303
+ return { stopped: true, pid, msg: `server stopped (pid=${pid})` };
64181
64304
  }
64182
- cleanPidFile(PID_FILE());
64183
- return { stopped: true, pid, msg: `server stopped (pid=${pid})` };
64305
+ const port = defaultPortFromConfig(config.serverUrl);
64306
+ return await stopByPortDiscovery(port, { url: url2 });
64184
64307
  }
64185
- var __dirname3, PID_FILE, LOG_FILE, WATCHDOG_PID_FILE, START_LOCK_FILE, START_LOCK_STALE_MS, LOG_MAX_BYTES, LOG_KEEP_FILES, startCommand, stopCommand;
64308
+ var __dirname3, PID_FILE, LOG_FILE, WATCHDOG_PID_FILE, START_LOCK_FILE, START_LOCK_STALE_MS, LOG_MAX_BYTES, LOG_KEEP_FILES, isHmServerCmd, isHmWatchdogCmd, startCommand, stopCommand, restartCommand;
64186
64309
  var init_server = __esm({
64187
64310
  "src/commands/server.ts"() {
64188
64311
  "use strict";
@@ -64198,16 +64321,31 @@ var init_server = __esm({
64198
64321
  START_LOCK_STALE_MS = 9e4;
64199
64322
  LOG_MAX_BYTES = () => Number(process.env.HM_LOG_MAX_BYTES || 50 * 1024 * 1024);
64200
64323
  LOG_KEEP_FILES = 3;
64324
+ isHmServerCmd = (cmd) => /packages[/\\]server[/\\]dist[/\\]main|assets[/\\]server[/\\]main/.test(cmd);
64325
+ isHmWatchdogCmd = (cmd) => /watchdog\.js/.test(cmd) && /hunter-mate|packages[/\\]cli|cli[/\\]dist/.test(cmd);
64201
64326
  startCommand = new Command("start").description("\u542F\u52A8\u672C\u5730 NestJS server\uFF08REST + WebSocket + SPA\uFF09\uFF0C\u5BF9\u5E94 chromepilot start").option("-p, --port <port>", `server \u7AEF\u53E3\uFF0C\u4F18\u5148\u7EA7: -p > \u73AF\u5883\u53D8\u91CF PORT > config.serverUrl(\u65E7\u9ED8\u8BA4 34570 \u5DF2\u7EDF\u4E00\u8FC1\u79FB\u5230 ${DEFAULT_SERVER_PORT})`).option("-h, --host <host>", "\u7ED1\u5B9A host\uFF0C\u9ED8\u8BA4 127.0.0.1", "127.0.0.1").option("-f, --foreground", "\u524D\u53F0\u8FD0\u884C\uFF08\u9ED8\u8BA4\u540E\u53F0 daemon\uFF0C\u5199 server.pid + server.log\uFF09").action(async (opts) => {
64202
64327
  const r = await runStart({ port: opts.port ? Number(opts.port) : void 0, host: opts.host, foreground: opts.foreground });
64203
64328
  console.log(r.msg);
64204
64329
  if (!r.started && !r.pid) process.exit(1);
64205
64330
  });
64206
- stopCommand = new Command("stop").description("\u505C\u6B62\u672C\u5730 server\uFF08\u8BFB ~/.hunter-mate/server.pid \u5E76 SIGTERM\uFF09").action(async () => {
64331
+ stopCommand = new Command("stop").description("\u505C\u6B62\u672C\u5730 server\uFF08\u8BFB ~/.hunter-mate/server.pid \u5E76 SIGTERM;pid \u6587\u4EF6\u7F3A\u5931\u65F6\u6309\u7AEF\u53E3\u56DE\u9000\u53D1\u73B0,\u9A8C\u660E\u8EAB\u4EFD\u540E\u7ECF watchdog \u4E00\u5E76\u505C\u6B62\uFF09").action(async () => {
64207
64332
  const r = await runStop();
64208
64333
  console.log(r.msg);
64209
64334
  if (!r.stopped && r.pid) process.exit(1);
64210
64335
  });
64336
+ restartCommand = new Command("restart").description("\u91CD\u542F\u672C\u5730 server(\u5148\u505C\u6B62\u73B0\u6709\u5B9E\u4F8B\u2014\u2014\u542B\u65E0 pid \u6587\u4EF6\u65F6\u7684\u7AEF\u53E3\u56DE\u9000\u53D1\u73B0,\u518D\u91CD\u65B0\u542F\u52A8;\u505C\u6B62\u88AB\u62D2\u65F6\u4E0D\u542F\u52A8)").option("-p, --port <port>", `server \u7AEF\u53E3\uFF0C\u4F18\u5148\u7EA7: -p > \u73AF\u5883\u53D8\u91CF PORT > config.serverUrl(\u65E7\u9ED8\u8BA4 34570 \u5DF2\u7EDF\u4E00\u8FC1\u79FB\u5230 ${DEFAULT_SERVER_PORT})`).option("-h, --host <host>", "\u7ED1\u5B9A host\uFF0C\u9ED8\u8BA4 127.0.0.1", "127.0.0.1").action(async (opts) => {
64337
+ console.log("-- \u505C\u6B62\u73B0\u6709 server --");
64338
+ const stopR = await runStop();
64339
+ console.log(stopR.msg);
64340
+ if (!stopR.stopped && stopR.pid) {
64341
+ console.log("\u2717 \u91CD\u542F\u5DF2\u4E2D\u6B62:\u73B0\u6709 server \u672A\u80FD\u505C\u6B62,\u672A\u6267\u884C\u542F\u52A8");
64342
+ process.exit(1);
64343
+ }
64344
+ console.log("-- \u542F\u52A8\u65B0 server --");
64345
+ const startR = await runStart({ port: opts.port ? Number(opts.port) : void 0, host: opts.host });
64346
+ console.log(startR.msg);
64347
+ if (!startR.started && !startR.pid) process.exit(1);
64348
+ });
64211
64349
  }
64212
64350
  });
64213
64351
 
@@ -71783,6 +71921,20 @@ ${B3.bold}${B3.cyan}\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
71783
71921
  } catch (e) {
71784
71922
  checks.push({ key: "harness_path", status: "skip", detail: `\u8DF3\u8FC7(\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25): ${e.message}` });
71785
71923
  }
71924
+ {
71925
+ const hcapiBase = process.env.HCAPI_BASE_URL || "http://localhost:7001";
71926
+ const reachable = await axios_default.get(hcapiBase, { timeout: 3e3, proxy: false, validateStatus: () => true }).then(() => true).catch(() => false);
71927
+ if (reachable) {
71928
+ checks.push({ key: "hcapi_reachable", status: "ok", detail: hcapiBase });
71929
+ } else {
71930
+ checks.push({
71931
+ key: "hcapi_reachable",
71932
+ status: "warn",
71933
+ detail: `hcapi \u4E0D\u53EF\u8FBE: ${hcapiBase}(u_person \u4EBA\u624D\u6C60\u641C\u7D22\u5C06\u5931\u8D25;LinkedIn \u9002\u914D\u5668\u4E0D\u53D7\u5F71\u54CD)`
71934
+ });
71935
+ hints.push("\u5728 server \u7684 .env \u914D\u7F6E HCAPI_BASE_URL(\u751F\u4EA7: https://hcapi.hiredchina.com)\u4E0E HCAPI_INTERNAL_TOKEN \u540E\u91CD\u542F server");
71936
+ }
71937
+ }
71786
71938
  const manifestPath = path25.join(initResult.extensionDir, "manifest.json");
71787
71939
  let extInstalled = fs23.existsSync(manifestPath);
71788
71940
  if (extInstalled) {
@@ -73348,7 +73500,7 @@ recommendCommand.command("list").description("\u6309\u804C\u4F4D\u67E5\u63A8\u83
73348
73500
  process.exit(1);
73349
73501
  }
73350
73502
  });
73351
- recommendCommand.command("add").description("\u63A8\u8350\u5EFA\u6863(\u5E42\u7B49):\u5BFB\u8BBF\u4EA4\u4ED8\u767B\u8BB0;--stage recommended \u8FDB\u63A8\u8350\u4EBA\u624D\u6C60").argument("<jobCaseId>", "\u804C\u4F4D case id(\u6570\u5B57)").option("--entity <id>", "\u4EBA\u624D\u5B9E\u4F53 id(talent_profiles)").option("--portrait <id>", "\u4EBA\u624D\u7EDF\u4E00\u6863\u6848 id(talent_portraits)").option("--stage <stage>", "\u76EE\u6807\u9636\u6BB5", "recommended").option("--note <text>", "\u5907\u6CE8(\u5982\u53BB\u91CD\u6821\u9A8C\u7ED3\u8BBA)").option("--form <k=v,k=v>", "\u9636\u6BB5\u8868\u5355\u952E\u503C\u5BF9(\u9017\u53F7\u5206\u9694,\u6A21\u677F\u89C1 GET /recommendations/meta)").option("--name <name>", "\u4EBA\u624D\u540D\u5FEB\u7167(\u8DE8\u7AEF\u53EF\u8BFB)").option("--headline <text>", "headline \u5FEB\u7167").option("--source <text>", "\u6765\u6E90\u5FEB\u7167(\u5982 linkedin/liepin)").option("--url <url>", "\u4E3B\u9875 URL:\u672A\u7ED9 --entity/--portrait \u65F6\u5148\u7ECF /ingest/talents \u5EFA\u6863\u4EBA\u624D\u5B9E\u4F53,\u518D\u6302\u63A8\u8350\u8BB0\u5F55").option("--json", "JSON \u8F93\u51FA\u5EFA\u6863\u7ED3\u679C", false).action(async (jobCaseId, opts) => {
73503
+ recommendCommand.command("add").description("\u63A8\u8350\u5EFA\u6863(\u5E42\u7B49):\u5BFB\u8BBF\u4EA4\u4ED8\u767B\u8BB0;--stage recommended \u8FDB\u63A8\u8350\u4EBA\u624D\u6C60").argument("<jobCaseId>", "\u804C\u4F4D case id(\u6570\u5B57)").option("--entity <id>", "\u4EBA\u624D\u5B9E\u4F53 id(talent_profiles)").option("--portrait <id>", "\u4EBA\u624D\u7EDF\u4E00\u6863\u6848 id(talent_portraits)").option("--stage <stage>", "\u76EE\u6807\u9636\u6BB5", "recommended").option("--note <text>", "\u5907\u6CE8(\u5982\u53BB\u91CD\u6821\u9A8C\u7ED3\u8BBA)").option("--form <k=v,k=v>", "\u9636\u6BB5\u8868\u5355\u952E\u503C\u5BF9(\u9017\u53F7\u5206\u9694,\u6A21\u677F\u89C1 GET /recommendations/meta)").option("--reason <text>", "\u63A8\u8350\u7406\u7531(AI \u7406\u7531,\u8FDB scores.aiReason;\u7528\u6237\u5BA1\u9605\u9875\u636E\u6B64\u5224\u65AD,\u5BFB\u8BBF\u4EA4\u4ED8\u5FC5\u586B)").option("--name <name>", "\u4EBA\u624D\u540D\u5FEB\u7167(\u8DE8\u7AEF\u53EF\u8BFB)").option("--headline <text>", "headline \u5FEB\u7167").option("--source <text>", "\u6765\u6E90\u5FEB\u7167(\u5982 linkedin/liepin)").option("--url <url>", "\u4E3B\u9875 URL:\u672A\u7ED9 --entity/--portrait \u65F6\u5148\u7ECF /ingest/talents \u5EFA\u6863\u4EBA\u624D\u5B9E\u4F53,\u518D\u6302\u63A8\u8350\u8BB0\u5F55").option("--json", "JSON \u8F93\u51FA\u5EFA\u6863\u7ED3\u679C", false).action(async (jobCaseId, opts) => {
73352
73504
  try {
73353
73505
  const config = loadConfig();
73354
73506
  const headers = await authedHeaders5();
@@ -73387,6 +73539,7 @@ recommendCommand.command("add").description("\u63A8\u8350\u5EFA\u6863(\u5E42\u7B
73387
73539
  portraitId,
73388
73540
  note: opts.note,
73389
73541
  formData,
73542
+ scores: opts.reason ? { aiReason: opts.reason } : void 0,
73390
73543
  snapshot: Object.keys(snapshot).length ? snapshot : void 0
73391
73544
  },
73392
73545
  { headers, proxy: false, timeout: 1e4 }
@@ -73623,7 +73776,7 @@ function installLocalProxyBypass() {
73623
73776
  // package.json
73624
73777
  var package_default = {
73625
73778
  name: "hunter-mate",
73626
- version: "0.1.24",
73779
+ version: "0.1.26",
73627
73780
  type: "module",
73628
73781
  description: "HiredChina \u730E\u5934 Agent \u6570\u636E\u52A9\u624B CLI:\u4EBA\u624D\u5E93/\u5BA2\u6237/\u804C\u4F4D\u6570\u636E\u8BBF\u95EE,\u6D4F\u89C8\u5668\u5F55\u5236\u89E3\u6790\u7B80\u5386,server/\u6269\u5C55\u4E00\u81F4\u6027\u81EA\u6108",
73629
73782
  license: "MIT",
@@ -73783,6 +73936,7 @@ program2.addCommand(initCommand);
73783
73936
  program2.addCommand(installCommand);
73784
73937
  program2.addCommand(startCommand);
73785
73938
  program2.addCommand(stopCommand);
73939
+ program2.addCommand(restartCommand);
73786
73940
  program2.addCommand(loginCommand);
73787
73941
  program2.addCommand(logoutCommand);
73788
73942
  program2.addCommand(tokenCommand);
package/dist/watchdog.js CHANGED
@@ -111,6 +111,13 @@ var LivenessProbe = class {
111
111
  }
112
112
  failCount = 0;
113
113
  timer = null;
114
+ /** 启动宽限截止:spawn 后这段时间内探测一律跳过(高负载机器 boot 可达 2min+,2026-10-19 实证) */
115
+ graceUntilMs = 0;
116
+ /** 每次拉起子进程时调用:重设启动宽限并清零失败计数 */
117
+ markBootStart(graceMs) {
118
+ this.graceUntilMs = Date.now() + graceMs;
119
+ this.failCount = 0;
120
+ }
114
121
  async doCheck() {
115
122
  const check = this.opts.check || ((url) => new Promise((resolve2, reject) => {
116
123
  const req = http.get(url, { timeout: 5e3 }, (res) => {
@@ -128,8 +135,10 @@ var LivenessProbe = class {
128
135
  }));
129
136
  await check(this.opts.healthUrl);
130
137
  }
131
- /** 立即探测一次并更新失败计数;达到阈值时回调 onFailure 并清零 */
138
+ /** 立即探测一次并更新失败计数;达到阈值时回调 onFailure 并清零。
139
+ * 启动宽限期内直接跳过(子进程尚在 boot,探测无意义且会误判假活)。 */
132
140
  async checkNow() {
141
+ if (Date.now() < this.graceUntilMs) return;
133
142
  try {
134
143
  await this.doCheck();
135
144
  this.failCount = 0;
@@ -237,6 +246,7 @@ async function runWatchdog() {
237
246
  const logFile = process.env.HM_SERVER_LOG;
238
247
  const nodeArgs = parseNodeArgs(process.env.HM_SERVER_NODE_ARGS);
239
248
  const maxRestartDelayMs = Number(process.env.HM_WATCHDOG_MAX_DELAY_MS || "30000");
249
+ const bootGraceMs = Number(process.env.HM_WATCHDOG_BOOT_GRACE_MS || "150000");
240
250
  if (!entry || !logFile) {
241
251
  console.error("[HunterMate watchdog] HM_SERVER_ENTRY and HM_SERVER_LOG are required");
242
252
  process.exit(1);
@@ -265,9 +275,9 @@ async function runWatchdog() {
265
275
  intervalMs: Number(process.env.HM_WATCHDOG_PROBE_INTERVAL_MS || 3e4),
266
276
  threshold: Number(process.env.HM_WATCHDOG_PROBE_THRESHOLD || 3),
267
277
  onFailure: (lastError) => {
268
- if (stopping || !child || child.killed) return;
278
+ if (stopping || !child || child.killed || child.exitCode !== null) return;
269
279
  console.error(`[HunterMate watchdog] server unresponsive (last error: ${lastError}), killing for restart`);
270
- crashReason = `liveness probe failed: ${lastError}`;
280
+ crashReason = `liveness probe failed: ${lastError} (child pid=${child.pid})`;
271
281
  try {
272
282
  child.kill("SIGKILL");
273
283
  } catch {
@@ -290,6 +300,7 @@ async function runWatchdog() {
290
300
  windowsHide: true
291
301
  });
292
302
  if (child.pid) writePid(SERVER_PID_FILE(), child.pid);
303
+ probe.markBootStart(bootGraceMs);
293
304
  probe.start();
294
305
  child.on("exit", (code, signal) => {
295
306
  try {
@@ -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/10ba1fa1d6ce23a7.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-54e74ccc9e9451ee.js"/><script src="/_next/static/chunks/a7067448-e416655baf443992.js" async=""></script><script src="/_next/static/chunks/935-7be3e60dd8bc29d2.js" async=""></script><script src="/_next/static/chunks/main-app-f496bd51a73ef9f3.js" async=""></script><script src="/_next/static/chunks/589-f984bff035a1cb85.js" async=""></script><script src="/_next/static/chunks/105-dcd8f6d5867c8995.js" async=""></script><script src="/_next/static/chunks/app/layout-af39afc7866e74db.js" async=""></script><meta name="robots" content="noindex"/><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"><div class="flex h-screen w-screen flex-col items-center justify-center bg-gray-50"><span class="hm-spinner" aria-label="加载中"></span><div class="mt-4 text-sm text-gray-400">正在加载,请稍候…</div></div><script src="/_next/static/chunks/webpack-54e74ccc9e9451ee.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/10ba1fa1d6ce23a7.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[76939,[],\"\"]\n4:I[74268,[],\"\"]\n5:I[81050,[],\"\"]\n6:I[15214,[\"589\",\"static/chunks/589-f984bff035a1cb85.js\",\"105\",\"static/chunks/105-dcd8f6d5867c8995.js\",\"185\",\"static/chunks/app/layout-af39afc7866e74db.js\"],\"AuthGate\"]\n7:I[67188,[\"589\",\"static/chunks/589-f984bff035a1cb85.js\",\"105\",\"static/chunks/105-dcd8f6d5867c8995.js\",\"185\",\"static/chunks/app/layout-af39afc7866e74db.js\"],\"AntdProvider\"]\n8:I[9424,[\"589\",\"static/chunks/589-f984bff035a1cb85.js\",\"105\",\"static/chunks/105-dcd8f6d5867c8995.js\",\"185\",\"static/chunks/app/layout-af39afc7866e74db.js\"],\"SystemSidebar\"]\ne:I[62319,[],\"\"]\n9:{\"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\"}\na:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\nb:{\"display\":\"inline-block\"}\nc:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nf:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"hBLezfvVOMiGqm4V9F15i\",\"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/10ba1fa1d6ce23a7.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,{\"children\":[\"$\",\"$L7\",null,{\"children\":[[\"$\",\"$L8\",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\":\"$9\",\"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\":\"$a\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$b\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$c\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Ld\"],\"globalErrorComponent\":\"$e\",\"missingSlots\":\"$Wf\"}]\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"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>
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/a8f0a381a2372781.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-54e74ccc9e9451ee.js"/><script src="/_next/static/chunks/a7067448-3f2b194cfadb91fb.js" async=""></script><script src="/_next/static/chunks/935-efb30b9f6f558e3f.js" async=""></script><script src="/_next/static/chunks/main-app-f496bd51a73ef9f3.js" async=""></script><script src="/_next/static/chunks/589-cc56950ae4117cdd.js" async=""></script><script src="/_next/static/chunks/187-f067914dcd1330c2.js" async=""></script><script src="/_next/static/chunks/app/layout-bd9a7e5e4474b692.js" async=""></script><meta name="robots" content="noindex"/><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"><div class="flex h-screen w-screen flex-col items-center justify-center bg-gray-50"><span class="hm-spinner" aria-label="加载中"></span><div class="mt-4 text-sm text-gray-400">正在加载,请稍候…</div></div><script src="/_next/static/chunks/webpack-54e74ccc9e9451ee.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/a8f0a381a2372781.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[76939,[],\"\"]\n4:I[74268,[],\"\"]\n5:I[81050,[],\"\"]\n6:I[15214,[\"589\",\"static/chunks/589-cc56950ae4117cdd.js\",\"187\",\"static/chunks/187-f067914dcd1330c2.js\",\"185\",\"static/chunks/app/layout-bd9a7e5e4474b692.js\"],\"AuthGate\"]\n7:I[67188,[\"589\",\"static/chunks/589-cc56950ae4117cdd.js\",\"187\",\"static/chunks/187-f067914dcd1330c2.js\",\"185\",\"static/chunks/app/layout-bd9a7e5e4474b692.js\"],\"AntdProvider\"]\n8:I[9424,[\"589\",\"static/chunks/589-cc56950ae4117cdd.js\",\"187\",\"static/chunks/187-f067914dcd1330c2.js\",\"185\",\"static/chunks/app/layout-bd9a7e5e4474b692.js\"],\"SystemSidebar\"]\ne:I[62319,[],\"\"]\n9:{\"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\"}\na:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\nb:{\"display\":\"inline-block\"}\nc:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nf:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"m0UGHVTGvtvb9mn4-uzJJ\",\"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/a8f0a381a2372781.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,{\"children\":[\"$\",\"$L7\",null,{\"children\":[[\"$\",\"$L8\",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\":\"$9\",\"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\":\"$a\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$b\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$c\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Ld\"],\"globalErrorComponent\":\"$e\",\"missingSlots\":\"$Wf\"}]\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"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>