ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ai-job-search 求职追踪仪表盘:用 /html-report 一键生成零依赖的离线 HTML 看板

ai-job-search 求职追踪仪表盘:用 /html-report 一键生成零依赖的离线 HTML 看板 AI 应用AI 技能【免费下载链接】ai-job-searchThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.项目地址https://gitcode.com/GitHub_Trending/ai/ai-job-search点击查看免费下载/html-report是 ai-job-search 框架内置的追踪仪表盘命令它把job_search_tracker.csv与documents/applications/下的申请归档合并成一个单个、自包含、可完全离线打开的 HTML 文件——无服务器、无 CDN、无任何外部依赖双击即可在浏览器查看。读完本文你将掌握该命令的完整执行流程参数解析、数据收集、统计口径、HTML/SVG 渲染、它背后严格的不虚构数据设计原则以及仓库测试如何锁定这些行为。命令定位追踪仪表盘在求职工作流中的位置在 ai-job-search 的闭环中/apply负责投递并写追踪行、/outcome负责记录结果与归档而/html-report是这两个命令数据的纯消费者它只读不写从追踪器和归档生成可视化报告。README 中将其定位为re-run it any time after/applyor/outcomeadds new entries——即每投递或记录一次结果随时重跑即可刷新看板。与/notion-sync面向 Notion 的可随时瞥一眼的实时视图互补/html-report是办公桌前深度查看的离线仪表盘不依赖任何第三方服务数据完全留在本机。Step 0参数解析与输出路径命令接受三种调用形式逻辑在 html-report.md 的 Step 0 中定义调用形式行为/html-report无参数输出到reports/application-dashboard.html/html-report ~/Desktop/report.html路径参数输出到指定路径/html-report --open写入后提示用户手动打开文件命令本身无法直接拉起浏览器若reports/目录不存在则先创建。注意输出目录是刻意被忽略的仓库.gitignore第 96 行明确记录了reports/因为生成的仪表盘属于个人产出数据不应被提交。Step 1数据收集——两个数据源的并行读取与合并命令在一步内并行读取两类数据1.1job_search_tracker.csv主数据源每一行被解析为包含 14 个字段的记录date、company、sector、role、role_type、channel、status、contact_person、fit_rating、notes、cv_file、cover_letter_file、source、deadline这 14 列头部与 apply.md Step 6b 及 outcome.md Step 1.1 使用的规范头部完全相同——两个命令在创建/迁移时共享同一套头部定义保证数据永不漂移。测试 test_html_report_command.py 中test_step1_parses_every_canonical_tracker_column会实时从apply.md读回规范头部并与命令文件中的字段枚举比对防止未来新增列后仪表盘静默漏掉。旧数据兼容在deadline列加入之前写入的行只有 13 个字段、无第 14 个值。解析时必须把缺失字段当作空值处理——既不能丢弃整行也绝不能从该行的date推断 deadline。这一点在tools/rank_state.py中有对应的防御性日期解析缺失 deadline 留空、绝不猜测而/applyStep 6b 的迁移规则更明确若文件头部不以,deadline结尾仅在头部行追加,deadline不触碰任何数据行。1.2documents/applications/*/outcome.md阶段历史补充对每个已结案的申请读取归档中的outcome.md格式见 documents/README.md含Interview stages reached复选框与Notes提取实际到达的面试阶段勾选框与备注然后按 companyrole 模糊匹配小写化、忽略标点合并进追踪器对应行若某行有归档但匹配不上也把归档作为额外上下文附加。1.3 状态归一化六个规范桶计算统计前先把追踪器中的status值映射到 6 个规范桶大小写不敏感追踪器值规范桶draftedDrafted/apply已产出文档、尚未投递appliedActive简历已提交、无进一步信号interviewInterviewofferOfferhiredHiredrejected/no_response/no response/offer_declined/offer declined/withdrawnRejected/Closed其他任何值Rejected/Closed并在状态明细中把未识别值点名一次这套桶映射在读取时容忍旧版空格拼写no response、offer declined这样规范拼写锁定前写入的数据不会从统计中消失而权威的状态词汇表在 outcome.md 的Tracker status vocabulary一节规范拼写为下划线形式drafted、applied、interview、offer、hired、rejected、no_response、offer_declined、withdrawn。Step 2汇总统计——三个最容易算错的指标2.1 Drafted 行的排除规则Drafted 行被排除在下面每一项统计之外——它们从未投递。Drafted 计数单独报告仅出现在状态明细中。这也是documents/README.md与/outcome对drafted语义的延续未发送即无信号可言。2.2 漏斗率从阶段历史而非当前状态计算漏斗率回答多少比例越过了简历筛选进入 Interview 或更后。命令明确要求stage-reached 从历史计算不从当前状态计算——当一条记录当前状态暗示到达某阶段、或其合并的outcome.md阶段勾选框显示到达该阶段时才算到达。测试test_funnel_is_computed_from_stage_history_not_current_status直接锁定这一规则一条rejected行若其 outcome 文件勾了面试阶段仍计入 Interview一条hired行视为到达 Hired 之前的每一个阶段。原因在命令文档中写得很直白仅凭当前状态会在结构上少计每个早期阶段——一场已经结束的求职会读起来像从来没有人参加过面试对应 2026-08-19 评审发现 F10测试注释中留档。2.3 拒绝率与 Rejected/Closed 桶严格区分拒绝率的分子只含真正的拒绝rejected、no_response分母只含有最终结果的申请offer_declined候选人拒绝了 offer——这是成功与withdrawn候选人主动撤回不是拒绝不得进分子Interview、Offer 行仍未结案与 Active 一起不进分母。也就是说Rejected/Closed桶在环形图中仍把全部已结案行归组但计算比率时绝不能盲目复用该桶——这是命令明确划出的边界评审发现 F11测试test_rejection_rate_excludes_declined_offers_and_withdrawals负责守门。Step 3生成 HTML——单文件、全内联、手写 SVG3.1 自包含与转义强制项输出是单个HTML 文件所有 CSS 内联在style块、所有 JS 内联在script块环形图与柱状图全部由手写内联 SVG绘制——不用 Chart.js、不用 CDN、不用任何外部依赖保证每次打开都完全离线渲染。转义是强制要求插值进页面的每个 CSV/outcome 值都要做 HTML 转义覆盖表格单元格、截断备注的title提示属性、以及任何放进 SVG 的文本text标签、图表 tooltip。原因很实际从职位帖复制来的备注和公司名常含这些字符不转义会破坏布局甚至把标记注入一个用户每天打开的个人页面。3.2 布局与设计规范页面布局遵循命令文档中的 ASCII 结构顶部标题栏含生成日期→ 6 张统计卡Sent/Draft/Active/Interview/Offer/Rejected-Closed→ 两行图表区 → 底部带过滤器的申请明细表┌─────────────────────────────────────────────┐ │ Job Search Dashboard Generated: DATE │ ├──────┬──────┬──────┬──────┬──────┬───────────┤ │Sent │Draft │Active│Inter-│Offer │Rejected/ │ ← stat cards │ N │ N │ N │view N│ N │Closed N │ ├──────┴──────┴──────┴──────┴──────┴───────────┤ │ Status breakdown (doughnut) │ By sector (bar)│ ← charts row ├───────────────────────────────────────────── ┤ │ By channel (bar) │ Funnel (horizontal bar) │ ← charts row ├────────────────────────────────────────────── ┤ │ Applications [Status ▾] [Sector ▾] [ ...]│ ← table with filters │ date │ company │ sector │ role │ status │ ... │ │ ... │ └───────────────────────────────────────────────┘设计规范要点配色CSS 自定义属性承载状态色——Drafted#64748b石板灰、Active#3b82f6蓝、Interview#f59e0b琥珀、Offer#8b5cf6紫、Hired#22c55e绿、Rejected/Closed#ef4444红字体system-ui 栈不加载任何网络字体统计卡白底、轻阴影、大号加粗数字、下方标签、左侧状态色边框图表宽屏两列网格、窄屏纵向堆叠表格隔行着色状态列用彩色 pill/badgesource列若值为 URL以http开头渲染为超链接空单元格渲染为—响应式900px 以上可用以下不破损页脚Generated by Claude Code · ai-job-search · {ISO date}。3.3 客户端过滤表格自带三重 AND 组合过滤一个文本搜索框跨 company role sector 过滤加上 status、sector 两个下拉框独立过滤三者叠加生效。默认排序为日期倒序date降序其次按公司名字母序。注意表格列的顺序在 test_html_report_command.py 的test_step3_table_columns_include_deadline_after_date中有专门测试——Date 必须在 Deadline 之前因为 deadline 正是驱动/rank紧急度判断的那口钟仪表盘必须把它放在日期旁边该测试特意拒绝两者都出现即可的宽松断言因为列序本身就是表格展示给读者的一部分。3.4 四类图表全手写 SVG每个图表都是手写svg从 Step 2 的统计值计算柱长/环形弧角直接输出rect/path/circle/text元素——不用图表库、不用canvas。每个svg带roleimg和汇总用的aria-label如 Status breakdown: 3 Active, 2 Interview, 1 Offer外包一层div classchart-card并配h3标题。绘制进text节点的标签/数值同样遵循转义规则。Status doughnut状态环形图——每个状态桶一个扇区颜色取自调色板By sector bar行业横向柱状图——每个行业公司数降序排列By channel bar渠道柱状图——online / referral / otherApplication funnel横向漏斗图——Applied → Interview → Offer → Hired每根柱 到达该阶段的计数按 Step 2 的漏斗规则当前状态加合并的outcome.md阶段勾选框推导——所以面试后又被拒的候选人依然计入 Interview 柱。3.5 表格列集合Date·Deadline·Company·Role·Sector·Channel·Status·Notes截断至 80 字符用title提示展示全文·Source链接或—。整列在所有行中均为空值时允许省略该列。Step 4写入与确认将完整 HTML 写入输出路径后命令按固定格式呈现结果摘要Dashboard generated:output pathOpen it in any browser — no server needed.Summary:Applications sent: N · drafted, not yet sent: NActive: N · Interview: N · Hired: N · Rejected/Closed: NFunnel: N% progressed past resume screenRe-run/html-reportany time after adding new entries via/applyor/outcometo refresh the dashboard.设计原则五项约束保障数据可信命令末尾明确列出五项设计原则这也是它区别于普通报表工具的核心自包含Self-contained单文件、完全离线——图表是内联 SVG无 CDN 与任何外部请求纯数据Data-only命令只读渲染从不写追踪器或归档幂等Idempotent重复运行在同一路径覆盖旧报告无累积稀疏数据优雅降级Graceful on sparse data行数很少时如框架刚起步阶段图表依然正确渲染小 N表格是主要价值载体不得因为 N 小而隐藏图表不虚构No fabrication报告中的每个数字都直接来自 CSV 或 outcome 文件缺失字段绝不推断或估算。工程保障测试如何锁死这份契约/html-report的行为由 test_html_report_command.py 多角度锁定任何改动破坏契约都会在 CI 中失败命令文件本身文件必须存在、首行必须是# /html-report对应tools/lint_skills.py对全部.claude/commands/*.md的统一要求以# /name标题开头、长度必须超过 100 字符字段同步Step 1 的字段枚举必须与 apply.md 读回的规范头部逐一相等用真实文件反推头部而非硬编码 14 列字符串避免14 列字符串是 15 列头部的子串这种漂移漏检列序表格列必须保证Date紧邻Deadline在前统计口径漏斗必须依据合并的outcome.md阶段勾选框而非当前状态拒绝率必须显式排除offer_declined与withdrawnGit 忽略.gitignore必须包含reports/个人生成产出不入库Lint 集成在装有 PyYAML 的环境下python tools/lint_skills.py必须对真实仓库返回 0 且输出含OK——命令文件的新增不能破坏技能/命令文件的整体校验。实践要点小结每次/apply新增投递或/outcome记录结果后重跑/html-report即得最新看板输出默认落在reports/application-dashboard.html看板是单文件可复制到任何机器、用任何浏览器直接打开无需起服务统计口径不可随意改写Drafted 不计入、漏斗看历史阶段而非当前状态、拒绝率不等于 Rejected/Closed 桶若需把看板放进仓库请放reports/之外的位置——该目录已被.gitignore声明为个人产出区。赞分享AI 应用AI 技能【免费下载链接】ai-job-searchThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.项目地址https://gitcode.com/GitHub_Trending/ai/ai-job-search点击查看免费下载相关推荐webpack 5 如何用 module.parser.html.template 对 HTML 入口做模板渲染并追踪模板依赖webpack 5 如何用 module.parser.html.template 对 HTML 入口做模板渲染并追踪模板依赖 如果你的 HTML 页面不是手写前端构建开发工具workerd WPT 更新全流程一条命令升级依赖再给每个失败的测试定性workerd WPT 更新全流程一条命令升级依赖再给每个失败的测试定性 上游 Web Platform TestsWPT发了新版本现在你要把 wor后端语言运行时WebAssembly使用 clidash 为 NanoClaw 搭建零依赖、只读的 CLI 衍生 Web 仪表盘使用 clidash 为 NanoClaw 搭建零依赖、只读的 CLI 衍生 Web 仪表盘 clidash 是随 NanoClaw 技能仓库一起分发的轻量级只人工智能AI 应用AI AgentAgent 沙箱交互助手上一篇Claude Desktop for Linux 补丁档案getHostPlatform Linux 分支补丁的设计、演化与退役下一篇go-chi/cors 中间件实战为 Chi 路由器构建安全、可调试的 CORS 跨域请求处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表