@hadoku/resume-bot 0.0.0-stage → 3.14.16

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 (70) hide show
  1. package/README.md +135 -3
  2. package/dist/App.d.ts +9 -0
  3. package/dist/App.d.ts.map +1 -0
  4. package/dist/ChatInterface-mHtxUGpp.js +128 -0
  5. package/dist/ChatInterface-mHtxUGpp.js.map +1 -0
  6. package/dist/ResumeViewer-C-uxZ-7E.js +296 -0
  7. package/dist/ResumeViewer-C-uxZ-7E.js.map +1 -0
  8. package/dist/builder/BlockCard.d.ts +15 -0
  9. package/dist/builder/BlockCard.d.ts.map +1 -0
  10. package/dist/builder/BuilderApp.d.ts +3 -0
  11. package/dist/builder/BuilderApp.d.ts.map +1 -0
  12. package/dist/builder/api.d.ts +37 -0
  13. package/dist/builder/api.d.ts.map +1 -0
  14. package/dist/builder/entry.d.ts +8 -0
  15. package/dist/builder/entry.d.ts.map +1 -0
  16. package/dist/builder/useBuilderAuth.d.ts +10 -0
  17. package/dist/builder/useBuilderAuth.d.ts.map +1 -0
  18. package/dist/builder.js +537 -0
  19. package/dist/builder.js.map +1 -0
  20. package/dist/components/ChatInterface.d.ts +10 -0
  21. package/dist/components/ChatInterface.d.ts.map +1 -0
  22. package/dist/components/ResumeDocument.d.ts +30 -0
  23. package/dist/components/ResumeDocument.d.ts.map +1 -0
  24. package/dist/components/ResumeViewer.d.ts +12 -0
  25. package/dist/components/ResumeViewer.d.ts.map +1 -0
  26. package/dist/entry-BTJjyohQ.js +154 -0
  27. package/dist/entry-BTJjyohQ.js.map +1 -0
  28. package/dist/entry.d.ts +22 -0
  29. package/dist/entry.d.ts.map +1 -0
  30. package/dist/index.js +9 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/markdown-vendor-61sRGACd.js +10510 -0
  33. package/dist/markdown-vendor-61sRGACd.js.map +1 -0
  34. package/dist/rehype-vendor-C_Q-vwLE.js +5647 -0
  35. package/dist/rehype-vendor-C_Q-vwLE.js.map +1 -0
  36. package/dist/services/api.d.ts +62 -0
  37. package/dist/services/api.d.ts.map +1 -0
  38. package/dist/style.css +1 -0
  39. package/dist/worker/application-extras.d.ts +56 -0
  40. package/dist/worker/application-extras.d.ts.map +1 -0
  41. package/dist/worker/blocks.d.ts +12 -0
  42. package/dist/worker/blocks.d.ts.map +1 -0
  43. package/dist/worker/builder.d.ts +33 -0
  44. package/dist/worker/builder.d.ts.map +1 -0
  45. package/dist/worker/constants.d.ts +39 -0
  46. package/dist/worker/constants.d.ts.map +1 -0
  47. package/dist/worker/contact.d.ts +34 -0
  48. package/dist/worker/contact.d.ts.map +1 -0
  49. package/dist/worker/cover-letter.d.ts +16 -0
  50. package/dist/worker/cover-letter.d.ts.map +1 -0
  51. package/dist/worker/index.d.ts +38 -0
  52. package/dist/worker/index.d.ts.map +1 -0
  53. package/dist/worker/llm.d.ts +77 -0
  54. package/dist/worker/llm.d.ts.map +1 -0
  55. package/dist/worker/pdf.d.ts +46 -0
  56. package/dist/worker/pdf.d.ts.map +1 -0
  57. package/dist/worker/rate-limit.d.ts +10 -0
  58. package/dist/worker/rate-limit.d.ts.map +1 -0
  59. package/dist/worker/resume.d.ts +33 -0
  60. package/dist/worker/resume.d.ts.map +1 -0
  61. package/dist/worker/skeleton.d.ts +73 -0
  62. package/dist/worker/skeleton.d.ts.map +1 -0
  63. package/dist/worker/tailored-resume.d.ts +31 -0
  64. package/dist/worker/tailored-resume.d.ts.map +1 -0
  65. package/dist/worker/typography.d.ts +12 -0
  66. package/dist/worker/typography.d.ts.map +1 -0
  67. package/dist/worker/variants.d.ts +51 -0
  68. package/dist/worker/variants.d.ts.map +1 -0
  69. package/dist/worker.js +42508 -0
  70. package/package.json +43 -4
