knowme-careerforge-skill 0.0.2 → 0.0.6

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 (127) hide show
  1. package/AGENT.md +276 -0
  2. package/ARCHITECTURE.md +216 -0
  3. package/README.md +34 -54
  4. package/README.zh-CN.md +35 -57
  5. package/SKILL.md +28 -137
  6. package/agents/claude/knowme-careerforge.md +2 -16
  7. package/agents/codex/knowme-careerforge.yaml +5 -7
  8. package/agents/cursor/knowme-careerforge.mdc +4 -9
  9. package/agents/opencode/skill.yaml +1 -1
  10. package/agents/windsurf/knowme-careerforge.rules +2 -12
  11. package/dist/cli/src/commands/init.js +9 -0
  12. package/dist/cli/src/index.js +40 -19
  13. package/dist/scripts/rendering/engine-loader.d.ts +2 -0
  14. package/dist/scripts/rendering/engine-loader.js +46 -0
  15. package/dist/scripts/rendering/render-pdf.d.ts +3 -8
  16. package/dist/scripts/rendering/render-pdf.js +7 -103
  17. package/dist/scripts/rendering/runtime.d.ts +9 -0
  18. package/dist/scripts/rendering/runtime.js +63 -0
  19. package/dist/scripts/validation/validate-ats.d.ts +2 -22
  20. package/dist/scripts/validation/validate-ats.js +6 -168
  21. package/dist/scripts/validation/validate-layout.d.ts +2 -23
  22. package/dist/scripts/validation/validate-layout.js +5 -159
  23. package/package.json +16 -4
  24. package/references/01-evidence-mining.md +5 -0
  25. package/references/02-career-goal.md +38 -0
  26. package/references/03-jd-analysis.md +44 -0
  27. package/references/04-template-selection.md +43 -0
  28. package/references/05-html-canvas-tokens.md +12 -0
  29. package/references/06-qa-and-rendering.md +14 -0
  30. package/references/07-artifact-contract.md +64 -0
  31. package/scripts/Agent.md +9 -136
  32. package/scripts/build/build-gallery.py +66 -56
  33. package/scripts/build/run-all-tests.py +1 -0
  34. package/scripts/build/sync-version.py +37 -10
  35. package/scripts/contracts/profile.py +101 -0
  36. package/scripts/evidence/extract-evidence.py +109 -62
  37. package/scripts/pipeline/forge.py +266 -136
  38. package/scripts/rendering/README.md +65 -0
  39. package/scripts/rendering/browser-engine.d.ts +15 -0
  40. package/scripts/rendering/browser-engine.js +366 -0
  41. package/scripts/rendering/browser_engine.py +39 -0
  42. package/scripts/rendering/engine-loader.ts +11 -0
  43. package/scripts/rendering/render-pdf.py +26 -151
  44. package/scripts/rendering/render-pdf.ts +7 -83
  45. package/scripts/template/instantiate-resume.py +266 -167
  46. package/scripts/template/search-template.py +367 -89
  47. package/scripts/validation/measure-dom.js +5 -0
  48. package/scripts/validation/validate-ats.ts +6 -174
  49. package/scripts/validation/validate-layout.ts +5 -159
  50. package/scripts/validation/validate-resume.py +23 -134
  51. package/skill.json +1 -1
  52. package/src/knowledge/index.json +390 -10
  53. package/src/knowledge/resume-schema.json +377 -71
  54. package/src/knowledge/templates.json +388 -8
  55. package/src/references/01-evidence-mining.md +5 -0
  56. package/src/references/02-career-goal.md +38 -0
  57. package/src/references/03-jd-analysis.md +44 -0
  58. package/src/references/04-template-selection.md +43 -0
  59. package/src/references/05-html-canvas-tokens.md +12 -0
  60. package/src/references/06-qa-and-rendering.md +14 -0
  61. package/src/references/07-artifact-contract.md +64 -0
  62. package/src/templates/Agent.md +11 -0
  63. package/src/templates/academic-research/README.md +25 -0
  64. package/src/templates/academic-research/canvas.html +21 -0
  65. package/src/templates/academic-research/metadata.json +38 -0
  66. package/src/templates/academic-research/sample-profile.json +86 -0
  67. package/src/templates/academic-research/style.css +213 -0
  68. package/src/templates/classic/README.md +9 -0
  69. package/src/templates/classic/canvas.html +21 -0
  70. package/src/templates/classic/metadata.json +3 -0
  71. package/src/templates/classic/sample-profile.json +86 -0
  72. package/src/templates/classic/style.css +35 -54
  73. package/src/templates/common/base.css +182 -0
  74. package/src/templates/common/canvas-bindings.css +41 -0
  75. package/src/templates/common/resume-contract.md +8 -0
  76. package/src/templates/compact-dense/README.md +25 -0
  77. package/src/templates/compact-dense/canvas.html +14 -0
  78. package/src/templates/compact-dense/metadata.json +38 -0
  79. package/src/templates/compact-dense/sample-profile.json +86 -0
  80. package/src/templates/compact-dense/style.css +218 -0
  81. package/src/templates/creative-tech/README.md +26 -0
  82. package/src/templates/creative-tech/canvas.html +15 -0
  83. package/src/templates/creative-tech/metadata.json +39 -0
  84. package/src/templates/creative-tech/sample-profile.json +86 -0
  85. package/src/templates/creative-tech/style.css +257 -0
  86. package/src/templates/data-analyst/README.md +26 -0
  87. package/src/templates/data-analyst/canvas.html +15 -0
  88. package/src/templates/data-analyst/metadata.json +39 -0
  89. package/src/templates/data-analyst/sample-profile.json +86 -0
  90. package/src/templates/data-analyst/style.css +285 -0
  91. package/src/templates/executive/README.md +9 -0
  92. package/src/templates/executive/canvas.html +15 -0
  93. package/src/templates/executive/sample-profile.json +86 -0
  94. package/src/templates/executive/style.css +83 -74
  95. package/src/templates/international-flow/README.md +26 -0
  96. package/src/templates/international-flow/canvas.html +21 -0
  97. package/src/templates/international-flow/metadata.json +37 -0
  98. package/src/templates/international-flow/sample-profile.json +86 -0
  99. package/src/templates/international-flow/style.css +208 -0
  100. package/src/templates/minimal/README.md +9 -0
  101. package/src/templates/minimal/canvas.html +21 -0
  102. package/src/templates/minimal/sample-profile.json +86 -0
  103. package/src/templates/minimal/style.css +54 -72
  104. package/src/templates/modern/README.md +9 -0
  105. package/src/templates/modern/canvas.html +15 -0
  106. package/src/templates/modern/sample-profile.json +86 -0
  107. package/src/templates/modern/style.css +78 -71
  108. package/src/templates/startup-generalist/README.md +25 -0
  109. package/src/templates/startup-generalist/canvas.html +21 -0
  110. package/src/templates/startup-generalist/metadata.json +37 -0
  111. package/src/templates/startup-generalist/sample-profile.json +86 -0
  112. package/src/templates/startup-generalist/style.css +237 -0
  113. package/src/references/ats.md +0 -17
  114. package/src/references/evidence-first.md +0 -22
  115. package/src/references/pdf.md +0 -40
  116. package/src/references/resume-writing.md +0 -25
  117. package/src/references/template-design.md +0 -57
  118. package/src/templates/classic/template.html +0 -133
  119. package/src/templates/executive/template.html +0 -101
  120. package/src/templates/minimal/template.html +0 -114
  121. package/src/templates/modern/template.html +0 -139
  122. package/src/workflows/analyze-job.md +0 -16
  123. package/src/workflows/define-goal.md +0 -16
  124. package/src/workflows/forge-resume.md +0 -25
  125. package/src/workflows/know-me.md +0 -21
  126. package/src/workflows/position.md +0 -19
  127. package/src/workflows/review.md +0 -31
