openings 0.1.4 → 0.1.5

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openings",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Find evidence-grounded jobs, including relevant roles you may not have searched for, without accounts or API keys.",
5
5
  "author": { "name": "Openings contributors" },
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openings",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "A free, candidate-safe job-search substrate for AI agents",
5
5
  "license": "MIT",
6
6
  "repository": { "type": "git", "url": "git+https://github.com/abhay-avagama/hiring-agent.git" },
@@ -43,9 +43,11 @@ export function createCrawlReporter(options: { url: string; fetcher?: Fetch; tim
43
43
  }
44
44
 
45
45
  /** Downloads the aggregator's published snapshot; returns null on any failure so setup falls back to crawling. */
46
- export async function fetchSeedSnapshot(url: string, fetcher: Fetch = globalThis.fetch, timeoutMs = 20_000): Promise<JobSnapshot | null> {
46
+ export async function fetchSeedSnapshot(url: string, fetcher: Fetch = globalThis.fetch, timeoutMs = 20_000, countries: string[] = []): Promise<JobSnapshot | null> {
47
47
  try {
48
- const response = await fetcher(endpoint(url, "v1/snapshot"), { signal: AbortSignal.timeout(timeoutMs) });
48
+ const codes = countries.map((code) => code.toUpperCase()).filter((code) => /^[A-Z]{2}$/.test(code));
49
+ const target = endpoint(url, "v1/snapshot") + (codes.length ? `?countries=${codes.join(",")}` : "");
50
+ const response = await fetcher(target, { signal: AbortSignal.timeout(timeoutMs) });
49
51
  if (!response.ok) return null;
50
52
  const snapshot = await response.json() as JobSnapshot;
51
53
  if (snapshot?.version !== 1 || !snapshot.partitions || typeof snapshot.partitions !== "object" || !snapshot.lastCrawl) return null;
@@ -18,7 +18,7 @@ export function createJobSearchPreparer(options: {
18
18
  store: SnapshotStore;
19
19
  crawl(scope: CrawlScope): Promise<CrawlReport>;
20
20
  /** Optional published snapshot used instead of crawling when no local snapshot exists yet. */
21
- seed?(): Promise<JobSnapshot | null>;
21
+ seed?(countries: string[]): Promise<JobSnapshot | null>;
22
22
  now?: () => Date;
23
23
  freshnessDays?: number;
24
24
  batchSize?: number;
@@ -32,7 +32,7 @@ export function createJobSearchPreparer(options: {
32
32
  const { countries } = input;
33
33
  let snapshot = await options.store.read();
34
34
  if (!snapshot && options.seed) {
35
- const seeded = await options.seed().catch(() => null);
35
+ const seeded = await options.seed(countries).catch(() => null);
36
36
  if (seeded) { await options.store.write(seeded); snapshot = seeded; }
37
37
  }
38
38
  const pendingBefore = pendingSources(options.sources, snapshot, now(), freshnessMs);
package/src/mcp.ts CHANGED
@@ -22,7 +22,7 @@ export function createMcpHandler(tools: ToolHandler) {
22
22
  const base = { jsonrpc: "2.0" as const, id: request.id ?? null };
23
23
  try {
24
24
  if (request.method === "initialize") {
25
- return { ...base, result: { protocolVersion: "2025-06-18", capabilities: { tools: {} }, serverInfo: { name: "openings", version: "0.1.4" } } };
25
+ return { ...base, result: { protocolVersion: "2025-06-18", capabilities: { tools: {} }, serverInfo: { name: "openings", version: "0.1.5" } } };
26
26
  }
27
27
  if (request.method === "ping") return { ...base, result: {} };
28
28
  if (request.method === "tools/list") return { ...base, result: { tools: tools.list() } };
package/src/runtime.ts CHANGED
@@ -40,7 +40,7 @@ export function createRuntime(options: { dataDir?: string; concurrency?: number;
40
40
  workdayPageDelayMs: options.workdayPageDelayMs,
41
41
  onCrawled,
42
42
  });
43
- const preparation = createJobSearchPreparer({ sources: companies, store, crawl: preparationLocal.crawl, seed: aggregatorUrl ? () => fetchSeedSnapshot(aggregatorUrl) : undefined });
43
+ const preparation = createJobSearchPreparer({ sources: companies, store, crawl: preparationLocal.crawl, seed: aggregatorUrl ? (countries) => fetchSeedSnapshot(aggregatorUrl, globalThis.fetch, 20_000, countries) : undefined });
44
44
  const getSelectedJob = createSelectedJobLookup({
45
45
  getSnapshotJob: async (id) => (await local.get(id, { offline: true, staleDays: 14 })).job,
46
46
  getDetailedJob: (id) => liveCatalog.get(id),