@@ -0,0 +1,33 @@
1
+ import type { KVNamespace } from '@cloudflare/workers-types';
2
+ export interface ResumeEnv {
3
+ CONTENT_KV: KVNamespace;
4
+ /**
5
+ * Legacy fallback only. The prompt is content, not a credential — it is
6
+ * already served verbatim to friend tier at `/system-prompt` — so it lives in
7
+ * CONTENT_KV under `resume:prompt` alongside every other resume key. Optional
8
+ * because the goal is for this binding to stop existing.
9
+ */
10
+ RESUME_SYSTEM_PROMPT?: string;
11
+ }
12
+ /**
13
+ * The canonical résumé is assembled on the fly from the blocks tagged
14
+ * `canonical`, following the fixed page skeleton — one source of truth, so the
15
+ * display, the PDF and the chatbot never drift from a stale pre-baked blob.
16
+ * Falls back to the legacy pre-rendered keys only if no block carries the tag.
17
+ */
18
+ export declare function getResumeContent(env: ResumeEnv): Promise<string>;
19
+ /**
20
+ * KV first, worker secret second.
21
+ *
22
+ * Every other piece of resume content already comes from CONTENT_KV — eleven
23
+ * keys, `resume:full` and `resume:blocks:*` among them, read twelve lines above
24
+ * this. The prompt was the one exception, and being the exception is what kept
25
+ * a `resumeData.env` alive in hadoku_site as its only editable source, pushed
26
+ * with a raw `wrangler secret put` that repo's rules forbid.
27
+ *
28
+ * The secret is kept as a fallback so the two repos can migrate in either
29
+ * order: publishing this ahead of the KV write changes nothing.
30
+ */
31
+ export declare function getSystemPrompt(env: ResumeEnv): Promise<string>;
32
+ export declare function getFullSystemPrompt(env: ResumeEnv, ownerName: string): Promise<string>;
33
+ //# sourceMappingURL=resume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../worker/src/resume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAI5D,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,WAAW,CAAA;IACvB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAOrE;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe5F"}
@@ -0,0 +1,73 @@
1
+ import type { ResumeBlock } from './blocks.js';
2
+ /**
3
+ * The résumé is a fixed skeleton of sections in a fixed order, grouped into
4
+ * pages. Tailoring selects WHICH blocks land in each section; it never reorders
5
+ * the skeleton itself. A block's section comes from its `section:<id>` tag
6
+ * (consistent with the story:/layer:/tech: tag conventions); when that tag is
7
+ * absent we fall back to a section derived from the block type, so the assembler
8
+ * still produces correct structure for blocks authored before the tag existed.
9
+ */
10
+ export type SectionId = 'header' | 'summary' | 'experience-primary' | 'projects' | 'skills' | 'experience-secondary' | 'education';
11
+ /** Sections in render order, top of page 1 to bottom of the last page. */
12
+ export declare const SECTION_ORDER: readonly SectionId[];
13
+ /**
14
+ * A hard page break is emitted immediately before each of these sections (when
15
+ * something has already been rendered above). This is what makes the three-page
16
+ * layout deterministic: projects always open page 2, skills always open page 3.
17
+ */
18
+ export declare const PAGE_BREAK_BEFORE: ReadonlySet<SectionId>;
19
+ /**
20
+ * Sentinel line inserted between page groups. Both renderers recognise it: the
21
+ * PDF typesetter turns it into a forced new page, and the on-screen viewer
22
+ * splits on it and drops in a page-break element. Kept as an HTML comment so it
23
+ * stays invisible if any markdown path ever renders it literally.
24
+ */
25
+ export declare const PAGE_BREAK_MARKER = "<!-- page-break -->";
26
+ /**
27
+ * Blocks tagged `canonical` form the default résumé — the curated subset shown
28
+ * at /resume and in the plain PDF. The full block set stays a palette the
29
+ * tailoring pipeline selects from per job; only canonical blocks appear by
30
+ * default, which is what keeps the default résumé to its intended page count.
31
+ */
32
+ export declare const CANONICAL_TAG = "canonical";
33
+ /**
34
+ * Blocks tagged `always` are structural — the header, and heading-carrying
35
+ * blocks like the skills-section opener — and must appear in every tailored
36
+ * variant no matter what the selector returns. Selection treats this as a
37
+ * hard guarantee, not a prompt-level suggestion.
38
+ */
39
+ export declare const ALWAYS_TAG = "always";
40
+ export declare function filterCanonical(blocks: ResumeBlock[]): ResumeBlock[];
41
+ /** Remove page-break marker lines — for contexts where pages are meaningless
42
+ * (e.g. the résumé text embedded in the chatbot system prompt). */
43
+ export declare function stripPageBreaks(markdown: string): string;
44
+ /**
45
+ * Assemble blocks into résumé markdown following the fixed skeleton: bucket by
46
+ * section, drop empty sections, order within a section by priority (descending,
47
+ * stable for ties), and insert PAGE_BREAK_MARKER before each page-opening
48
+ * section.
49
+ *
50
+ * `blocks` may be the full palette (the canonical résumé) or a tailored subset
51
+ * (a per-job variant) — either way the output has the same page structure. The
52
+ * caller's ordering is intentionally ignored; the skeleton decides order.
53
+ */
54
+ export declare function assembleResume(blocks: ResumeBlock[]): string;
55
+ /**
56
+ * The projects anchor — the uncategorized always+canonical paragraph that opens
57
+ * page 2 — carries verified platform figures (docs/resume-structure.md). Its
58
+ * text is load-bearing in a way bullets are not, so it is exempt from LLM
59
+ * rewriting: renderers splice the canonical text back in verbatim.
60
+ */
61
+ export declare function projectsAnchorText(blocks: ResumeBlock[]): string;
62
+ /**
63
+ * Replace the paragraph(s) between the '# Projects' heading and the first
64
+ * category/section heading (or page-break marker) with `anchor`, verbatim.
65
+ * If the heading is immediately followed by structure (the rewrite dropped the
66
+ * anchor entirely), the anchor is inserted rather than replacing anything.
67
+ * No '# Projects' heading → returned unchanged.
68
+ */
69
+ export declare function restoreProjectsAnchor(markdown: string, anchor: string): string;
70
+ /** Count of page-break markers in an assembled document — used to detect that a
71
+ * tailoring rewrite preserved the skeleton's page structure. */
72
+ export declare function countPageBreaks(markdown: string): number;
73
+ //# sourceMappingURL=skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../worker/src/skeleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,SAAS,GACT,oBAAoB,GACpB,UAAU,GACV,QAAQ,GACR,sBAAsB,GACtB,WAAW,CAAA;AAEf,0EAA0E;AAC1E,eAAO,MAAM,aAAa,EAAE,SAAS,SAAS,EAQ7C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,SAAS,CAAmC,CAAA;AAExF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,wBAAwB,CAAA;AAkDtD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,cAAc,CAAA;AAExC;;;;;GAKG;AACH,eAAO,MAAM,UAAU,WAAW,CAAA;AAElC,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAEpE;AAED;oEACoE;AACpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOxD;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CA8C5D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAQhE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAiB9E;AAED;iEACiE;AACjE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMxD"}
@@ -0,0 +1,31 @@
1
+ import type { KVNamespace } from '@cloudflare/workers-types';
2
+ import { type LLMChain } from './llm.js';
3
+ /**
4
+ * LLMs sometimes wrap their entire response in a ```` ```markdown … ``` ```` code
5
+ * fence, which makes ReactMarkdown render the whole document as a `<pre><code>`
6
+ * block instead of formatted markdown. Unwrap only when the ENTIRE output is a
7
+ * single fenced block (leading fence + matching trailing fence) so we never
8
+ * clobber a legitimate embedded code block.
9
+ */
10
+ export declare function stripCodeFence(text: string): string;
11
+ export interface TailoredResumeRequest {
12
+ job_title: string;
13
+ company: string;
14
+ description: string;
15
+ profile_type?: string;
16
+ tailor?: boolean;
17
+ }
18
+ export interface TailoredResumeResponse {
19
+ resume_markdown: string;
20
+ blocks_used: string[];
21
+ cached: boolean;
22
+ }
23
+ export declare function generateTailoredResume(client: LLMChain, kv: KVNamespace, req: TailoredResumeRequest,
24
+ /**
25
+ * Epoch ms this whole generation must finish by. Defaults to a fresh budget,
26
+ * which is right for a standalone /tailored-resume call. The variants mint
27
+ * passes ITS deadline instead, because there the résumé shares one edge
28
+ * timeout with a cover letter generated afterwards.
29
+ */
30
+ deadline?: number): Promise<TailoredResumeResponse>;
31
+ //# sourceMappingURL=tailored-resume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailored-resume.d.ts","sourceRoot":"","sources":["../../worker/src/tailored-resume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAU5D,OAAO,EAAsB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AA2B5D;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,QAAQ,EAChB,EAAE,EAAE,WAAW,EACf,GAAG,EAAE,qBAAqB;AAC1B;;;;;GAKG;AACH,QAAQ,GAAE,MAAyC,GAClD,OAAO,CAAC,sBAAsB,CAAC,CA8RjC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * LLM-generated markdown leans on typographic Unicode: narrow no-break
3
+ * spaces (U+202F) around symbols, zero-widths, non-breaking hyphens. They
4
+ * read oddly in the web viewer and cannot be represented in the PDF's
5
+ * WinAnsi fonts. Normalize at the READ boundary (the /resume and /resume.pdf
6
+ * routes) so already-minted variants come out clean without re-minting them
7
+ * (their slugs are in links recruiters already hold), and at generation so
8
+ * fresh output is stored clean. En dashes (date ranges) and bullets are left
9
+ * alone; em dashes are banned outright (owner rule, 2026-08-21).
10
+ */
11
+ export declare function normalizeTypography(text: string): string;
12
+ //# sourceMappingURL=typography.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../worker/src/typography.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwBxD"}
@@ -0,0 +1,51 @@
1
+ import type { KVNamespace } from '@cloudflare/workers-types';
2
+ import type { LLMChain } from './llm.js';
3
+ export interface ResumeVariant {
4
+ slug: string;
5
+ label: string;
6
+ /** Pre-rendered markdown; takes precedence over block_ids when present */
7
+ markdown?: string;
8
+ /** Assembled from blocks at read time, in this order */
9
+ block_ids?: string[];
10
+ /** Tailored cover letter delivered alongside the résumé (the packet). */
11
+ cover_letter_markdown?: string;
12
+ /** Posting context, so the delivered page can label the packet. */
13
+ company?: string;
14
+ job_title?: string;
15
+ created_at: string;
16
+ }
17
+ export interface MintVariantRequest {
18
+ label: string;
19
+ slug?: string;
20
+ markdown?: string;
21
+ block_ids?: string[];
22
+ /** Alternative to markdown/block_ids: run the tailoring pipeline at mint time */
23
+ job_title?: string;
24
+ company?: string;
25
+ description?: string;
26
+ profile_type?: string;
27
+ tailor?: boolean;
28
+ /** Pre-rendered cover letter to deliver with the résumé (skips generation). */
29
+ cover_letter_markdown?: string;
30
+ /**
31
+ * When minting via the tailoring path (job_title+company+description), also
32
+ * generate a matching cover letter. Defaults to true; set false to skip the
33
+ * extra LLM call. Ignored when cover_letter_markdown is supplied.
34
+ */
35
+ cover_letter?: boolean;
36
+ /** Auto-expire the link after this many days */
37
+ ttl_days?: number;
38
+ }
39
+ export declare function getVariant(kv: KVNamespace, slug: string): Promise<ResumeVariant | null>;
40
+ /** Resolve a variant to resume markdown. Returns null when it holds no renderable content. */
41
+ export declare function renderVariant(kv: KVNamespace, variant: ResumeVariant): Promise<string | null>;
42
+ export declare function mintVariant(client: LLMChain, kv: KVNamespace, req: MintVariantRequest): Promise<ResumeVariant>;
43
+ export interface VariantSummary {
44
+ slug: string;
45
+ label: string;
46
+ created_at: string;
47
+ source: 'markdown' | 'blocks';
48
+ }
49
+ export declare function listVariants(kv: KVNamespace): Promise<VariantSummary[]>;
50
+ export declare function deleteVariant(kv: KVNamespace, slug: string): Promise<boolean>;
51
+ //# sourceMappingURL=variants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variants.d.ts","sourceRoot":"","sources":["../../worker/src/variants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AASxC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,+EAA+E;IAC/E,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAUD,wBAAsB,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAG7F;AAED,8FAA8F;AAC9F,wBAAsB,aAAa,CACjC,EAAE,EAAE,WAAW,EACf,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,QAAQ,EAChB,EAAE,EAAE,WAAW,EACf,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,aAAa,CAAC,CA2FxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAA;CAC9B;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAoB7E;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnF"}