@@ -1,164 +1,10 @@
1
1
  #!/usr/bin/env ts-node
2
2
  "use strict";
3
- /**
4
- * KnowMe CareerForge — Playwright DOM Layout & Overflow Inspector
5
- * 基于无头浏览器真实渲染计算 DOM 盒模型高度,检测单页/双页物理 A4 溢出与孤行。
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
3
  Object.defineProperty(exports, "__esModule", { value: true });
41
4
  exports.validateLayout = validateLayout;
42
- const playwright_1 = require("playwright");
43
- const path = __importStar(require("path"));
44
- const fs = __importStar(require("fs"));
45
- async function validateLayout(htmlPath, expectedPages = 1) {
46
- const absoluteHtml = path.resolve(htmlPath);
47
- if (!fs.existsSync(absoluteHtml)) {
48
- throw new Error(`HTML file not found: ${absoluteHtml}`);
49
- }
50
- const browser = await playwright_1.chromium.launch({ headless: true });
51
- const context = await browser.newContext({
52
- viewport: { width: 794, height: 1123 }, // A4 at 96 DPI
53
- deviceScaleFactor: 1
54
- });
55
- const page = await context.newPage();
56
- await page.goto(`file://${absoluteHtml}`, { waitUntil: 'networkidle' });
57
- await page.evaluateHandle('document.fonts.ready');
58
- // A4 标准高度 (297mm in pixels at 96 DPI ~= 1122.5px)
59
- const A4_HEIGHT_PX = 1122.5;
60
- const evaluation = await page.evaluate((allowedHeight) => {
61
- const pages = Array.from(document.querySelectorAll('.resume-page'));
62
- const details = pages.map((p, idx) => {
63
- const rect = p.getBoundingClientRect();
64
- const actualHeight = Math.ceil(rect.height);
65
- const isOverflow = actualHeight > allowedHeight + 2; // 2px 浮点容差
66
- return {
67
- pageIndex: idx + 1,
68
- actualHeightPx: actualHeight,
69
- allowedHeightPx: allowedHeight,
70
- isOverflow,
71
- overflowDeltaPx: isOverflow ? Math.ceil(actualHeight - allowedHeight) : 0
72
- };
73
- });
74
- const overflowSections = [];
75
- if (details.some(d => d.isOverflow)) {
76
- const items = Array.from(document.querySelectorAll('.experience-item, .project-item, .skills-content, .resume-section'));
77
- for (const item of items) {
78
- const rect = item.getBoundingClientRect();
79
- if (rect.bottom > allowedHeight) {
80
- overflowSections.push({
81
- selector: item.className ? `.${item.className.split(' ').join('.')}` : item.tagName.toLowerCase(),
82
- bottomPx: Math.ceil(rect.bottom),
83
- overflowByPx: Math.ceil(rect.bottom - allowedHeight)
84
- });
85
- }
86
- }
87
- }
88
- return {
89
- totalPagesFound: pages.length || 1,
90
- pageDetails: details.length ? details : [{
91
- pageIndex: 1,
92
- actualHeightPx: Math.ceil(document.body.getBoundingClientRect().height),
93
- allowedHeightPx: allowedHeight,
94
- isOverflow: document.body.getBoundingClientRect().height > allowedHeight + 2,
95
- overflowDeltaPx: Math.max(0, Math.ceil(document.body.getBoundingClientRect().height - allowedHeight))
96
- }],
97
- overflowSections
98
- };
99
- }, A4_HEIGHT_PX);
100
- await browser.close();
101
- const hasOverflow = evaluation.pageDetails.some(p => p.isOverflow) || evaluation.totalPagesFound > expectedPages;
102
- return {
103
- status: hasOverflow ? 'OVERFLOW' : 'PASS',
104
- expectedPages,
105
- totalPagesFound: evaluation.totalPagesFound,
106
- pageDetails: evaluation.pageDetails,
107
- overflowSections: evaluation.overflowSections
108
- };
109
- }
110
- async function main() {
111
- const args = process.argv.slice(2);
112
- let htmlPath = 'workspace/resume.html';
113
- let expectedPages = 1;
114
- let jsonOutput = false;
115
- for (let i = 0; i < args.length; i++) {
116
- if (args[i] === '--html' || args[i] === '-i') {
117
- htmlPath = args[i + 1];
118
- i++;
119
- }
120
- else if (args[i] === '--expected-pages' || args[i] === '-p') {
121
- expectedPages = parseInt(args[i + 1], 10) || 1;
122
- i++;
123
- }
124
- else if (args[i] === '--json') {
125
- jsonOutput = true;
126
- }
127
- else if (!args[i].startsWith('-')) {
128
- htmlPath = args[i];
129
- }
130
- }
131
- try {
132
- const result = await validateLayout(htmlPath, expectedPages);
133
- if (jsonOutput) {
134
- console.log(JSON.stringify(result, null, 2));
135
- process.exit(result.status === 'PASS' ? 0 : 1);
136
- }
137
- console.log('======================================================');
138
- console.log(` KnowMe CareerForge — Layout QA: ${result.status}`);
139
- console.log(` HTML Path : ${htmlPath}`);
140
- console.log(` Expected Pages : ${result.expectedPages} | Pages Found: ${result.totalPagesFound}`);
141
- console.log('------------------------------------------------------');
142
- for (const p of result.pageDetails) {
143
- const fitText = p.isOverflow ? `[✗ OVERFLOW by ${p.overflowDeltaPx}px]` : `[✓ FIT] (Overflow: ${p.overflowDeltaPx}px)`;
144
- console.log(` Page ${p.pageIndex}: ${p.actualHeightPx}px / ${p.allowedHeightPx}px ${fitText}`);
145
- }
146
- if (result.overflowSections.length > 0) {
147
- console.log('\n[!] Offending Overflow Elements:');
148
- for (const el of result.overflowSections.slice(0, 3)) {
149
- console.log(` - Element "${el.selector}" exceeds A4 baseline by ${el.overflowByPx}px (Bottom: ${el.bottomPx}px)`);
150
- }
151
- console.log('\n💡 Recommendation: Reduce --resume-space-section by 1~2pt or reduce --resume-font-size-body by 0.2pt in <style>.');
152
- }
153
- console.log('======================================================');
154
- process.exit(result.status === 'PASS' ? 0 : 1);
155
- }
156
- catch (err) {
157
- const errorMsg = err instanceof Error ? err.message : String(err);
158
- console.error(`[✗] Layout Validation Failed: ${errorMsg}`);
159
- process.exit(1);
160
- }
161
- }
162
- if (require.main === module) {
163
- main();
5
+ const engine = require("../rendering/engine-loader");
6
+ function validateLayout(htmlPath, expectedPages = 1, options = {}) {
7
+ return engine.run(htmlPath, { ...options, expectedPages });
164
8
  }
9
+ if (require.main === module)
10
+ engine.cli();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knowme-careerforge-skill",
3
- "version": "0.0.2",
3
+ "version": "0.0.6",
4
4
  "description": "An agent-native skill for self-discovery, career positioning, and tailored resume engineering.",
5
5
  "main": "dist/cli/src/index.js",
6
6
  "bin": {
@@ -13,7 +13,10 @@
13
13
  "scripts",
14
14
  "agents",
15
15
  "SKILL.md",
16
- "skill.json"
16
+ "skill.json",
17
+ "references",
18
+ "AGENT.md",
19
+ "ARCHITECTURE.md"
17
20
  ],
18
21
  "scripts": {
19
22
  "build": "tsc",
@@ -30,7 +33,9 @@
30
33
  "build:knowledge": "python3 scripts/build/build-knowledge.py",
31
34
  "build:gallery": "python3 scripts/build/build-gallery.py",
32
35
  "release": "python3 scripts/build/release.py",
33
- "prepublishOnly": "npm run build && npm test"
36
+ "version:sync": "python3 scripts/build/sync-version.py",
37
+ "prepublishOnly": "npm test",
38
+ "pretest": "npm run build"
34
39
  },
35
40
  "keywords": [
36
41
  "career-forge",
@@ -54,8 +59,15 @@
54
59
  },
55
60
  "devDependencies": {
56
61
  "@types/node": "^22.0.0",
57
- "playwright": "^1.49.0",
58
62
  "ts-node": "^10.9.2",
59
63
  "typescript": "^5.9.3"
64
+ },
65
+ "dependencies": {
66
+ "pdf-lib": "^1.17.1",
67
+ "pdfjs-dist": "^5.4.624",
68
+ "playwright": "^1.62.1"
69
+ },
70
+ "engines": {
71
+ "node": ">=22.13.0"
60
72
  }
61
73
  }
@@ -0,0 +1,5 @@
1
+ # Organize user-supplied facts
2
+
3
+ Use the user's descriptions, prior resume and explicitly supplied supporting material. Repository scanning is not a supported candidate input mode. Reuse known information; ask progressive follow-up questions only for consequential gaps. Do not invent dates, employers, degrees or metrics, or weaken stated ownership solely because it came from chat.
4
+
5
+ Store incomplete information as Draft and reviewed supplied facts as Master. Derive role-specific Variant content without changing the Master. Unknown values remain omitted/null. Follow the shared lifecycle and error rules in 07-artifact-contract.md.
@@ -0,0 +1,38 @@
1
+ # Reference Manual 02: Career Goal Definition & Role Archetypes
2
+
3
+ > **"Know Yourself. Define Your Direction. Forge Your Opportunity."**
4
+
5
+ ---
6
+
7
+ ## 1. Professional Seniority Signals
8
+
9
+ Identify candidate level and calibrate narrative depth accordingly:
10
+
11
+ | Seniority Tier | Core Value Proposition | Key Narrative Signals | Section Priority |
12
+ |:---|:---|:---|:---|
13
+ | **Junior (1~3 Years)** | Rapid learning, solid coding standards, reliable task delivery | Clean code, unit test coverage, framework fluency, bug resolution | Skills → Projects → Experience → Education |
14
+ | **Mid-Level (3~5 Years)** | Independent ownership, feature architecture, performance optimization | End-to-end module ownership, database tuning, API design, CI/CD | Experience → Projects → Skills → Education |
15
+ | **Senior / Lead (5~8+ Years)** | System architecture, technical leadership, cross-system trade-offs | Distributed systems, high availability, mentoring, business impact | Experience → Projects → Architecture → Skills |
16
+ | **Principal / Architect** | Technical vision, organizational strategy, governance, ROI | Architecture governance, multi-team alignment, technology selection | Experience → Leadership → Architecture → Patents |
17
+
18
+ ---
19
+
20
+ ## 2. Role Archetypes Knowledge Base (`src/knowledge/roles/*.json`)
21
+
22
+ The skill ships with 9+ structured role profiles:
23
+ - `ai-agent-engineer.json`: LLM Orchestration, RAG, Tool Calling, VectorDB, Prompt Engineering
24
+ - `frontend.json`: React/Vue/Next.js, Web Vitals, Design Systems, State Management
25
+ - `java-backend.json`: Spring Boot, JVM tuning, Distributed Caching, Message Queues
26
+ - `node-fullstack.json`: TypeScript, Node.js runtime, GraphQL, Cloud Native
27
+ - `architect.json`: Distributed Systems, Domain-Driven Design, High Concurrency, Cloud Architecture
28
+ - `product-manager.json`: PRD, User Research, Data Analysis, Roadmapping, Growth
29
+
30
+ ---
31
+
32
+ ## 3. Core Value Proposition Formulation
33
+
34
+ Synthesize the 15~25 word Value Proposition headline following this formula:
35
+ $$\text{Value Proposition} = [\text{Target Role}] + [\text{Years/Domain Focus}] + [\text{Top 2 Signature Strengths}] + [\text{Concrete Impact Deliverable}]$$
36
+
37
+ *Example*:
38
+ > **Senior AI Agent Engineer** with 5+ years building scalable LLM orchestration & enterprise RAG pipelines, delivering 40% latency reduction across multi-agent production workflows.
@@ -0,0 +1,44 @@
1
+ # Reference Manual 03: Job Description (JD) Analysis & Keyword Extraction
2
+
3
+ > **"Understand the hiring manager's unstated pain point to align your verified strengths."**
4
+
5
+ ---
6
+
7
+ ## 1. Automated JD Signal Parsing Protocol
8
+
9
+ Execute the JD analyzer to extract structured requirements:
10
+ ```bash
11
+ python3 scripts/evidence/analyze-jd.py --jd "path/to/jd.md" --json
12
+ ```
13
+
14
+ ### Signal Extraction Dimensions:
15
+ 1. **Target Role & Seniority Tier**: Extracted from title and years of experience requirements;
16
+ 2. **Must-Have Skills (Hard Constraints)**: Top technical stacks and non-negotiable architectural competencies;
17
+ 3. **Nice-to-Have Skills (Differentiators)**: Emerging tools, cloud certifications, domain bonuses;
18
+ 4. **Hiring Pain Points**: High-frequency verbs indicating immediate business challenges (e.g., "reduce latency", "overhaul legacy monolithic service", "establish CI/CD").
19
+
20
+ ---
21
+
22
+ ## 2. Keyword Density & Highlighting Rules
23
+
24
+ In `workspace/resume.html`, inject JD keywords to pass ATS automated screening while remaining natural for human reviewers:
25
+
26
+ - **Primary Stack (Top 3~5 Keywords)**: Wrap with `<strong>` tags inside bullet points where evidence exists;
27
+ - **Technology Badges**: Place in `.tech-tags` or `.tech-badge` spans;
28
+ - **Density Control**: Maintain keyword density around 2.5%~4.0% of total words to prevent ATS keyword stuffing penalties.
29
+
30
+ ---
31
+
32
+ ## 3. FAB (Feature-Advantage-Benefit) Bullet Engineering
33
+
34
+ Structure every project bullet point using the FAB formula:
35
+
36
+ ```
37
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
38
+ │ Feature (技术动作)│ ────> │ Advantage (技术优势)│ ────> │ Benefit (业务价值) │
39
+ │ Exact tech & tool │ │ Architectural gain│ │ Quantified impact│
40
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
41
+ ```
42
+
43
+ *Before (Weak)*: Worked on database and improved query performance.
44
+ *After (FAB Standard)*: Refactored PostgreSQL indexing and introduced Redis multi-tier caching (**Feature**), cutting P99 query latency from 850ms to 45ms (**Advantage**), supporting 10x traffic spike during peak sales (**Benefit**).
@@ -0,0 +1,43 @@
1
+ # Reference Manual 04: Template Selection & Layout Geometries
2
+
3
+ > **"Layout geometry determines information hierarchy. Select the composition that earns the candidate's strongest evidence."**
4
+
5
+ ---
6
+
7
+ ## 1. Core Template Matrix (Baseline 4)
8
+
9
+ | Template ID | Layout Geometry | Tone & Accent | Target Roles | Density | ATS Tier |
10
+ |:---|:---|:---|:---|:---|:---|
11
+ | `minimal` (`minimal-tech`) | Single-Column Linear Flow | Geek Minimal (Tech Blue `#2563eb`) | Backend, AI/LLM, Systems, DevOps, Fullstack | High | Tier 1 (Optimal) |
12
+ | `modern` (`modern-split-sidebar`) | Two-Column Split (32:68 Dark Sidebar) | Deep Navy (`#254665`) + Sky Blue (`#38bdf8`) | AI Agent, Frontend, Fullstack, Mobile | Balanced | Tier 1 (Optimal) |
13
+ | `executive` (`executive-split`) | Hero Banner + Two-Column (33:67 Split) | Executive Slate (`#1e293b`) + Teal (`#0f766e`) | Tech Director, Architect, PM, CTO | Balanced | Tier 1 (Optimal) |
14
+ | `classic` (`table-structured`) | 6-Column Structured Grid Table | Corporate Blue (`#1d4ed8`) + Slate | Enterprise, Fintech, Hardware, State-Owned | High | Tier 1 (Optimal) |
15
+
16
+ ---
17
+
18
+ ## 2. Template Search Engine (`scripts/template/search-template.py`)
19
+
20
+ Search for the optimal template via CLI:
21
+ ```bash
22
+ # Hybrid Search (Default Recommended)
23
+ python3 scripts/template/search-template.py "AI Agent Engineer" --style "two-column-split" --target-pages 1
24
+
25
+ # BM25 Keyword Search
26
+ python3 scripts/template/search-template.py "Distributed Architect" --engine bm25 --json
27
+
28
+ # Weighted Multi-Criteria Rule Search
29
+ python3 scripts/template/search-template.py "Frontend Engineer" --engine weighted
30
+ ```
31
+
32
+ ### Search Scoring Formulation (Weighted Scorer):
33
+ $$\text{Score} = (\text{RoleMatch} \times 0.35) + (\text{StyleMatch} \times 0.25) + (\text{ATSTier} \times 0.20) + (\text{PageFit} \times 0.10) + (\text{Density} \times 0.10)$$
34
+
35
+ ---
36
+
37
+ ## 3. Instantiating the Intermediate HTML Canvas
38
+
39
+ ```bash
40
+ python3 scripts/template/instantiate-resume.py --template modern --profile workspace/evidence-master.json --keywords "Python,LLM,RAG,FastAPI" --output workspace/resume.html
41
+ ```
42
+
43
+ *The instantiator automatically inlines `src/templates/common/base.css` + `src/templates/{template}/style.css` into a single self-contained HTML file.*
@@ -0,0 +1,12 @@
1
+ # HTML canvas and tokens
2
+
3
+ Instantiate an empty canvas.html skeleton with explicit user facts. canvas.html is the sole maintained structure. Gallery previews bind explicit fictional sample-profile.json through the same instantiator and full CSS chain; sample data must never serve as default candidate facts. Shared normalization accepts omitted/null optional fields and rejects invalid types. Failed binding must preserve old output and return nonzero.
4
+
5
+ Tune the run's HTML with CSS variables for section/item/bullet spacing and body typography. Preserve manually edited content rather than regenerating stale profile data. Auto-healing cannot remove facts or reduce body font below 8.8pt. Validate in print mode, inspect all pages and verify the actual PDF before delivery. See 07-artifact-contract.md.
6
+
7
+
8
+ ## 本地字体与缺字诊断
9
+
10
+ `forge.py` 和 `instantiate-resume.py` 支持 `--font-preset system|arial-unicode`,默认保留系统字体。`arial-unicode` 显式使用本机 Arial Unicode MS;没有该字体时字体验收失败并返回 UNVERIFIED,不保证跨机器可用,也不自动下载字体。字体选择只改变画布样式,不改变 Master 事实,并记录在 Variant 的 source.fontPreset 和运行清单中。
11
+
12
+ 中文 PDF 若文本验收失败,检查 QA 每页的 missingCodepoints、missingFragments 与 extractedRadicals。部首字符可能来自字体字码映射差异,也可能存在真实缺字;不能仅凭这种提示放行。可选用本机可用字体、创建新运行并重新检查,不改写姓名/经历来绕过问题,也不把部首字符全部忽略。
@@ -0,0 +1,14 @@
1
+ # QA and final rendering
2
+
3
+ Validation and rendering use scripts/rendering/browser-engine.js. Inspect print media after fonts settle, every page container and visible content boundary; generate a fresh PDF and parse every page for A4 portrait dimensions, allowed page count and extractable content matching the canvas.
4
+
5
+ PASS requires the actual checks to complete. Missing browser/dependencies or timeout is UNVERIFIED (exit 2), a failed check is FAIL (exit 1). JSON mode uses the same exit rules. Do not use an estimate or an existing PDF as proof. Export verified bytes through a temporary file and atomic replacement; failed export retains the previous file.
6
+
7
+ The pipeline isolates each run and records artifact hashes in manifest.json. Use its current PASS output paths, not shared default filenames. Factual and visual review remain Agent responsibilities; text extraction does not certify every ATS. See 07-artifact-contract.md for the complete lifecycle.
8
+
9
+
10
+ ## 本地字体与缺字诊断
11
+
12
+ `forge.py` 和 `instantiate-resume.py` 支持 `--font-preset system|arial-unicode`,默认保留系统字体。`arial-unicode` 显式使用本机 Arial Unicode MS;没有该字体时字体验收失败并返回 UNVERIFIED,不保证跨机器可用,也不自动下载字体。字体选择只改变画布样式,不改变 Master 事实,并记录在 Variant 的 source.fontPreset 和运行清单中。
13
+
14
+ 中文 PDF 若文本验收失败,检查 QA 每页的 missingCodepoints、missingFragments 与 extractedRadicals。部首字符可能来自字体字码映射差异,也可能存在真实缺字;不能仅凭这种提示放行。可选用本机可用字体、创建新运行并重新检查,不改写姓名/经历来绕过问题,也不把部首字符全部忽略。
@@ -0,0 +1,64 @@
1
+ # 资料、运行与验收契约
2
+
3
+ ## Draft / Master / Variant
4
+
5
+ 这三个值表示资料用途,不是质量评分,也不表示已独立核实事实。
6
+
7
+ | kind | 用途 | 约束 |
8
+ | --- | --- | --- |
9
+ | draft | 用户资料尚不完整的草稿 | 可缺姓名及经历;仅生成草稿画布,不能报告 PDF 已验收 |
10
+ | master | 用户或 Agent 整理的完整事实集合 | 每次运行只保存新快照,不反写输入;完整指保留本次已知事实,不强制具备所有可选字段 |
11
+ | variant | 为目标岗位派生的展示资料 | 记录来源 Master 的 profileSha256;岗位标题只修改 Variant,不回写 Master;不能作为下一份 Master 隐式导入 |
12
+
13
+ 标准文档形状为:
14
+
15
+ ```json
16
+ {
17
+ "schemaVersion": "1.0",
18
+ "kind": "master",
19
+ "profile": {"basics": {"name": "候选人姓名"}},
20
+ "source": {"type": "user-input"}
21
+ }
22
+ ```
23
+
24
+ `profile` 的字段定义见 `src/knowledge/resume-schema.json`;脚本 `scripts/contracts/profile.py` 是归一化与封装契约的实现。脚本输出时附加 `profileSha256` 和 `missingFields`。摘要用于发现资料版本变化,不证明用户陈述真实性。手动修改封装资料后,应重新生成摘要或移除旧摘要再读入;不能保留不匹配的摘要。
25
+
26
+ 兼容旧版的裸 profile JSON,按调用者明确提供的 Master 事实输入处理。封装为 Draft 的输入必须加 `--draft` 才能生成草稿;复核后由 Agent 显式整理为 Master,不由工具自动升级。Variant 的语义改写与事实选择仍由宿主 Agent 完成;当前脚本保留所有输入条目,只处理显式基础信息覆盖、岗位标题及展示装配。
27
+
28
+ ## 缺失值
29
+
30
+ - 可选字段省略或 null 均表示未知,空白字符串归为 null,不生成占位候选人事实。
31
+ - null 的数组归为空数组;数组中的空白/null 项省略。未知字段和错误类型拒绝,不能悄悄丢失可能重要的资料。
32
+ - 教育经历、项目和工作经历为独立数组,按输入顺序完整处理;无教育描述不补“优秀毕业生”等默认荣誉。
33
+ - 缺失联系方式和目标岗位记录为待补信息。正式交付至少需要非空姓名及实质内容,打印与 PDF 验收进一步判断内容有效性。
34
+ - 旧版 L1/L2/L3 元数据可保留;用户陈述不因为来自对话就自动降级为“参与”。
35
+
36
+ ## 每次运行独立
37
+
38
+ `forge --profile-json <file>` 在 `workspace/runs/<唯一运行ID>/` 下创建私有目录,包含 `input.json` 原始输入快照、`master.json`、`variant.json`、`resume.html`、`qa.json`、通过验收后写入的 `resume.pdf` 和 `manifest.json`。Draft 运行保存 `draft.json` 和草稿画布,不生成正式 PDF。
39
+
40
+ `--workspace` 仅改变运行目录的父目录,不复用已有运行。失败现场保留供诊断,不自动删除或继续使用其他运行的文件。目录包含个人资料,不提交到 Git;可由用户按需删除。测试必须使用临时目录。
41
+
42
+ `--html-output` 和 `--output` 是可选的已验收副本路径。先在独立运行中完成验证,再一起准备副本;写入失败时回滚普通错误,目标锁阻止两个本工具进程交错写入。跨文件复制不具备操作系统崩溃下的事务保证,因此运行目录和 manifest 始终是交付判据。发现遗留锁时报告冲突,不擅自删除其他运行的锁。
43
+
44
+ ## 运行与检查状态
45
+
46
+ | status | 退出码 | 意义 |
47
+ | --- | --- | --- |
48
+ | RUNNING | 不作为最终结果 | 已开始但未完成,不能交付 |
49
+ | DRAFT | 0 | 草稿准备完成,无 PDF 验收承诺 |
50
+ | PASS | 0 | 本次指定检查及最终 PDF 验收通过 |
51
+ | FAIL | 1 | 输入、绑定、布局、PDF 内容或输出写入不符合要求 |
52
+ | UNVERIFIED | 2 | 浏览器、依赖、超时或检查协议故障,无法完成验收 |
53
+
54
+ `manifest.json` 包含 `runId`、`stage`、`errors`、`warnings`、`checks`、`outputs`。失败的 `outputs` 为空,即使目录或显式输出位置存在旧 PDF,也不能返回它作为本次交付。只有 PASS 的清单记录本次输出路径及 HTML/PDF SHA-256。JSON 模式与人读模式使用同一退出语义。
55
+
56
+ ## 打印与最终 PDF
57
+
58
+ 布局与导出共用 `scripts/rendering/browser-engine.js`,以 print 媒体模式等待字体,检查所有页面容器与内容边界。再生成新的 PDF,解析所有页,检查 A4 纵向尺寸、页数上限、逐页可提取文本与正文覆盖。最终写入的是通过验收的 PDF 字节,使用临时文件原子替换,不接受旧输出文件作为生成成功的证据。
59
+
60
+ 自动调优不得增加当前间距,正文字号不降至 8.8pt 以下;调优失败保留原画布,不删改事实来强行过关。浏览器不可用不得用字数/盒模型估算替代 PASS。PDF 文本提取通过不代表所有 ATS 对多栏阅读顺序的解释一致;事实与视觉仍需 Agent 复核。
61
+
62
+ 当前分页契约要求每个 `.resume-page` 对应一个 A4 页面,`--expected-pages` 为 1 或 2 的上限。一页文档可用上限 2;两页文档需由 Agent 显式建立两个页面容器。单个超高容器自然流入多页会被拒绝,不猜测浏览器分页后每页应有的内容。
63
+
64
+ 输入文档的来源说明保存在 Master 的 source.suppliedSource 中,包括 synthetic-simulation 等原始标签。它是来源元数据,不是新增候选人事实。字体预设单独记录为 Variant.source.fontPreset;不得把字体修订误记为事实变更。
package/scripts/Agent.md CHANGED
@@ -1,138 +1,11 @@
1
- # KnowMe CareerForge — Scripts Architecture & Agent Execution Specification
1
+ # Script responsibilities
2
2
 
3
- > **定位**:面向 AI Agent 与研发工程师的 `scripts/` 工具链架构规范、模块划分标准与执行契约手册。
4
- >
5
- > **版本**:v1.0.0-modular
6
- > **核心原则**:Domain-Driven Modularization · Quiet Agent Execution · Deterministic Rendering · Zero-Dependency Python Core
3
+ - contracts/: shared Draft/Master/Variant normalization and missing-value rules.
4
+ - pipeline/: unique run directory, immutable input snapshot, Master and Variant lineage, explicit result manifest and verified copies.
5
+ - evidence/: optional JD helpers; legacy extract-evidence.py is not a supported candidate input path.
6
+ - template/: template ranking and deterministic fact-only canvas binding.
7
+ - validation/: print-mode geometry and content checks through the shared browser engine; no estimate-based PASS.
8
+ - rendering/: final PDF page/text validation and atomic write, preserving old outputs on failure.
9
+ - build/: package, gallery and test utilities. Tests must write only to temporary directories.
7
10
 
8
- ---
9
-
10
- ## 1. 目录架构与模块职责划分 (Domain Architecture)
11
-
12
- 为了保证脚本工具链的高内聚、低耦合与易维护性,`scripts/` 目录划分为 **6 大功能领域模块**:
13
-
14
- ```text
15
- scripts/
16
- ├── Agent.md # 本规范文档 (Source of Truth for Agent/Dev)
17
- │
18
- ├── pipeline/ # 【模块 1: 端到端统筹管线】
19
- │ └── forge.py # 一键端到端装配引擎 (One-Shot Pipeline: 挖掘 -> 装配 -> QA -> PDF)
20
- │
21
- ├── evidence/ # 【模块 2: 事实与证据挖掘 (repo-to-resume)】
22
- │ ├── extract-evidence.py # 代码仓与 Git 事实挖掘器 (提取技术栈、架构信号、Git 贡献 -> L1~L3 证据链)
23
- │ └── analyze-jd.py # 目标 JD 深度分析器 (提取职级、分类、必备/加分项、痛点关键词)
24
- │
25
- ├── template/ # 【模块 3: 模板检索与工作区装配】
26
- │ ├── search-template.py # 多维加权打分搜索引擎 (BM25 + 岗位/风格/页数/密度推荐)
27
- │ └── instantiate-resume.py # 模板装配与数据注入引擎 (CSS 内联单文件 + 结构化数据注入 + 关键词高亮)
28
- │
29
- ├── validation/ # 【模块 4: 双重 QA 自动化质检】
30
- │ ├── validate-resume.py # 语义结构、Design Tokens 与字符密度轻量校验器
31
- │ ├── validate-layout.ts # Playwright DOM 盒模型物理高度 (1122.5px A4) 溢出与孤行检测
32
- │ └── validate-ats.ts # ATS 纯文本流解析、联系方式与 H1/H2 标头层级校验
33
- │
34
- ├── rendering/ # 【模块 5: 确定性 PDF 渲染导出】
35
- │ ├── render-pdf.py # 跨平台自愈式 PDF 渲染调度器 (自动探测 Playwright 及全平台 Chromium/Edge/Brave)
36
- │ └── render-pdf.ts # Playwright 驱动的无损矢量 A4 PDF 渲染器
37
- │
38
- └── build/ # 【模块 6: 编译构建、测试与发布工具链】
39
- ├── build-knowledge.py # 岗位画像与模板知识库索引编译器 (生成 index.json & templates.json)
40
- ├── build-gallery.py # 静态交互式模板画廊生成器 (编译 output/templates_gallery/)
41
- ├── run-all-tests.py # 全链路自动化测试运行器 (discover & run tests/)
42
- ├── sync-version.py # 多清单版本号同步器 (package.json / pyproject.toml / skill.json / cli)
43
- └── release.py # 自动化发布流水线引擎 (版本对齐 -> 编译 -> 测试 -> 打包预检)
44
- ```
45
- ---
46
-
47
- ## 2. 脚本契约与 Agent 调用规范 (Execution Contracts)
48
-
49
- ### 2.1 推荐调用模式:一键直达管线 (One-Shot Execution)
50
-
51
- AI Agent 响应用户求职定制需求时,**强烈推荐首选一键管线**:
52
-
53
- ```bash
54
- # 静默全流程执行 (后台自动完成:代码仓扫描 -> 模板检索 -> 工作区注入 -> Dual QA -> PDF 导出)
55
- python3 scripts/pipeline/forge.py --repo . --role "<Target Role>" --jd "<path/to/jd.txt>" --template modern --quiet
56
- ```
57
- * **CLI 等价形式**:`knowme forge --repo . --role "<Target Role>" --template modern --quiet`
58
- * **返回格式**:结构化 JSON,供 Agent 直接获取交付文件路径:
59
- ```json
60
- {
61
- "status": "SUCCESS",
62
- "htmlCanvas": "workspace/resume.html",
63
- "pdfDelivery": "workspace/resume.pdf",
64
- "evidenceProfile": "workspace/evidence-master.json",
65
- "templateUsed": "modern"
66
- }
67
- ```
68
-
69
- ---
70
-
71
- ### 2.2 细粒度分步调用接口 (Granular Step-by-Step APIs)
72
-
73
- 当 Agent 或用户需要分步微调、审查证据或调校 Design Tokens 时,按以下顺序执行:
74
-
75
- | 步骤 | 阶段 | 推荐命令 | 关键参数 | 产出物 |
76
- | :--- | :--- | :--- | :--- | :--- |
77
- | **Step 1** | **事实挖掘** | `python3 scripts/evidence/extract-evidence.py` | `--repo <dir>` `--name <name>` `--quiet` | `workspace/evidence-master.json` |
78
- | **Step 2** | **JD 解析** | `python3 scripts/evidence/analyze-jd.py` | `--jd <file>` 或 `--text "<str>"` `--json` | 提取必须技能与权重关键词 |
79
- | **Step 3** | **模板检索** | `python3 scripts/template/search-template.py` | `"<Role>"` `--style "<style>"` `--json` | 加权推荐模板列表 (Top 1) |
80
- | **Step 4** | **画布装配** | `python3 scripts/template/instantiate-resume.py` | `--template <id>` `--profile <json>` `--keywords <kw>` | `workspace/resume.html` (单文件内联) |
81
- | **Step 5** | **质检自愈** | `python3 scripts/validation/validate-resume.py` | `--html workspace/resume.html` `--expected-pages 1` | QA 诊断状态与溢出提示 |
82
- | **Step 6** | **PDF 导出** | `python3 scripts/rendering/render-pdf.py` | `workspace/resume.html` `workspace/resume.pdf` `--quiet` | `workspace/resume.pdf` (确定性矢量) |
83
-
84
- ---
85
-
86
- ## 3. Agent 对话降噪规范 (Strict Quiet Execution Protocol)
87
-
88
- 为了杜绝对话框中出现几百行冗余代码或中间脚本,所有接入的 AI Agent 必须遵守以下铁律:
89
-
90
- 1. **禁止在 Chat 中打印原始 HTML/CSS**:禁止将 `workspace/resume.html` 的数百行代码打印到对话框中;
91
- 2. **禁止在 Chat 中编写现场临时脚本**:严禁现场生成临时验证脚本或修改场脚本,必须使用 `scripts/` 下既有的标准工具链;
92
- 3. **静默执行原则**:调用脚本时统一添加 `--quiet` 或 `--json` 参数;
93
- 4. **标准交付物格式**:
94
- ```markdown
95
- ### 🎯 职业定位与核心价值主张 (Core Value Proposition)
96
- > **[姓名] · [目标岗位]**
97
- > *[15~25字核心定位与价值阐述]*
98
-
99
- ---
100
-
101
- ### 🛡️ Top 3 真实证据链亮点 (L1/L2 级别可追溯事实)
102
- 1. **[业务方向/核心架构]**: [动词 + 可量化成果 + 证据来源]
103
- 2. **[核心技术栈工程化]**: [关键框架与工程规范落地]
104
- 3. **[交付与系统效能]**: [稳定性/CI-CD/性能指标]
105
-
106
- ---
107
-
108
- ### 📄 最终交付产物
109
- - **PDF 终稿 (确定性 A4)**: `workspace/resume.pdf`
110
- - **HTML 修改场 (Design Tokens)**: `workspace/resume.html`
111
- - **证据事实底座**: `workspace/evidence-master.json`
112
- ```
113
-
114
- ---
115
-
116
- ## 4. 后续开发与扩展规范 (Developer Standards)
117
-
118
- 为保持工程整洁与跨平台稳定性,后续新增或修改脚本必须遵循以下标准:
119
-
120
- ### 4.1 根路径自适应解析 (Root Path Resolution Standard)
121
- 所有 Python 脚本**严禁使用硬编码相对路径**,必须通过自适应探测函数定位项目根目录:
122
- ```python
123
- def get_project_root() -> Path:
124
- curr = Path(__file__).resolve().parent
125
- for _ in range(5):
126
- if (curr / "SKILL.md").exists() or (curr / "package.json").exists():
127
- return curr
128
- curr = curr.parent
129
- return Path.cwd()
130
- ```
131
-
132
- ### 4.2 零重型依赖原则 (Zero-Heavy-Dependency)
133
- * 核心运行脚本(`evidence/`、`template/`、`pipeline/`)**仅使用 Python 3.9+ 标准库**(`json`, `argparse`, `pathlib`, `re`, `subprocess` 等);
134
- * 避免引入大型三方包(如 pandas、scikit-learn),保证轻量秒开与跨平台零安装成本。
135
-
136
- ### 4.3 渲染与 QA 规范
137
- * A4 绝对高度基准固化为 `1122.5px` ($297\text{mm} \times 96\text{DPI} / 25.4$);
138
- * 任何涉及排版验证与 PDF 导出的改动,必须通过 `scripts/build/run-all-tests.py` 全量测试套件验证。
11
+ Read ../references/07-artifact-contract.md for the authoritative artifact lifecycle, status/exit-code rules and output contract. Runtime scripts are resolved from the Skill installation; candidate artifacts belong to the user's workspace. A Draft is useful output but is never a verified PDF. FAIL and UNVERIFIED are nonzero exits in JSON and human-readable modes.