job-pro 1.0.13 → 1.0.14

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 (2) hide show
  1. package/dist/index.js +34 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -127,7 +127,8 @@ USAGE
127
127
  job-pro profile show print the loaded profile
128
128
  job-pro find <keyword> search ALL 50 companies in parallel
129
129
  [--limit N] [--companies a,b,c]
130
- [--timeout ms] [--compact | --text]
130
+ [--timeout ms] [--apply-ready]
131
+ [--compact | --text]
131
132
  job-pro --version
132
133
  job-pro help
133
134
 
@@ -1088,10 +1089,22 @@ async function main() {
1088
1089
  if (cmd === "find") {
1089
1090
  const compact = args.includes("--compact");
1090
1091
  const textMode = args.includes("--text");
1092
+ const applyReadyOnly = args.includes("--apply-ready");
1091
1093
  const keyword = args[1];
1092
1094
  if (!keyword || keyword.startsWith("--")) {
1093
- die(`usage: job-pro find <keyword> [--limit N] [--companies a,b,c] [--timeout ms] [--compact | --text]`);
1095
+ die(`usage: job-pro find <keyword> [--limit N] [--companies a,b,c] [--timeout ms] [--apply-ready] [--compact | --text]`);
1094
1096
  }
1097
+ // Static apply-readiness map. Source of truth for what kind of submission
1098
+ // each adapter supports — kept in sync with apply-smoke's submit_kind tally.
1099
+ const ANON_ADAPTERS = new Set(["xpeng", "weride", "hoyoverse"]);
1100
+ const EXTERNAL_ADAPTERS = new Set(["hikvision", "cicc", "cainiao", "webank", "unitree"]);
1101
+ const applyStatusFor = (adapterKey) => {
1102
+ if (EXTERNAL_ADAPTERS.has(adapterKey))
1103
+ return "external";
1104
+ if (ANON_ADAPTERS.has(adapterKey))
1105
+ return "anon";
1106
+ return loadSession(adapterKey) ? "session" : "missing-session";
1107
+ };
1095
1108
  const { args: aLimit, value: limitStr } = popFlagValue(args, "--limit");
1096
1109
  const { args: aCompanies, value: companiesStr } = popFlagValue(aLimit, "--companies");
1097
1110
  const { args: aTimeout, value: timeoutStr } = popFlagValue(aCompanies, "--timeout");
@@ -1126,7 +1139,7 @@ async function main() {
1126
1139
  return { company, ok: false, count: 0, positions: [], message: r.message ?? "search failed", elapsed_ms: elapsed };
1127
1140
  }
1128
1141
  const positions = Array.isArray(r?.positions) ? r.positions.slice(0, limit) : [];
1129
- return { company, ok: true, count: positions.length, positions, elapsed_ms: elapsed };
1142
+ return { company, ok: true, count: positions.length, positions, apply_status: applyStatusFor(company), elapsed_ms: elapsed };
1130
1143
  }
1131
1144
  catch (err) {
1132
1145
  const elapsed = Date.now() - t0;
@@ -1139,13 +1152,24 @@ async function main() {
1139
1152
  }
1140
1153
  }));
1141
1154
  const totalMs = Date.now() - startedAt;
1142
- const withHits = settled.filter((r) => r.count > 0);
1155
+ const allHits = settled.filter((r) => r.count > 0);
1156
+ const withHits = applyReadyOnly
1157
+ ? allHits.filter((r) => r.apply_status === "anon" || r.apply_status === "session")
1158
+ : allHits;
1143
1159
  const total = withHits.reduce((s, r) => s + r.count, 0);
1144
1160
  const failed = settled.filter((r) => !r.ok).map((r) => ({ company: r.company, message: r.message }));
1145
1161
  if (textMode) {
1146
- console.log(`\nfind "${keyword}" ${total} hit(s) across ${withHits.length}/${scope.length} companies (${totalMs}ms)\n`);
1162
+ const STATUS_ICON = {
1163
+ anon: "✅",
1164
+ session: "🟢",
1165
+ "missing-session": "🟡",
1166
+ external: "⛔",
1167
+ };
1168
+ const filterNote = applyReadyOnly ? " [apply-ready only]" : "";
1169
+ console.log(`\nfind "${keyword}" — ${total} hit(s) across ${withHits.length}/${scope.length} companies (${totalMs}ms)${filterNote}\n`);
1147
1170
  for (const r of withHits) {
1148
- console.log(`▌ ${r.company} (${r.count})`);
1171
+ const icon = STATUS_ICON[r.apply_status ?? ""] ?? "?";
1172
+ console.log(`${icon} ${r.company} (${r.count}) — ${r.apply_status}`);
1149
1173
  for (const p of r.positions) {
1150
1174
  const title = (p.title ?? "").trim().replace(/\s+/g, " ");
1151
1175
  const loc = (p.work_cities ?? "").trim();
@@ -1155,6 +1179,10 @@ async function main() {
1155
1179
  }
1156
1180
  console.log("");
1157
1181
  }
1182
+ const hiddenCount = allHits.length - withHits.length;
1183
+ if (applyReadyOnly && hiddenCount > 0) {
1184
+ console.log(`(${hiddenCount} company-bucket(s) hidden — missing-session / external)\n`);
1185
+ }
1158
1186
  if (failed.length > 0) {
1159
1187
  console.log(`Failed (${failed.length}):`);
1160
1188
  for (const f of failed)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job-pro",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "Query Chinese big-tech campus recruiting from your terminal. 50 companies, all 50 live. 46 via each company's own API; the 4 with no public canonical feed (Hikvision, CICC, Cainiao, WeBank) surfaced via Liepin as a clearly-labeled third-party fallback. No signup, no token, no server.",
5
5
  "homepage": "https://job.ha7ch.com",
6
6
  "repository": "https://github.com/HA7CH/job-pro",