変更履歴
GitHubすべての注目すべき変更をリリースごとに記録しています。同じファイルがリポジトリに収録されており、19言語すべてに翻訳されています。
[1.116.0] — 2026-07-06
使用量メーターの作り直し + 初のE2Eウィジェットテスト。 AI使用量メーター(v1.114.0)を正しく固定しました:左サイドバーの下部に固定され(サイドバー全幅、同じ表面)、自身の高さ分だけサイドバー下部に余白を確保してメニューが決して隠れません — ナビとバージョンフッターは常にその上をスクロールします。リアルタイム更新(15秒間隔 + タブフォーカス + ルート変更)で、各ウィンドウ行は常に100%の「割合」ではなく実際の**<トークン> · <推定コスト>(バーは30日ウィンドウ基準)を表示します。さらに、CVインポーターの恒久的な typeof バリアが、繰り返されるCodeQLの型混同の誤検知を根本で閉じ、新しいPlaywrightのE2Eテスト**が2つの常駐ウィジェットを実ブラウザで検証します。
public/js/lib/usage-hud.js+app.css、server/lib/cv-import.mjs。テスト:tests/playwright-widgets.mjs(2 E2E)+tests/usage-hud.test.mjs(10)。ヘルプ§6を×16拡張。
新規: なし。
[1.115.0] — 2026-07-06
デザインの磨き込み(保守的、コーラルのブランドは維持)。 共有デザインシステムへの軽い洗練パス — 構造変更なし、パレット変更なし。ダッシュボードのメトリクスカードはホバー時にわずかに浮き上がり、コーラルの枠線を帯びます(クイックアクションタイルと同じ)。コンテンツカードもわずかに浮きます。primary / dark / danger ボタンは静止時の影と穏やかなホバーリフトで奥行きを得ます。大きな数字は tabular-nums で揃います。インタラクティブなコントロールは2pxのキーボードリングの背後に柔らかなコーラルのフォーカスハローを受け取ります。すべてのモーションは prefers-reduced-motion を尊重し、ハローはコントロールに限定されます — グローバルな *:focus-visible ではありません。
- CSSのみ(
public/css/app.css)。マークアップ・i18n・ルート・CSPの変更なし。テスト:tests/design-polish-v1115.test.mjs(5)。Playwrightでライブ検証。
新規: なし。
[1.114.0] — 2026-07-06
サイドバーのAI使用量・コストメーター(左下)。 コンパクトな使用量セクションが、すべてのページのサイドバー下部に表示されます(サイドバーがなければ左下の固定カード、RTLでは右下)。24h / 7d / 30d の各ウィンドウのLLMトークン使用量を <トークン> · <割合%>(全期間に対する割合)で緑のメーターバーとともに表示し、24時間の推定コストのフッターを添えます。データは data/llm-usage.jsonl の読み取り専用 GET /api/usage 集計(ローカルのみ)で、#/usage ページと同じソースです。コストは推定であり、手動モードの実行は無料でカウントされません。折りたたみ可能 — ヘッダーで切り替え、状態は保持されます。
- 新しいクライアントウィジェット
public/js/lib/usage-hud.jsをindex.htmlから読み込み、バージョンフッターの上のサイドバーにマウント(固定コーナーのフォールバック)。CSP安全、テーマ対応 + RTLミラー。新しいサーバールートなし。テスト:tests/usage-hud.test.mjs(8)。新しいi18nキー3件×16。
新規: なし。
[1.113.0] — 2026-07-06
すべてのページに浮かぶ「ヘルプに質問」アシスタント。 グラデーションのロボットチャットボタンが、すべてのページの右下(RTLでは左下)に浮かびます。クリックすると、あなたの言語のアプリ内ヘルプガイドのみに基づいて使い方の質問に答えるコンパクトなチャットが開きます — #/docs-assistant ページと同じエンドポイント(POST /api/docs-assistant/ask)なので、CV・プロフィール・トラッカーは読みません。LLMキーがあればライブ、なければすぐ実行できるプロンプト。ヘッダーにはロボットアバター + オンライン状態、スターターチップでよくある質問を入力、Escまたは外側クリックで閉じ、#/docs-assistant ページでは非表示。
- 新しいクライアントウィジェット
public/js/lib/docs-fab.jsをindex.htmlからグローバルにマウント。CSP安全。app.cssにテーマ対応 + RTLミラーのスタイル。新しいサーバールートなし。テスト:tests/docs-fab.test.mjs(8)。新しいi18nキー6件×16。ヘルプ§1をその場で拡張。
新規: なし。
[1.112.0] — 2026-07-06
ドキュメントとQAの統合。 ユーザーに見えるコード変更なし。SDD規約ドキュメント(docs/sdd/CONVENTIONS.md)を現在の30ルートモジュール(以前は24)と現在のテスト基準に更新し、全プロジェクト確定QAプロンプト(qa/QA-REGRESSION-PROMPT.md)を統合しました — リリース手順を最新化(v1.111、parentVersion 1.17.0、リリーストリガー公開)、§14追加表を修正(Scan除外をv1.109.0に再ラベル)し、v1.111のCodeQLクローズアウトを追加 — 全機能の単一リグレッションプロンプトとして単独で成立します。過大アップロード分岐のカバレッジテストを1件追加。
新規: なし。
[1.111.0] — 2026-07-06
セキュリティ — CodeQLバックログの解消。 残る静的解析の指摘を握りつぶすのではなく原因箇所で閉じる、多層防御の強化3件。stripDangerousMarkdown は 途中で切れた 危険タグの開始(<script/<iframe/… で終わるペイロード)の < をエスケープするようになり、出力に生きた危険タグが残らないことを保証します。CVインポートはアップロードされたバッファのサイズを明示的な Number() 変換で読み取ります — 型混同のバリア。モードのロール行は、保存された関数ではなく String.replace で補間されるテンプレート文字列になり、動的ディスパッチ呼び出しを完全に排除しました。ユーザーに見える挙動の変化はありません。
server/lib/security.mjs、server/lib/cv-import.mjs、server/lib/prompts.mjs。テスト:tests/security-hardening-v1111.test.mjs(7)+ v1108ガードテスト更新。i18n/ヘルプ/ルート変更なし。
新規: なし。
[1.110.0] — 2026-07-06
ドキュメント & QA 更新(全言語)。 コード変更なし。プロジェクト全体のQAプロンプトがv1.109.0に更新され、v1.98→v1.109を扱う新§14が追加、UX監査とデザインエクスポートのプロンプトが現在の画面群を反映。v1.100–v1.109で追加された全ヘルプ段落が全16言語に翻訳されました。
新規: なし.
[1.109.0] — 2026-07-06
Scanの除外フィルター + パイプライン概要(Webレイアウトパリティ)。 #/scanで検索ボックスがカンマをORとして扱い(「探す役割」)、新しい除外フィールドは会社/役割/場所にカンマ区切りの語(例: senior, staff)を含む行を隠します。両方とも保存済み検索に記憶されます。#/pipelineにはコンパクトな概要ストリップがパイプラインを一目で表示 — 受信 N、追跡 N、トラッカーの Applied / Responded / Interview / Offer の数、各チップは #/tracker にリンク。
- クライアントのみ(新ルート/書き込みなし)。
public/js/views/scan.js+public/js/views/pipeline.js。テスト:tests/scan-pipeline-ui-v1109.test.mjs(2)。新しいi18nキー4件×16。ヘルプ§7 + §8をその場で拡張。
新規: なし。
[1.108.0] — 2026-07-06
セキュリティ強化(CodeQLトリアージ第2弾)。 さらに軽微な3件を修正: モードプロンプトビルダーがロケールの役割行を自身のキー + typeof === functionで解決し、改ざんされたロケールがプロトタイプメソッドへディスパッチできないようにし(unvalidated-dynamic-method-call);PDFファイル名スラッグを正規表現の前に200文字に制限し、全ハイフン入力がバックトラックしないようにし(多項式ReDoS);ドキュメントインポートが配列のfilename(繰り返しヘッダー)を文字列に強制変換します(type-confusion)。有効な入力に対する挙動変化なし。
server/lib/prompts.mjs、server/lib/routes/runners.mjs、server/lib/cv-import.mjs+tests/security-hardening-v1108.test.mjs(3)。v1.106–v1.108で静的解析のバックログは167から約14に減り、真にセキュリティ関連の指摘はすべて修正、残り(ガード/サニタイズ済みの誤検知 + ノートレベルのlint)は根拠付きで却下。
新規: なし。
[1.107.0] — 2026-07-06
サニタイザー強化(保存時XSSの多層防御)。 stripDangerousMarkdown — 保存済みの履歴書/求人マークダウン内の危険なHTMLを無害化し、描画時エスケープのクライアントを迂回する消費者も安全にする — が、タグ除去を不動点まで(変化がなくなるまで反復)実行し、除去がペイロードを再構成する場合(例: <scr<script></script>ipt>)を捕捉し、末尾にゴミが付いたscript/styleなどの終了タグ(</script foo>)と閉じられていない実行オープナー(<script …>)を除去します。有効なマークダウンの挙動は変わらず、より多く除去するだけです。
server/lib/security.mjs: 不動点ループ(8回制限)+[^>]*>終了タグパターン + 未クローズオープナー除去。tests/cv-xss-bypasses.test.mjsに回帰ケース+3。権威あるXSS境界は依然として出力エスケープ(UI.md)であり、これは保存時保証を強化し、対応するCodeQLの指摘を解消します。
新規: なし。
[1.106.0] — 2026-07-06
セキュリティ強化(CodeQLトリアージ)。 静的解析のバックログを精査し、実際の(軽微だが)3件を修正しました: ルート描画のエラー経路がエラーメッセージをDOMに到達する前にエスケープするようになり(サーバーエラーがユーザー入力を反映しうるため、信頼できないものとして扱う — XSS境界)、プロフィール/設定のプロパティ書き込みが**__proto__ / constructor / prototype キーを拒否**します(念のためのプロトタイプ汚染ガード — キーは固定フィールド仕様から来るもので、生のリクエスト入力ではない)。残りのアラートの大半は、スキャナーの正当な data/* の読み書きや、既に独自レートリミッターを備えたルートに対する誤検知で、根拠付きで却下しました。
public/js/router.jsはinnerHTMLの前にUI.escapeHtmlでerr.messageをエスケープ;server/lib/routes/content.mjsとserver/lib/routes/config.mjsはプロトタイプキーをガード。有効な入力に対する挙動変化なし。テスト:tests/security-hardening-v1106.test.mjs(3)。新しいi18nキーなし。
新規: なし。
[1.105.0] — 2026-07-06
AI使用量とコストのページ。 新しいAI使用量ページ(サイドバー、ヘルスの隣)は、ライブのAI生成 — 評価・レポート・チャット — に費やしたトークンを、過去24時間・7日・30日・全期間にわたってプロバイダーごとに表示し、推定USDコストを併記します。すべてのライブ呼び出しは小さな {provider, in, out} レコードを data/llm-usage.jsonl に追加します(どこにも送信されません)。キーなしの実行(手動モード)はコストがかからず、記録されません。
- 新ルートモジュール(30番目)
server/lib/routes/usage.mjs—GET /api/usage(読み取り専用の集計) +server/lib/llm-usage.mjs(recordUsageがAnthropic/OpenAI/Geminiの使用量形式を正規化してbest-effortで追加、readUsage/aggregateが24h/7d/30d/全期間の窓 × プロバイダーで集計) +server/lib/llm-pricing.mjs(編集可能なプロバイダーごとの$/1Mトークン価格表 — トークンは正確、ドルは概算定価でプランに合わせて修正可能、請求されない)。記録はディスパッチ地点(runActiveProvider+routes/llm.mjs)にフックされます。 - 新ビュー
public/js/views/usage.js(#/usage、期間タブ)。テスト:tests/usage-routes.test.mjs。新しいi18nキー17件×16(usage.*+nav.usage)。ヘルプ§6をその場で拡張。
新規: server/lib/routes/usage.mjs; server/lib/llm-usage.mjs; server/lib/llm-pricing.mjs; public/js/views/usage.js.
[1.104.0] — 2026-07-06
スキャン表の会社ロゴ(プライバシー保護)。 アプリ設定の新しい外観トグル — スキャン表に会社ロゴを表示(既定オフ) — が #/scan で会社名の隣にロゴを描画します。ロゴは会社自身のドメインから取得したファビコンで、サーバー側でプロキシされます(GET /api/logo)。そのためサードパーティのロゴサービスがあなたの見ている雇用主を知ることはありません。共有求人ボード(Greenhouse、Lever、Ashby など)の掲載はボードのアイコンではなく色付きの文字バッジを表示し、読み込みに失敗したロゴも同じバッジにフォールバックします。
- 新ルートモジュール(29番目)
server/lib/routes/logos.mjs—GET /api/logo?domain=。ドメインを検証し(スキーム/パス/ループバックなし)、SSRF安全なsafeGet(新しいbinaryモードが生バイト + content-type を返す。DNSピン留め・リダイレクト検証・サイズ上限は不変)で/favicon.icoを取得し、HTMLエラーページを画像として提供しないよう画像マジックのスニッフィングを行い、ヒットとミスをメモリLRUにキャッシュし、ディスクには何も書き込みません。 - 新クライアントライブラリ
public/js/lib/company-logo.js(window.CompanyLogo): localStorageフラグで既定オフ。共有ATSホストはスキップして決定的な文字アバターを使用。CSP安全なimg.onerrorフォールバック。テスト:tests/logo-routes.test.mjs。新しいi18nキー5件×16(appear.*)。ヘルプ§2をその場で拡張。
新規: server/lib/routes/logos.mjs; public/js/lib/company-logo.js.
[1.103.0] — 2026-07-06
設定: 「AI CLIツール」 — 何がインストールされているか。 career-opsはClaude Codeベースですが、オープンなスキル標準の任意のエージェントCLIで動作します。アプリ設定(#/config)の新しいAI CLIツールタブは、Claude Code、Codex、Gemini CLI、OpenCode、GitHub Copilot CLI、Qwen、Antigravityのうち、サーバーを実行しているマシンに何がインストールされ、そのパスがどこかを表示します。これは読み取り専用のPATHスキャンです: 各バイナリの存在を確認するだけで決して実行せず(--versionなし、実行なし)、何も書き込まず、ユーザーデータに触れません。
- 新ルートモジュール(28番目)
server/lib/routes/cli-detect.mjs—GET /api/cli-detect。検出は固定7件の許可リストからprocess.env.PATHを通じてバイナリのパスを解決します(Windowsの.cmd/.exe/.batシム、POSIXの実行ビット)。PATH上の悪意あるファイルがこのルートで実行されることは決してありません。 public/js/views/config.jsの新しい「AI CLIツール」タブ(遅延読み込み、#/config?tab=cliでディープリンク)。テスト:tests/cli-detect-routes.test.mjs。新しいi18nキー8件×16(cli.*+config.tabCli)。ヘルプ§2をその場で拡張。
新規: server/lib/routes/cli-detect.mjs.
[1.102.0] — 2026-07-05
「ガイドに質問」 — アプリ内ヘルプガイドに基づくチャット。 新しいガイドに質問 💬ページ(サイドバー、ヘルプの下): 「求人ポータルはどうスキャンしますか?」のような質問を入力すると、あなたの言語のアプリ内ヘルプガイドのみから回答が得られます — 使用したセクションを表示し、あなたの履歴書・プロフィール・求職活動は一切読み取りません。あなたのことではなく、アプリの使い方についてです。LLMキーがあればライブ回答、なければ関連するヘルプセクションが既に入ったすぐ実行できるプロンプトを渡します。
- 新ルートモジュール(27番目)
server/lib/routes/docs-assistant.mjs—POST /api/docs-assistant/ask。依存関係なしの検索: あなたの言語のヘルプ文書を##セクションに分割し、質問とのキーワード重複でスコア付け — 上位セクションをインライン化し、モデルはそこから回答するかガイドが扱っていないと述べます(機能/ルートの捏造なし)。共有プロバイダーカスケード、手動フォールバック、レート制限、書き込みなし、ユーザーデータを読みません。 - 新ビュー
public/js/views/docs-assistant.js。テスト:tests/docs-assistant-routes.test.mjs。新しいi18nキー14件×16(docs.*+nav.docsAssistant)。ヘルプ§1をその場で拡張。
新規: server/lib/routes/docs-assistant.mjs; public/js/views/docs-assistant.js.
[1.101.0] — 2026-07-05
CV Studio: 特定の求人に合わせて履歴書を最適化し、カバーレターを作成 — リクルーターのチェックリストでゲート。 #/cv-studioに新しい求人に合わせて最適化カード: 求人内容(任意で目標の役割/ヘッドライン)を貼り付けると、CV Studioがその求人に合わせた履歴書と対応するカバーレターを作成し、渡す前に両方をチェックリストゲートに通します — errorはブロック(結果を見る前に修正)、warnは助言。この仕組みはキャリアコーチングの実践を汎用ルールに蒸留したものです — リクルーターは数秒で読むため、関連経験は上に、ヘッドラインは求人の役割に一致、成果には具体的な数値、カバーレターは「要件↔あなたの合致する事実」という単一のブリッジを持つ短いティーザー。あなた自身の履歴書・プロフィール・ツーページャーのみに基づき決して捏造しません — 企業・役割・経歴をハードコードしません。
- 新エンドポイント
POST /api/cv-studio/tailor(既存のcv-studioモジュールを拡張 — 27番目のモジュールではない):buildTailorPrompt+ 汎用のTAILOR_INSTRUCTIONSゲート、bundleProjectContextに基づき、共有プロバイダーカスケード、キーがなければ手動プロンプト、レート制限、書き込みなし。結果は共有のreport-export.jsバーでMarkdown / PDF / DOCX にエクスポート。 - テスト:
tests/cv-studio-routes.test.mjsに+3。新しいi18nキー10件×16(cvs.tailor*)。汎用リファレンスdocs/prompts/resume-cover.md。ヘルプ§24をその場で拡張。
新規: docs/prompts/resume-cover.md.
[1.100.0] — 2026-07-05
ツーページャー: 履歴書からのAI自動入力+プレビュー+PDF/DOCX/Markdownエクスポート。 ツーページャー(#/two-pager)は次の役割に本当に望むものを記録しますが、これまでは各項目を手入力するかプロンプトを別ツールにコピーする必要がありました。今回、✨ AI入力アシスタントが設定済みプロバイダーでライブ実行されます — 履歴書+プロフィールのみを読み込み(bundleProjectContext、捏造なし)、すべての項目(私は誰か/好きなこと/必須条件/嫌いなこと/絶対NG/譲れない点/目標環境)を下書きしてフォームに入力し、確認・編集・保存できます。APIキーがなければ従来どおりプロンプトコピーのモーダルにフォールバックします。新しい**👁 プレビューとエクスポートボタンはツーページャーを整形済み文書として描画し、.mdをダウンロード/PDFで保存/DOCXで保存/コピー**のバーを表示します。
- 依存関係なしの
.docxエクスポート。 新規server/lib/docx.mjsが最小限だが有効なOffice Open XML.docx(4つのOOXMLパートのDEFLATE ZIP、エントリごとにCRC-32)を生成します — 新しいランタイム依存なし(依存はexpress+js-yamlのまま)。新ルートPOST /api/export/docx(server/lib/routes/export.mjs、26番目のルートモジュール。ステートレス、200 KB制限、書き込み・LLM・URL fetchなし)。共有のpublic/js/lib/report-export.jsに統合したため、市場レポート、キャリアプラン、キャリアオリエンテーションのレポートもDOCXエクスポートに対応します。 - ライブ自動入力は共有プロバイダーカスケード(
runActiveProvider/providerAvailable)を使用し、返されたYAMLはパースされて制限付きツーページャー形状(parseYamlFields+normalizeTwoPager)に強制変換されます — 不明なキーは破棄、配列/文字列は上限あり。手動モードは維持。 - テスト:
tests/export-routes.test.mjs。新しいi18nキー4件×16(export.saveDocx、twoPager.preview、twoPager.aiFilling、twoPager.aiFilled)。
新規: server/lib/docx.mjs; server/lib/routes/export.mjs.
[1.99.0] — 2026-07-05
ポータル状態ページ(#/portals)。スキャナは portals.yml の会社群を監視します。ATS スラッグが静かに壊れると、その雇用主は以降のすべてのスキャンから静かに消えます。新しい Portals ページは監視中の各社を一覧し、Check portal health で各 careers_url を DNS ピン留めの safeGet(SSRF 安全)で探査し、死んだもの(404 = 静かに除外)を印付けします — 読み取り専用。またレビューに従い v1.98.0 のバグレポーターを強化:エラーリングバッファがネットワークの fetch 失敗を捕捉し、スクラバがラベルなしのプロバイダキーを伏字にします。
新規: server/lib/routes/portals.mjs; public/js/views/portals.js.
[1.98.0] — 2026-07-05
アプリ内バグレポーター(親プロジェクトの web-v0.2.0 Web とのパリティ)。通知ドロワーの 🐞 Report a bug ボタンが、プライバシー下限を守る診断スナップショットを収集します — バージョン、現在の画面、ブラウザ、/api/health のチェック要約、新しいクライアント側リングバッファからの直近 20 件のエラー — さらに決定的な重複排除フィンガープリント(co-web-<base36>)を付け、正確な Markdown を確認させてから、事前入力済みの GitHub Issue を開きます。自動送信は一切なく、CV・プロフィール・回答・求人 URL・キーを決して含みません。新ライブラリ logbuf.js + bug-report.js;11 個の i18n キー ×16;tests/bug-report.test.mjs。
新規: public/js/lib/logbuf.js; public/js/lib/bug-report.js.
[1.97.1] — 2026-07-05
レビュー起点の堅牢化とドキュメントのパリティ(v1.97.0 のフォローアップ)。 AI レビューログを一巡したところ、実際の修正が浮かび上がりました:
fit-score.js(スキャン◎適合バッジ)。salaryFloor()は年額未満のレートをもう偽の年額下限に格上げしません — 「at least 500 EUR/day」「$80/hr」「6000 monthly」は 500k/80k のディールブレーカーではなくnullを返すようになりました。国のマッチングが単語単位(\b…\b)になり、「Germany」が形容詞「German」(あるいは「Nigerian」内の「Nigeria」)にマッチして誤った必須条件-他地域違反を発火させることがなくなりました。tests/fit-score.test.mjsにテスト +3。- ドキュメントのパリティ。 すべてのローカライズ済み README が 16 ロケール を一貫して表示するようになりました — Help 行の件数/一覧(×13)とローカライズセクションの本文 + 「N 個すべてのファイルにキーを追加」ノート(×8)が、まだ v1.85 以前の件数(8/9)のままでした。アプリ内ヘルプ §17 のアダプタ件数は、16 バンドル全体で 46 アダプタ — 英語 41 + ロシア語 5 に修正されました。
適合バッジのヒューリスティック以外に動作変更なし。新しいルート、キー、i18n の追加なし。
[1.97.0] — 2026-07-05
Dassault Systèmes スキャナソース + 3方面の品質スイープ。
- 新しいスキャンソース — Dassault Systèmes(親 career-ops パリティ、#1498)。
server/lib/sources/dassault.mjs+server/lib/portals/adapters/dassault.mjsは、親プロジェクトのゼロトークン Exalead「カード検索」プロバイダ(3ds.com/careers/jobsの背後にある公開フィード)をそのまま反映します。単一のグローバルエンドポイントなので、プロバイダ選択(provider: dassault)または3ds.comホストからの自動検出で、redirect:'error'とともにwww.3ds.comに SSRF ホスト固定されます。XML は DOM なし(<Hit>ごとの<Meta>マップ)で解析され、都市/国はローカライズされたカテゴリ文字列から取得され、求人はその公開 URL が*.3ds.com上にある場合のみ保持されます。レジストリは 46 アダプタ(EN 41 + RU 5)を提供するようになりました。ALL_ADAPTERSの件数、ソート済み id、/api/scan/sourcesの EN セットアサーションが 40 → 41 に引き上げられました。スイートtests/sources-dassault.test.mjs(10 ケース)。 - 親プロジェクトの堅牢性修正を移植。 Avature パーサは 2 つのライブテナントのマークアップ変種(位置インデックスの接尾辞付き
article--result+ クラスなしの JobDetail タイトルアンカー、#1541)を許容するようになりました。Get on Board は0/負のpublished_atを防御します(もう誤った 1970 年の日付はありません)。SuccessFactors は最終ページに上限を設け、MAX_JOBSを超えないようにします(#1528)。 - サーバ監査の修正。
safe-fetchは上限超過のレスポンスでもうハングしません — サイズ上限のパスが、破棄されたストリームが決して発火しない'end'イベントを待つ代わりに、Promise を直接解決するようになりました(大きなページの/api/pipeline/preview+ 自動パイプラインのフェッチを修正)。SSEstream.*のアクティビティログが再び到達可能になりました(/api/stream/チェックが包括的な「GET をスキップ」ガードより上に移動)。 - SPA 監査の修正。
#/statsタブスイッチャーが非同期レンダーの競合を防御します — 遅いタブの結果が、ユーザーがすでに切り替えた新しいタブを上書きできなくなりました。mock interview とネットワーキングの削除確認は、適切なタイトル + 本文を渡すようになりました(もう本文が空のダイアログはありません)。 - 翻訳の修正。 未翻訳の辞書値を修正 — ウクライナ語
config.modes*(Adaptive Framing / Exit Narrative / Location Policy)、ロシア語eval.jdLbl(「Job Description」)、イタリア語dash.quick.contactoSub(「referral」→「segnalazione」)— さらに ru/uk/ja/ko/zh-CN/zh-TW の CHANGELOG で英語の 16 ロケール の定型文をローカライズしました。
新規: server/lib/sources/dassault.mjs; server/lib/portals/adapters/dassault.mjs.
[1.96.0] — 2026-07-04
キャリアの方向性(Epic 27)。 新しい #/orientation ページは「どの方向が実際に自分に合うのか?」に答えます — 職業適性検査で得られるような読み解きですが、アンケートではなく、あなた自身の CV とプロフィールから推測します。プロフィールを生成 をクリックすると、モデルはあなたの 最も適したキャリアベクトル(8 つのアーキタイプ — 機能主義者、管理者、コミュニケーター、スペシャリスト、アナリスト、イノベーター、マネージャー、アントレプレナー — のうちどれが合うか、根拠とともに)、キャリアタイプの傾向、おすすめの職種、CV に結び付いた職業上の強み、働き方の傾向、そして開発の推奨事項を返します。これは あなたの CV がどう読めるかについての AI による振り返りであり — 心理検査ではありません:実績を捏造することはなく、数値スコアを測定されたものであるかのように報告することもありません。Markdown または PDF にエクスポートでき、ディスクには何も書き込まれません。
- 新しいルート
server/lib/routes/orientation.mjs(24 番目のルートモジュール)—POST /api/orientation/generateは共有プロバイダカスケードを通じて CV+プロフィール+ツーページャー+メモリからプロフィールのプロンプトを構築し、コピー&ペーストの手動フォールバックと ファイル書き込みなし を提供します。 - Growth ナビゲーショングループの下で、Markdown/PDF/コピーのために
report-export.jsを再利用します。 - テスト:
tests/orientation-routes.test.mjs(振り返りのフレーミング / 捏造されたスコアなし、CV/プロフィールをシードにした手動モード)。新しい i18n キー 7 個 ×16 ロケール、ヘルプ §28 ×16。
新規:#/orientation;server/lib/routes/orientation.mjs。
[1.95.0] — 2026-07-04
キャリアプラン(Epic 26)。 新しい #/career-plan ページは、あなたの CV とプロフィールを、具体的でパーソナライズされた成長プランに変えます。期間(6/12/24 か月)と任意の フォーカス を選ぶと、モデルは — あなたの CV、プロフィール、two-pager、メモを読んで — 出発点のスナップショット、強み/成長の SWOT、SMART / OKR / WOOP としての目標、代替の進路、ハード/ソフトスキルの計画、月ごとのロードマップ、進捗管理の方法、落とし穴、そしてサポートの一手を書き出します。あなたの資料が実際に示していることから先を計画し、あなたの経歴について事実を捏造することは決してありません。インラインで編集し、ユーザーレイヤー(config/career-plan.md)に 保存 し、Markdown または PDF に エクスポート できます。
- 新しいルート
server/lib/routes/career-plan.mjs(23 番目のルートモジュール)—GET/PUT /api/career-plan(config/career-plan.mdに書き込み)+POST /api/career-plan/generate(共有プロバイダーカスケード、手動フォールバック、捏造なし)。PATHS.careerPlan。 - 共有ヘルパー
report-export.js(v1.94.0)を Markdown/PDF/コピーに再利用し、新しい 成長 ナビゲーショングループを追加。 - テスト:
tests/career-plan-routes.test.mjs(範囲、GET/PUT のラウンドトリップ、期間を踏まえた CV/プロフィールをシードしたプロンプト)。16 ロケール すべてに 20 個の新規 i18n キー、ヘルプ §27 16 言語すべて。
新規: #/career-plan、server/lib/routes/career-plan.mjs、PATHS.careerPlan。
[1.94.0] — 2026-07-04
統計、刷新(Epic 25)。 #/stats ページは、実際のグラフと大幅に増えたデータを備えた、3 つのタブからなる 統計 セクションになりました。新しい 市場レポート タブは、あなたが選んだ地域と通貨で、あなたのターゲット職種の給与および労働市場分析をモデルに求めます — エグゼクティブサマリー、P10/P25/P75/P90 パーセンタイル付きのグレード別給与、上位の雇用主、需要のあるスキル一覧、福利厚生の頻度、オフィス/ハイブリッド/リモートの内訳、12〜24 か月のトレンド、そして交渉ガイダンス。すべての数値は、スクレイピングしたデータとしてではなく、モデルの知識に基づく方向性の推定値 として明示されます。新しい マイパイプライン タブは、あなた自身のトラッカーをチャート化します: スコア分布、ステータスファネル、上位の企業と職種、時系列の応募、そしてコンバージョン率。元のターゲット職種ビュー(国別の求人/給与 + 保存したスナップショットのトレンド)は 3 つ目のタブに移り、通貨セレクター と 職種別の求人 概要を備えるようになりました。
- どのレポートもエクスポート — 共有ヘルパー
report-export.jsを介して、Markdown または PDF にエクスポートするか、コピーします(Markdown blob のダウンロード。PDF は既存のインライン PDF ランナー経由)。 - 新しいルート
server/lib/routes/market.mjs(22 番目のルートモジュール)—POST /api/stats/marketは、あなたの CV/プロフィール(そのためあなたのターゲット職種を把握しています)、地域、通貨から市場分析プロンプトを構築し、共有プロバイダーカスケードを通じて実行し、キーがなければコピー&ペースト用のプロンプトにフォールバックします。ディスクへの書き込みなし。 - テスト:
tests/market-routes.test.mjs(地域/通貨の範囲、正直さを明示したプロンプト、CV/プロフィールをシードした手動モード)。16 ロケール すべてに 36 個の新規 i18n キー、ヘルプ §26 16 言語すべて。
新規: タブに刷新された #/stats、server/lib/routes/market.mjs、public/js/lib/report-export.js。
[1.93.0] — 2026-07-04
メモリレイヤー(Epic 24)。 新しい #/memory ページには、アシスタントが すべての タスクで念頭に置く、短く編集可能な「私についてこれを覚えておいて」というメモが保存されます:
- 一つのメモをどこでも —
bundleProjectContextにインライン展開されるため、メモはすべての AI リクエスト(評価、模擬面接、ネットワーキング、CV Studio)に すべての プロバイダーを横断して自動的に届きます。一度書けば、すべてを方向づけます。 - 事実ではなく方向づけ — あなたの好みや働き方(トーン、フォーマット、deal-breaker、ペース)を捉えるものであり、あなたの経歴に関する新しい事実の主張は決して含みません — それらは今も CV、プロフィール、two-pager にのみ存在します。ユーザーレイヤーの
config/memory.mdに保存され、更新で上書きされることはありません。 - あなたのデータから提案 —
POST /api/memory/suggestはあなた自身の応募トラッカーから行動パターンを抽出し、あなたがレビューして編集するための箇条書きを下書きします。トラッカーを読むだけで、事実を捏造することは決してなく、ライブ呼び出しも行いません。
新規: server/lib/routes/memory.mjs(21 番目のルートモジュール — GET/PUT /api/memory + POST /api/memory/suggest)、public/js/views/memory.js、PATHS.memory、そして bundleProjectContext に追加された config/memory.md ブロック。16 ロケール すべてに 11 個の新規 i18n キー。テスト: tests/memory-routes.test.mjs。
[1.92.0] — 2026-07-04
CV Studio(Epic 21)。 新しい #/cv-studio ページは、あなたの CV に正直で、ほとんどローカルで動く 3 つのツールを提供します:
- 履歴書診断 — 決定論的な 0–100 のスコアと、各チェックの説明(定量化されたインパクト、弱い動詞、バズワード、長さ、コアセクション、連絡先情報)。純粋なクライアントサイド(
window.CvDiagnostics)— LLM なし、捏造なし、すべての指摘が説明されるので、何を変えるかはあなたが決めます。 - プライバシーマスク — CV をサンプルやスクリーンショットとして共有する前に、PII(メール、電話番号、リンク/ハンドル、住所、任意で名前 → イニシャル)を伏せ字にします。すべてブラウザ内で実行され(
window.CvPrivacy)、何を伏せ字にしたかを正確に報告し、原文を保存することは決してありません。 - Make it human / voice match — 硬い一文や段落を貼り付けると、
voice-dna.mdとwriting-samples/にサーバー側で基づいて、あなたの声で書き直します。厳格なガードレール: 並べ替え・引き締め・声の再構成はできますが、テキストにまだ存在しない事実・指標・実績を持ち込むことは決してありません。共有プロバイダーカスケードを通じてライブ実行するか、キーがなければコピー&ペースト用のプロンプトを返します。
新規: server/lib/routes/cv-studio.mjs(20 番目のルートモジュール — POST /api/cv-studio/humanize)、public/js/views/cv-studio.js、public/js/lib/cv-diagnostics.js、public/js/lib/cv-privacy.js、PATHS.voiceDna + PATHS.writingSamplesDir。16 ロケールすべてに 29 個の新規 i18n キー。テスト: tests/cv-diagnostics.test.mjs、tests/cv-studio-routes.test.mjs。(テンプレートギャラリー、Word エクスポート、求人票 PDF アーカイブは CV Studio の後続作業として追跡されています。)
[1.91.0] — 2026-07-04
ネットワーキングと企業の詳細リサーチ(Epic 16)。 新しい #/networking ページは、企業を面接獲得のための実行可能なプランに変換します。あなたの CV・プロフィール・two-pager に基づいています:
- 企業ドシエ — 企業が何をしているか、引用に値する最近のシグナル、そしてあなたの実際の経歴から引き出した「なぜ自分が合うのか」のフックをまとめた簡潔なブリーフ。
- 誰に連絡すべきか — 3〜5 人のターゲットペルソナ(採用マネージャー、社内リクルーター、チームのシニア IC、温かい/同窓のつながり)と、それぞれを見つけるための具体的な LinkedIn 検索文字列。実在の名前を捏造することは決してありません。
- 最も温かい紹介ルート — あなたの経歴にとって最も現実的な温かい入り口(共通の雇用主/学校/コミュニティ、2 次のつながり、あるいはシグナルの強いコールド DM)とその理由。
- アウトリーチのドラフト — 上位ペルソナ向けの短く具体的なメッセージ。あなたの実際の実証ポイントに基づきます。
- ライブまたは手動 — 任意のキーで共有プロバイダーカスケードを通じてライブ実行するか、コピー&ペースト用のプロンプトを返します(正直なフォールバック、捏造なし)。プランを保存は完成したプランをユーザーレイヤー(
networking/net-{company}-{role}-{date}.md)に永続化し、ページは保存済みプランの一覧・表示・削除を行います。
新規: server/lib/routes/networking.mjs(19 番目のルートモジュール)、public/js/views/networking.js、PATHS.networkingDir。v1.90.0 の server/lib/llm-dispatch.mjs カスケードを再利用します。16 ロケールすべてに 24 個の新規 i18n キー。テスト: tests/networking-routes.test.mjs。
[1.90.0] — 2026-07-04
Mock Interview 2.0(Epic 15)。 新しい #/mock-interview ページは、あなたの CV・プロフィール・two-pager・ストーリーバンクをターン制の面接リハーサルに変えます:
- 対話型の練習 — 目標とする職種(+任意で企業 / JD)を設定すると、面接官が的を絞った質問で始めます。送信した各回答には構造化された返答が返ります:Feedback(強み + STAR+R のギャップ)、Score(
N/5)、そして直前の回答の最も弱い部分を突く Next question。サーバー側であなたの実際の資料に基づいており — 持っていない経験を捏造しません。 - ストーリーバンク対応 —
interview-prep/story-bank.mdがプロンプトにインライン展開され(cv.mdと同じ信頼レベル)、フィードバックがあなた自身の最良のストーリーを指し示せます。 - ライブまたは手動 — プロバイダーキーがあれば、そのターンは共有プロバイダーカスケード(Anthropic → Gemini → OpenAI → Qwen → OpenRouter → GitHub Models)経由でライブ実行されます。キーがなければ、そのままコピー&ペーストできるプロンプトが得られます(誠実なフォールバック、捏造された回答なし)。
- 保存されたセッション — Save transcript をクリックすると、完了した面接がユーザーレイヤー(
interview-prep/mock-{company}-{role}-{date}.md)に保存されます。ページ上で保存済みセッションを一覧表示・開く・削除できます。
新規: server/lib/routes/interview.mjs(18 番目のルートモジュール)、public/js/views/mock-interview.js、server/lib/llm-dispatch.mjs(共有プロバイダーカスケード)、PATHS.storyBank、bundleProjectContext({ extraFiles })。16 ロケール 全体で 30 個の新しい i18n キー。テスト: tests/interview-routes.test.mjs。
[1.89.0] — 2026-07-04
候補者と市場のフィット — two-pager(Epic 14)。 新しい #/two-pager ページで、次の職務に対して あなた自身 が本当に求めるものを書き留められます。Never Search Alone の「Mnookin two-pager」をモデルにしています:
- ガイド付きビルダー — 一人称の「私は誰か」ナラティブ、「ターゲット環境」ノート、そして 5 つのチップリストエディタ: loves、must-haves、hates、deal-breakers、non-negotiables。親プロジェクトのユーザーレイヤー(
config/two-pager.yml)にPUT /api/two-pager経由で保存されます — システム更新で上書きされることはありません。 - AI 入力アシスタント(
POST /api/two-pager/draft)— あなたの CV + プロフィールをインライン化した、そのまま実行可能な Mnookin プロンプトを組み立てます。任意の LLM で実行し、結果を貼り戻してください。使うのはあなた自身の素材だけで、何も捏造しません。 - 求めるものとの適合バッジ —
#/scanの各求人に◎ Nの適合スコア(クライアント側、window.FitScore経由)が表示され、求人の勤務形態・国・最低給与・移転をあなたの two-pager と照合します。設計上、正直です: 求人が照合可能なシグナルを与えない場合、バッジは表示されません(捏造した数値は決して出しません)。deal-breaker 違反は軽い嫌悪より重く扱われます。 - すべての評価に反映 — 保存された two-pager は
bundleProjectContextにインライン化されるため、以降のすべての LLM 評価が、あなたが表明した好みと CV 対 JD のマッチングを合わせて考慮します。
新規: server/lib/routes/two-pager.mjs、public/js/views/two-pager.js、public/js/lib/fit-score.js、PATHS.twoPager。16 ロケールすべてに 27 個の新規 i18n キー。テスト: tests/two-pager-routes.test.mjs、tests/fit-score.test.mjs。
[1.88.0] — 2026-07-04
Issue #29 の仕上げ — スキャンの i18n の抜け + API の衛生。
- 最後まで残っていたハードコードのスキャン文字列をローカライズ(ロードマップ v1.69.4): ソース要約のピル(
N 件の新規 / M 件の一致)、N 件の新規求人トースト、relocバッジがt()を経由するようになりました — 16 ロケールすべてに 4 つの新規キー(scan.pillNew、scan.pillMatching、scan.newOffers、scan.relocBadge)。英語以外のユーザーは、コアのスキャンフローで英語が紛れ込むのを見なくなりました。 X-Powered-Byヘッダーを無効化(ロードマップ v1.69.5):createApp()内のapp.disable('x-powered-by')— サーバーはもう Express を広告しません。(このエピックの残りはすでに出荷済み:parentVersionは release-please のコメントを除去、ライトモードのテーマ切り替え、ルート変更時のモーダル閉じ、レポートの「Score」(rep.score)のローカライズ。)
テスト: tests/scan-i18n-gaps.test.mjs + tests/security-headers.test.mjs の X-Powered-By 不在アサーション。
[1.87.0] — 2026-07-04
認証不要のスキャンプロバイダーを4つ追加(親 career-ops v1.16.0 との同等性)。 スキャナーレジストリが 41 → 45 アダプター(40 EN + 5 RU)に増えました — すべて公開、認証なし、ホスト固定、redirect:'error'(SSRF セーフ)で、それぞれ CI 分離テスト付きです:
- Get on Board (
getonbrd) — ポータル全体の公開 JSON:API(LATAM/リモート技術)、プロバイダー選択、ページネーション対応。server/lib/sources/getonbrd.mjs。 - Amazon (
amazon) —amazon.jobsの公開検索 JSON、ホスト検出またはprovider: amazon、オフセットページネーション。server/lib/sources/amazon.mjs。 - Avature (
avature) — テナントごとの*.avature.netATS、HTML 解析、ホスト検出またはprovider: avature。server/lib/sources/avature.mjs。 - SAP SuccessFactors (
successfactors) — テナントごとの RMK タイルリスト(*.successfactors.eu/.com、jobs2web.com)、HTML 解析。server/lib/sources/successfactors.mjs。
それぞれが sources/<slug>.mjs(自動検出される meta → #/scan ドロップダウン)および ALL_ADAPTERS 内の portals/adapters/<slug>.mjs(2つのレジストリのルール)+ tests/sources-<slug>.test.mjs を同梱します。ALL_ADAPTERS の数とソート済み id・/api/scan/sources の EN セットのアサーションは 36→40 に増え、GET /api/scan/sources は現在 45 件を列挙します。
[1.86.0] — 2026-07-03
ターゲット職種別の統計(#/stats)— あなたのターゲット職種に対する市場の求人・給与統計。 新しい分析ページがプロフィールのターゲット職種(config/profile.yml → ハードコードではない)と最新スキャンの求人を読み取り、職種と国ごとに次を表示します:
- 国別の求人数と国別の給与中央値(USD) — スキャナーがすでに収集している疎なデータからクライアント側で集計されます(
public/js/lib/role-stats.js、window.Countriesを再利用)。任意通貨の給与は明示的に近似の FX テーブルで USD に正規化され、サンプルサイズに関する注意書きが添えられます — 決して捏造されません。 - 職種・国フィルターと手書きのインライン SVG 棒グラフ・トレンドチャート(新規依存なし、CSP セーフ —
addEventListenerのみ)。 - スナップショット保存(
POST /api/stats/snapshot)は現在の集計をdata/role-stats.jsonlに永続化し、トレンドチャート(GET /api/stats/trend)は時系列での求人数を追跡します — 「ダイナミクス」ビュー。誠実なハイブリッド: スナップショットはローカルのスキャンデータから生成され、オンデマンドで更新されます。 - 16 ロケールすべてに完全ローカライズ(新規 i18n キー 26 個)。
新規: server/lib/routes/stats.mjs(16 番目のルートモジュール)、public/js/lib/role-stats.js、public/js/views/stats.js、PATHS.roleStats;テスト role-stats.test.mjs(7)+ stats-routes.test.mjs(5)。
[1.85.0] — 2026-07-03
ドイツ語・イタリア語・トルコ語ロケール(親 career-ops v1.16.0 ロケールパリティ)。 UI が 16 言語で提供されるようになりました — 既存の 13 言語に de 🇩🇪、it 🇮🇹、tr 🇹🇷 が加わります。
- UI 全体の翻訳 —
public/js/lib/locales/i18n-dict.{de,it,tr}.jsで 730 個の i18n キーをすべて翻訳。言語スイッチャーに Deutsch / Italiano / Türkçe が表示され、ブラウザ言語の自動検出がde/it/trを認識します(public/js/lib/i18n.js)。 - アプリ内ヘルプガイド —
docs/help/{de,it,tr}.mdを翻訳(完全な 19 H2 / 75 H3 構造)、GET /api/help/:langで配信されます。 - ドキュメント —
README.{de,it,tr}.mdとCHANGELOG.{de,it,tr}.mdを追加。CHANGELOG のロケールパリティゲートが 15 の非 EN ロケールをカバーするようになりました。 - プロンプトのスキャフォールディング —
server/lib/prompts.mjs(LOCALE_NAMES+SCAFFOLD_STRINGS)を 3 つの新規ロケール向けにローカライズし、LLM の出力が UI 言語に従うようにしました。
すべてのパリティゲート(i18n-locale-files、i18n-coverage、check-changelog-parity、lang-switcher-rtl)を 16 ロケールセットに拡張しました。
[1.84.0] — 2026-06-30
再応募クールダウン + pipeline.md への報酬情報(親 career-ops v1.15.0 パリティ)。 スキャナーの 2 件のアップグレード:
- 再応募クールダウン (#1201): EN スキャンが最近応募した企業の求人をスキップし、結果が新しい求人にフォーカスされます。
config/profile.ymlのre_apply_windows:以下で企業ごとの期間を設定できます(last_apply_date、same_role_days、applied_to: [roles]、省略可能なcross_role_bucket);企業マッチングは句読点非依存 + 単語境界(server/lib/cooldown.mjs)。キーが存在しない場合は無効;スキャンログにCooldown skipped: Nが表示されます。 - pipeline.md への報酬情報 (#1017): スキャンされた求人が給与をオプションの末尾カラム(
url | <salary>)としてdata/pipeline.mdに保存されます。URL は重複排除キーのまま(| comp列は読み込み時に除去)、セルはサニタイズされ(行/列インジェクションなし、数式先頭を無効化)、ベア URL のパイプラインは後方互換性を維持します。
tests/cooldown.test.mjs および pipeline 報酬テストを同梱。ソース数は 41 のまま — いずれもスキャンロジックのアップグレードであり、新しいボードではありません。
[1.83.0] — 2026-06-30
再掲載 / ゴースト求人検出器(親 career-ops v1.15.0 パリティ)。 #/scan に新しい 🔁 再掲載 / ゴースト求人 パネルが追加され、90 日のローリングウィンドウ内で異なる URL に再掲載された企業+職種クラスタを表示します — 古い採用パイプラインやゴースト求人のシグナルです。ファジー職種タイトルマッチャー(server/lib/role-matcher.mjs)と data/scan-history.tsv に対する読み取り専用の検出器(server/lib/detect-reposts.mjs)を基盤とし、GET /api/scan/reposts で公開されます。また:/api/health の parentVersion がセマバーのみを返すようになりました(リリース-プリーズ # x-release-please-version コメントを除去)。tests/detect-reposts.test.mjs を同梱。ソース数は 41 のまま — 再掲載は分析機能であり、新しいボードではありません。
[1.82.0] — 2026-06-30
NoDesk スキャンソース(親 career-ops v1.15.0 パリティ)。 ボード全体の NoDesk リモート求人 RSS フィードが第一級のスキャンソースになりました — provider: nodesk のエントリを追加すると #/scan の Source ドロップダウンに表示されます(合計 41 アダプタ:EN 36 + RU 5)。ホストは nodesk.co に固定し redirect:'error'(SSRF 対策);タイトルは Role at Company で分割(NoDesk にはロケーションタグがないため所在地は空欄のまま);全行リモート。CI 隔離の tests/sources-nodesk.test.mjs スイートを同梱;フルユニットスイート 1523 件グリーン。
[1.81.0] — 2026-06-29
親 career-ops パリティ — 13 件の新規求人ボードスキャンソース。 Fighter90/career-ops main の最新プロバイダバッチをインプロセススキャナに移植します。ボード全体の公開 API(プロバイダ選択): Arbeitnow、Himalayas、Jobicy、Landing.jobs、4 Day Week、The Muse、The Hub、Jobspresso(RSS)、Hacker News “Who is hiring?”(Algolia 2 ステップ)。ポーランドのボード(ホストまたは provider: 検出): JustJoin.it および NoFluffJobs(POST 検索)。テナント別 ATS(careers_url から自動検出): Pinpoint(<slug>.pinpointhq.com/postings.json)および Rippling(ats.rippling.com/<slug> → api.rippling.com ボード)。すべてのソースは redirect:'error' でホスト固定(SSRF 対策)され、#/scan の Source ドロップダウンで選択できます — レジストリは 40 スキャナアダプタ(EN 35 + RU 5)を提供します。ソースごとの CI 隔離テストスイート 13 件を追加; フルユニットスイート 1513 件グリーン。
[1.80.0] — 2026-06-28
スキャンの 5 つの強化(job-crawler のアイデアを再実装)。 (1) Teamtailor ソース — <slug>.teamtailor.com のテナント別キャリアサイトを公開 /jobs.rss フィード経由で取得。careers_url から自動検出(ホスト固定 + redirect:'error')。レジストリは 27 アダプタ に。(2) ソースのクォランティン — 恒久的な 404/410 を返したソースを data/scan-quarantine.json に記録し、以後のスキャンでスキップ(自己修復:14 日後に再試行)。(3) ソースごとの上限 — #/scan の任意フィールドで各ボードの件数を制限(既定は ∞)。(4) 投稿期間 — クライアント側の経過フィルタ(24時間 / 7日 / 30日)。(5) 保存した検索 + ★ お気に入り — フィルタセットに名前を付けて再利用し、求人にスターを付与。localStorage に防御的バリデーション付きで保存(壊れたキャッシュはクリーンにリセット)。結果キャッシュはスキャン前にリセットされ、ライブで再充填されます。
[1.79.0] — 2026-06-28
WeWorkRemotely スキャンソース(親 career-ops v1.14.0 パリティ)。 We Work Remotely のボード全体のリモート求人 RSS フィードが第一級のスキャンソースになりました — provider: weworkremotely のエントリを追加すると #/scan の Source ドロップダウンに表示されます(合計 26 アダプタ)。ホストは weworkremotely.com に固定し redirect:'error'(SSRF 対策)。タイトルは Company: Role で分割。さらに title_filter のキーワードは長さチェックの前にトリムされます(parent #1261)。
[1.78.2] — 2026-06-27
i18n と UX の強化(v1.78.1 のフォローアップ)。 ロゴのアクセシブル名が 13 言語すべてでローカライズされました(nav.logoHome)。すでに #/scan にいる状態でのグローバル検索 Enter は強制再レンダーし、入力済みの語が失われません(同一ルートガード)。health.title がポーランド語(Kondycja)とデンマーク語(Systemtilstand)に翻訳されました(以前は英語のまま)。テスト 1235 → 1238。
[1.78.1] — 2026-06-27
Scan の UX 修正。 #/scan の結果テーブルが、スキャン中もライブで自動更新され、完了後にもう一度更新されます(手動リロード不要)。トップバーのグローバル検索は Enter ヒントを表示し、URL でないクエリでは検索欄を埋めた状態で #/scan へ遷移します(以前は #/tracker)。ロゴはダッシュボード(ホーム)へのリンクになりました。
[1.78.0] — 2026-06-27
Scan ページに地域フィルター — 国ごと(国旗付き)に求人を絞り込み。 #/scan の新しい 国 ドロップダウンは、結果から検出した各国(国旗絵文字+件数)を一覧表示し、特定の国に紐づく求人だけに絞れます。Remote/Hybrid/Onsite の勤務形態フィルターと併用でき、国に紐づく仕事もリモートも探せます。新しい countries.js ヘルパーが求人のフリーテキストの所在地(国名・別名・約100の主要都市)を ISO 国コード+国旗にマッピング。検出は保守的で、決して推測しません。
[1.77.0] — 2026-06-27
デンマーク語 (Dansk) を 13 番目の UI 言語として追加。 UI、アプリ内ヘルプガイド(19 H2 / 75 H3)、README、CHANGELOG をデンマーク語に完全翻訳。デンマーク語は国旗付き言語ピッカーに追加され、i18n の仕組み(アセンブラ、監査、パリティゲート、スナップショット)は 13 ロケールに対応しました。
[1.76.0] — 2026-06-26
親 career-ops v1.13.0 とのパリティ — 新規ソース6件、スキャナ堅牢化、結果テーブルの上限撤廃。
追加
- テナント別ATSソース6件 — BambooHR、Breezy HR、Comeet、Personio、Recruitee、SolidJobs。
careers_urlのホストから自動検出(Comeet は完全なapi:が必要)。各ホストはアンカー付き正規表現 +redirect:'error'で固定(SSRF対策)。#/scanの Source ドロップダウンで選択可能 — レジストリは 25 アダプタ(EN 20 + RU 5)に。Personio の XML フィード用にfetchTextヘルパーを追加。 trust_filter— 任意の信頼スコア(0–100、レベル high/medium/low、フラグ)。注釈のみ。high未満の行は#/scanに言語非依存の ⚠ バッジを表示。求人は決して除外しない。- Arbeitsagentur
remoteMatch+remoteMaxPages— 設定駆動のリモート判定:title、filter(サーバー側homeoffice=nv_true+ ページング)、off。
変更
- スキャン結果の上限なし。 表示上限
MAX_STORED_RESULTS(2000)を撤廃 — 一致した求人をすべて保存し、#/scanテーブルでページ送り(200件/ページ)。 - タイトルフィルタの堅牢化 — 短い略語(COO、SDR…)は単語境界で一致;不正な
title_filter設定でスキャンが落ちない。ATS と地域スキャナの両方。
テスト
- +32 ケース(1190 → 1222):
sources-ats-providers、title-filter、arbeitsagentur-remote、trust-validator、書き直したscan-result-cap「上限なし」ガード。
[1.75.2] — 2026-06-19
docs: v1.75.0 のスキャナ集約サイトに対する全12ロケールでの完全なドキュメントパリティ。 コード変更なし — v1.75.0 で着地した7件のソースにユーザー向けドキュメントを揃えます:
- ヘルプガイド(12ロケール)。 §5 に
content_filterブロック(説明/スニペットのキーワードゲーティング、location_filterの兄弟)と集約サイトに関するノートが追加されます。§7 はワンクリックスキャンの一巡と Source ドロップダウンの完全な列挙に7件の新規ソースを記載します。§17 のアダプタ数が古い “11 adapters” から “19 adapters — 14 English + 5 Russian” へ訂正されます。##/###の見出しは追加していないため、ゲートされた 19 H2 / 75 H3 構造は変更されません。 - README(9件の完全ロケール)。 スキャンソースの下に新しい “Aggregator boards (v1.75.0)” の箇条書きが追加され、リリースバッジが v1.75.2 に更新されます。(省略版の pl/uk/ar README にはソースごとのリストがなく、その箇所は意図的に手を付けていません。)
- リファレンスドキュメント。
docs/portals-examples.mdに7件すべての正確なprovider:/<provider>:設定ブロックを備えたコピー&ペースト用 “Aggregator boards” セクションが追加されます。docs/PROJECT.mdは 19 adapters に更新されます。docs/sdd/CONVENTIONS.mdは、2つのレジストリの区別(ドロップダウン用sources/registry.mjs対フェッチ用portals/registry.mjs)、opts.companyとして通されるprovider:ベースの集約サイト選択、スキャン書き込みのサニタイザ(scan-sanitize.mjs)、および v1.75.1 のテスト数(1190)を文書化します。 - QA。
qa/QA-REGRESSION-PROMPT-v1.75.2-FULL.mdを追加 — v1.75.x のスキャン集約サイトサイクル向けに刷新した、全面的なリリースゲートドライバ。
[1.75.1] — 2026-06-19
fix(scan): v1.75.0 の構成駆動ソースに対する堅牢性の仕上げ。 リリース後レビューから得られた 3 つの小さな強化修正です(正常なスキャンでは動作変更なし):
- Abort を考慮したページネーション遅延。 Glints(300 ms)および Jobstreet/SEEK(200 ms)のページ間の待機は、
server/lib/http-json.mjsの新しいdelay(ms, signal)ヘルパーを介して、スキャンのAbortSignalが発火すると即座に解決されるようになりました。これにより、切断されたクライアントがページネーション中のスキャンを余分な待機分だけ占有し続けることができなくなります。 - 説明的な非 JSON エラー。
fetchJsonは、非 JSON の2xxボディ(例: ステータス 200 で配信される HTML メンテナンスページ)を、むき出しのSyntaxErrorを表面化させる代わりにnon-JSON 2xx response from <url>としてラップするようになりました。これにより、スキャナーのソースごとのエラーログが不正な挙動のエンドポイントを明示します。 - より強力なスキャン書き込みの正規化。
normalizeScanScalarは、\r \n \tに加えて、垂直タブ、フォームフィード、および Unicode の行/段落区切り(\v \f U+2028 U+2029)も折りたたむようになりました — 厳密な上位集合であり、スプレッドシートやビューアが尊重しうるレコード/行区切りがscan-history.tsvに生き残ることはありません。
[1.75.0] — 2026-06-19
feat(scan): 親 career-ops v1.12.0 のパリティを移植 — 新規求人ソース7件、コンテンツフィルタリング、セキュリティ/品質修正。 web-ui は独自のインプロセススキャナを実行し(親の scan.mjs へシェルアウトしない)、そのため親 v1.12.0 のプロバイダおよびスキャン変更は自動的には流れ込みません — 本リリースでは、適用可能なものを web-ui のアダプタ契約に沿って再実装します。
- 新規スキャナソース7件。 ボード横断のリモート集約サイト3件 — RemoteOK、Remotive、Working Nomads — は自動検出される
server/lib/sources/*.mjsパターンに収まります(provider: remoteok/remotive/workingnomadsで選択)。設定駆動の地域集約サイト4件 — IBM careers、Arbeitsagentur(ドイツ連邦雇用庁)、Glints(東南アジア)、Jobstreet / SEEK — はエントリごとの<provider>:設定ブロックを読み取ります。en-scanner は解決済みの企業エントリを各フェッチャーまで通すようになり、フェッチャーがそれを読めるようになりました。7件すべてが#/scanのソースドロップダウンに自動的に表示されます。 content_filter(親 #974)。 求人をその説明/スニペットのテキストでゲートする任意のportals.ymlブロック(positive/negativeキーワードリスト) —location_filterのセマンティクスを踏襲し、説明のない求人は常に通過します。EN と RU の両スキャナに組み込まれました。- スキャン書き込みの堅牢化(親 #1098)。 外部フィードのメタデータは
data/scan-history.tsvおよびdata/pipeline.mdに書き込まれる前にサニタイズされるようになりました: 制御文字は折りたたまれ(企業名/タイトルの改行が TSV 行を注入できなくなりました)、先頭の= + - @はスプレッドシートの数式インジェクションに対して無効化されます。 - Ashby
secondaryLocations(親 #1073)。 Ashby ソースは各セカンダリロケーションの地域ラベルに加えて郵便のaddressLocality/addressCountryをロケーション文字列に畳み込む(重複排除)ようになり、主ラベルが例えば “Canada” と表示される EU 対象の職務がlocation_filterで表面化します。 - 評価レポート形状の検証(親 #819)。
/api/evaluateのインプロセスプロバイダ(Anthropic / OpenAI / Qwen / OpenRouter / GitHub Models)は、不正な形式の A–G /SCORE_SUMMARYレポートを致命的でないwarnings配列としてフラグするようになりました。Gemini 評価パスは親のgemini-eval.mjsから既にこのガードを継承しています。 - docs: Antigravity CLI を12のすべての README のサポート対象アシスタント一覧に追加(Gemini プロバイダにマッピング)。
親の git pull から無償で継承(web-ui はこれらへシェルアウトします): 日本語 CJK PDF フォントのフォールバック(#1053)、ATS セーフな PDF フォント(#1074)、LaTeX CJK ガード(#1054)、tracker/merge/followup/dashboard の修正、および modes/zh 中国語モード(web-ui はモードを動的に列挙します)。
[1.74.3] — 2026-06-18
docs(parent-source): 親 career-ops リポジトリを Fighter90/career-ops フォークに向ける。 web-ui は実際のソースとして使われるすべての箇所でメンテナーのフォークを親プロジェクトとして参照するようになりました: bin/setup.sh インストーラーの CAREER_OPS_REPO クローン既定値、12 個の README にあるすべての git clone /「の上に乗る」/ オンボーディングリンク、そしてエージェントドキュメント(CLAUDE.md、AGENTS.md、GEMINI.md、.github/copilot-instructions.md、docs/)。作者 santifer へのクレジット(および非公式 UI の免責表示)は変更なし — ソース/クローン URL のみ移動しました。tests/sh-files.test.mjs はインストーラーがフォークをクローンすることを検証するようになりました。
[1.74.2] — 2026-06-17
fix(health): #/health と /api/status/providers で GITHUB_MODELS_API_KEY をオプションのチェック項目として表示。 v1.74.0 の GitHub Models プロバイダーは #/config で設定可能でしたが、Health ページに行がなく、keysConfigured プロバイダーサーフェスからも欠落していました。オプションのチェック項目(他の5つのライブ評価プロバイダーと同じ “set / unset (manual mode)” の文言)と github(+ その GITHUB_MODELS_MODEL)を /api/status/providers に追加したため、アクティブプロバイダーのルーティングと Health ページが6つすべてを反映するようになりました。tests/api.test.mjs のヘルス行テストを6つのプロバイダーすべてに拡張しました。
[1.74.1] — 2026-06-17
docs + test: README の「AI アシスタントをインストールする」セクション;Gemini コネクタの完全ブランチカバレッジ。 README にインストール/ログイン一覧表を追加 — Claude Code / Gemini CLI / Codex / Qwen Code / OpenCode / GitHub Copilot CLI のインストールリンク + それぞれの #/config プロバイダーマッピング + 「続行前にログインしてください」(career-ops.org/docs のクイックスタートを反映;web-ui が CLI 不要のスタンドアロン代替手段であることを明確化)。新しい tests/gemini-connector.test.mjs(8 ケース)は runGemini のすべてのブランチをカバー — キーなし、成功、API エラー、空/ブロックされた補完、不正な形式のボディ、タイムアウト、ネットワークエラー、hasGeminiKey — server/lib/gemini.mjs のステートメントを 100% に到達させる。全体カバレッジ: 96% ライン / 88% ブランチ / 96% 関数。スイート 1126 → 1134。
[1.74.0] — 2026-06-17
feat(llm): GitHub Models (Copilot) を第6のプロバイダーとして追加 + 6アシスタントの標準的な整列. career-ops.org/docs には、6つのAIコーディングアシスタントが記載されています — Claude Code, Gemini CLI, Codex, Qwen Code, OpenCode, GitHub Copilot CLI。web-ui はこれら6つすべてをサポートするようになりました: 5つは既存のライブプロバイダー (Anthropic / Gemini / OpenAI / Qwen / OpenRouter) に対応し、GitHub Copilot CLI は専用の GitHub Models コネクター — runGitHubModels (OpenAI-compatible; models スコープを持つ GitHub PAT) を獲得します。これは #/config (GITHUB_MODELS_API_KEY + GITHUB_MODELS_MODEL) で設定可能で、LLM_PROVIDER=github で選択でき、auto 順序では6番目です。ヘルプバンドルと README は標準の6つをリストするようになり (Qwen CLI→Qwen Code に改名; Gemini CLI + GitHub Copilot CLI を追加)、README にはすべての機能が親プロジェクトに追跡できるよう、完全なモード参照とポータルアダプターのリンクテーブルが career-ops.org/docs に追加されます。tests/llm-provider-context.test.mjs はフェッチ境界マトリックスを6つのプロバイダーすべてに拡張し (cv.md + profile.yml インライン + アーティファクト返却)、新しい GITHUB_MODELS_* キーがすべての12のロケール辞書に追加されます。スイート 1125 → 1126。
[1.73.0] — 2026-06-17
feat(llm): 汎用Geminiコネクター + 全プロバイダーにわたって検証済みのCV/プロフィールコンテキスト。 server/lib/gemini.mjs (runGemini) を追加しました — Anthropic / OpenAI互換クライアントと同じ {markdown, usage, error} の形式を返す、外部依存なしのGemini generateContent クライアントです。修正: /api/mode/:slug と /api/deep はこれまで、オファー評価専用の gemini-eval.mjs を通じてプロンプトを処理していたため、Gemini Run live が要求されたアーティファクト(カバーレター、アウトリーチ、ブリーフ)の代わりに評価を返していました。現在は bundleProjectContext とともに runGemini を呼び出すため、他のすべてのプロバイダーと同様に cv.md + config/profile.yml がGeminiにもインラインで埋め込まれ、レターやブリーフが詳細かつパーソナライズされます。新しい tests/llm-provider-context.test.mjs は各プロバイダーのHTTP境界をモックし、5つのプロバイダー(Anthropic / Gemini / OpenAI / Qwen / OpenRouter)すべてが cv.md + profile.yml をインラインで埋め込み、アーティファクトを返すことを検証します(mode + deep + evaluate マトリックス、9ケース)。/api/evaluate はオファー専用の gemini-eval.mjs を維持します。Suite 1116 → 1125。
[1.72.0] — 2026-06-17
feat(modes): Run live が最終成果物を直接返すようになりました(シングルショット出力コントラクト)。 親テンプレート modes/<slug>.md はClaude Codeのインタラクティブセッション向けに書かれており、いくつか(cover、contactoなど)は結果を生成する前に確認の質問のために一時停止します。これにより、WebUIの Run live が成果物ではなくアンケートを出力していました。buildModePrompt は現在、すべてのモードを非インタラクティブな出力コントラクトでラップします: 分析(JD分析、企業ノート、ATSキーワード、プロフィール↔JDのギャップ、トーン/アングルの選択)をサイレントに実行し、テンプレートが通常尋ねるものについては cv.md / config/profile.yml から適切なデフォルト値を選択し、最終成果物のみを出力します — モードごとの «output ONLY {the cover letter / outreach message / …}» リマインダーで締めくくられます。これにより、#/cover で Run live をクリックするとカバーレター自体が返されます。同じ修正がすべての汎用モード(cover、contacto、interview-prep、project、training、followup、patterns)の12ロケール全体に適用されます(成果物はロケールディレクティブによりUI言語で記述されます)。Suite 1103 → 1116。
[1.71.2] — 2026-06-17
docs(i18n): ドキュメント整合性パスを公開します。各 README の “Translations of this guide” ブロックに、11 のサポート言語がすべて列挙されるようになりました(以前は English/Français が省略されたり自己リンクになっていたものがありました)。また、セクション区切り前の空行が復元されました。QA リグレッション プロンプト全体が現在のバージョン名に変更され、ドキュメント(CLAUDE.md、CONVENTIONS、LOCALIZATION、PROJECT-CONTEXT)が現在のバージョンとテスト数(1103)に同期されました。コードや動作の変更はありません — ドキュメントのみの変更のため、ヘルプ/UI の翻訳および 1.70.0–1.71.1 のすべての機能は変更されていません。
[1.71.1] — 2026-06-17
fix(i18n): アプリ内ヘルプガイドが全12言語で完全に翻訳されました。 docs/help/{pl,uk,ar}.md を追加し(それぞれゲート済みの 19 H2 / 75 H3 構造を含む)、#/help が英語へのフォールバックではなくポーランド語・ウクライナ語・アラビア語のネイティブバンドルを提供するようになりました — GET /api/help/{pl,uk,ar} がそれぞれのロケールを返すようになりました。すべてのヘルプゲート(help-ui, help.test, help-ru-config-section, canonical-docs-coverage)に接続されています。また、12言語すべての翻訳リストを完成させました: READMEの «Translations of this guide» ブロック(9つのREADME)、ローカライズされたCHANGELOGの «Translations:» ヘッダー(8ファイル)、そして古くなったドキュメントの数値を更新しました。Suite 1100 → 1103.
[1.71.0] — 2026-06-16
feat(cover): #/cover から直接カバーレターPDFを生成します。 v1.70.0で追加されたcoverモードはレター本文を生成します。結果画面に Generate PDF ボタンが追加され、共有インラインmarkdown→PDFパイプライン(POST /api/stream/pdf/inline → generate-pdf.mjs)を通じてレンダリングされます。これはinterview-prepが使用するのと同じパスです。SPA を離れることなく、レターを作成してPDFを送付できるようになりました。
test/docs: v1.70.0 レビューの堅牢化。 coverモード(許可リスト+プロンプト組み立て)、国旗 <select> スイッチャー+アラビア語RTL(dirFor/<html dir>)、すべてのロケールの top.langLabel、カバーレターPDFの配線、prompts.mjs ロケールディレクティブ+fr/pl/uk/ar のスキャフォールディングについて、CI 分離カバレッジを追加しました。docs/sdd/CONVENTIONS.md および全プロジェクトQAリグレッションプロンプトの古い「全8件」→12ロケール参照を更新しました。
[1.70.0] — 2026-06-16
feat(i18n): 新しいUIの言語として、ポーランド語(pl)、ウクライナ語(uk)、アラビア語(ar、完全なRTL対応)の3言語を追加し、SPAを12ロケールに拡張しました。これは親プロジェクト career-ops の READMEに記載されたすべての言語と一致します。 各新ロケールには697キーの完全な辞書(public/js/lib/locales/i18n-dict.{pl,uk,ar}.js)が含まれており、既存のパリティ / カバレッジ / ラテン文字漏れなし / 個人データなしのテストスイートで検証されています。アラビア語は本格的な右から左へのサポートを追加します: i18n.js はRTLロケールに対して <html dir="rtl"> を設定し、app.css のスコープ付き [dir="rtl"] ブロックはクロム(サイドバー、通知ドロワー、マークダウンテーブル/ブロック引用、インライン間隔)をミラーリングします — LTRロケールはバイト単位で変更されません。新しい top.langLabel キー(×12)がスクリーンリーダー向けにピッカーを命名します。
feat(ui): フラグアイコン付き <select> 言語切り替えが折り返しボタン行を置き換えます。 12ロケールでは、旧来の .lang-btn 行がサイドバーで3行に折り返されていました。ネイティブの <select>(各オプションに国旗絵文字のプレフィックス)はすっきりとスケールし、キーボードおよびスクリーンリーダーに対応しており、CSPに安全です(addEventListener を介した変更ハンドラー、インラインJSなし)。プラットフォームに国旗グリフがない場合は地域文字に降格されるため、言語ラベルが常に主要な識別子となります。
feat(cover): 親プロジェクトのカバーレターモード(career-ops v1.10.0 + v1.11.0 の挨拶文)をSPAに移植します。 汎用モードランナーを基盤として、アプリケーションナビグループの下に新しい #/cover ページを追加: 求人説明 + 企業名/職種 + オプションの挨拶文 → cv.md / modes/_profile.md から生成されたカスタマイズされたレター。サーバーの MODE_ALLOWLIST に cover を追加し、cover.* i18nブロック(×12ロケール)を追加しました。
chore(compat): 親プロジェクト career-ops v1.11.0 を追跡します。 読み取り/書き込みコントラクトが維持されていることを確認しました — data/applications.md は引き続きMarkdownの信頼できる情報源です(v1.11.0のSQLiteトラッカーインデックスは派生キャッシュ)。トラッカーの列は引き続きヘッダーマッピングされています。parentVersion は1.11.0を報告するようになりました。
fix(i18n): フランス語(v1.61.0で追加)が server/lib/prompts.mjs の LOCALE_NAMES および SCAFFOLD_STRINGS に欠落していた潜在的な問題を修正しました — フランス語のLLM呼び出しは暗黙的に英語出力と英語スキャフォールディングにフォールバックしていました。fr/pl/uk/ar がすべてプロンプトロケールパスに接続されました。
既知のフォローアップ: アプリ内ヘルプガイド(
docs/help/)はpl/uk/arでは英語にフォールバックします(UIクローム自体は完全にローカライズ済み)。親プロジェクトのインタラクティブなインタビューオンボーディング、リバースATS探索、新しいスキャンプロバイダーはまだSPAに公開されていません。
[1.69.2] — 2026-06-12
fix(test): npm test が実際の config/profile.yml と data/scan-history.tsv を上書きしてしまうテスト分離リークを修正。 tests/critical-fixes.test.mjs がファイル冒頭で prompts.mjs(→ paths.mjs)を読み込んでいたため、before() が CAREER_OPS_ROOT を一時ディレクトリに設定する前に PROJECT_ROOT が実際の親に解決され、PUT /api/profile が毎回「Acceptance Test」フィクスチャを実際のプロフィールに書き込んでいました。修正:prompts.mjs を before() 内で動的 import() により読み込むように変更。新規 tests/test-root-isolation.test.mjs(2 ケース)がスイート全体をこのパターンから保護します。本番コードの変更なし。スイート 1084 → 1086。
[1.69.1] — 2026-06-12
fix(scan): #/scan が大規模な地域スイープを黙って切り詰めなくなりました。 リージョンごとの表示セットが 500 件に固定されていました(実際の RU スキャンでは一致 1352 件のうち 500 件しか表示されず、852 件が非表示 =「2000 件スキャン、約 600 件表示」の症状)。両スキャナーは共有かつ環境変数で上書き可能な定数 MAX_STORED_RESULTS(既定 2000、SCAN_MAX_RESULTS で上書き)を使用します。表示のみ — pipeline.md / scan-history.tsv への追加は元から切り詰めなしのセットを使用していました。fix(health/ui): #/health のチェックカードがはみ出さなくなりました。 長い名前/値が Fix → ボタンとステータスバッジに衝突していましたが、.health-check-row で縮小・折り返しするようになりました。新規テスト scan-result-cap + health-card-overflow。スイート 1079 → 1084。
[1.69.0] — 2026-06-12
feat(scan): スキャナーアダプターの自動検出(P-14)— server/lib/sources/ に .mjs ファイルを置くだけで新しいソースを登録できます。 v1.69 以前は server/lib/sources/registry.mjs のソース一覧が手作業の静的配列で、アダプターを追加するには <id>.mjs と registry.mjs の両方を編集する必要がありました。これでロードマップ項目 P-14(docs/ROADMAP.md)の残作業を解消します。server/lib/sources/ 内の各 *.mjs はモジュール起動時に動的にロードされ、各アダプターは自己記述的なブロック export const meta = { value, label, region, configKey? } で自身を宣言します。同梱の 12 個のアダプター(ashby / greenhouse / lever / rss / smartrecruiters / workable / workday + geekjob / getmatch / habr / hh / trudvsem)に meta を追加。registry.mjs は readdirSync + 動的 import() を top-level await で解決します(Node 18+ の ESM 標準)。公開 API(SOURCES, SOURCES_BY_REGION, RU_CONFIG_KEYS, getRegionalSources)は変更なし — 既存のインポートはそのまま動作します。meta が不正な場合はスキップし、ファイルごとに console.warn を 1 回出力します。tests/sources-registry-discovery.test.mjs に 14 ケースを追加。スイート 1065 → 1079。
[1.68.2] — 2026-06-07
fix(bin): npx / npm link 経由の CLI 動詞が壊れていた — bin パスをシンボリックリンク経由で解決するよう修正。 npm と npx は career-ops-ui を node_modules/.bin/ 配下のシンボリックリンクとして公開しますが、従来の dirname "${BASH_SOURCE[0]}" はパッケージのルートではなく .bin を指していたため、npx career-ops-ui init が node node_modules/scripts/init.mjs を実行して MODULE_NOT_FOUND で落ちていました(ローカルの npm install 実行は影響を受けず、バグが隠れていました)。bin/career-ops-ui.sh と bin/start.sh はシンボリックリンクのチェーンをたどって SCRIPT_DIR を正規化するようになり(readlink ループ + cd -P)、すべての動詞がリポジトリから、npm link 経由、npx 経由で動作します。.bin スタイルのシンボリックリンク経由で動詞を実行する回帰ロックを tests/sh-files.test.mjs に追加。スイート 1065/1065。
[1.68.1] — 2026-05-29
fix(scan): ソース別フェッチのタイムアウトを 10s → 60s に延長。 v1.67.1 の 10s fail-fast は、もう少し時間が必要なだけの「遅いが生きている」Ashby ボードも切ってしまっていました。デフォルトを 1 分に上げて、それらが返るようにします。トレードオフ: 本当に死んだ/ハングしたソースは 60s 丸ごと並列枠を占有し(最悪ケースのスキャンが遅くなる)、慢性的なハング(Perplexity・Supabase・Resend など)はおそらく依然としてタイムアウトします — 適切に直すならソース別 / Ashby の並列度を下げる対応が必要です。SCAN_FETCH_TIMEOUT_MS で上書き可。スイート 1063/1063。
[1.68.0] — 2026-05-29
feat(scan): 結果フィルタのパネルを刷新 — ラベル付きフィールド、適用ボタン、オフィス勤務オプション、そして機能する給与フィルタ。 #/scan の各フィルタはラベル付きフィールドになりました(プレースホルダーではなくコントロールの上にラベル): 検索 · 勤務形態 · 給与 下限 · 給与 上限 · ソース · 範囲。明示的な適用ボタン(およびリセット、各フィールドでの Enter)でフィルタを再実行し、ページ上のヒントで使い方を説明します。給与レンジが実際にフィルタするようになりました — 下限/上限を設定すると、給与がレンジ外の求人および給与未掲載の求人は除外されます(レンジの重なり判定、通貨は無視)。勤務形態フィルタに、リモート / ハイブリッド / 転居 と並んでオフィス勤務オプションを追加。新規 i18n キー ×9、salaryInRange を厳格化、スイート 1063/1063。
[1.67.1] — 2026-05-29
fix(scan): ソース別フェッチのタイムアウトを 30s → 10s に短縮(fail-fast)。 v1.67.0 の 30s への引き上げでは遅い Ashby ボードの半分ほどしか復活せず、残り(Perplexity・Supabase・Resend・DeepL・Ramp など)は期限に関係なくハングするため、長いタイムアウトは死んだ枠を待ってスキャン全体を停滞させるだけでした。10s は慢性的なハングに即座に失敗し、スキャンの応答性を保ちます。SCAN_FETCH_TIMEOUT_MS で上書き可。スイート 1060/1060。
[1.67.0] — 2026-05-29
feat(scan): #/scan に給与レンジ(下限/上限)フィルタを追加し、ソース別フェッチのタイムアウトを延長。 結果テーブルに、テキスト・リモートのフィルタの隣に2つの数値入力(給与 下限 / 上限)が加わりました。各行のフリーテキスト給与(от 100 000 до 200 000 ₽、120000-150000 USD、$120K–$150K など)を数値レンジに解析し、レンジの重なり判定でマッチします。給与未掲載の行は残すため、フィルタは一覧を絞り込むだけでゼロにはしません(通貨は区別しません=為替換算なし)。さらに ソース別スキャンのフェッチタイムアウトを 15s → 30s に延長(SCAN_FETCH_TIMEOUT_MS で上書き可)。Ashby の includeCompensation ペイロードは ×8 並列下で >15s を要することが多く、毎回 ~30 の Ashby ボードがタイムアウトしていました。新規 window.Skills.parseSalaryRange/salaryInRange + i18n ×9、テスト13件追加、スイート 1060/1060。
[1.66.0] — 2026-05-28
feat(scan): RU ソースが最初のページだけでなく全ページを走査します。 hh.ru・Habr Career・Trudvsem はクエリごとに先頭 ~50 件しか取得していませんでしたが、最後までページを辿るようになりました — hh.ru/Habr は &page=N、Trudvsem は offset/meta.total — ページ間で重複除去し、新規が無くなったら(または 50 ページの安全上限で)停止します。「Backend разработчик」のようなクエリが 1 ページではなく全件を返します(例: hh.ru PHP 17 → 3 ページで 55 件以上、Trudvsem は 72 件すべて)。ページ単位のフェッチは既存のタイムアウト + AbortSignal を維持。テスト 4 件追加、スイート 1045/1045。
[1.65.0] — 2026-05-28
feat(scan): hh.ru を JSON API ではなく公開ウェブサイトからスクレイプ — どの IP からでもプロキシ不要で動作。 api.hh.ru は IP や User-Agent に関係なくすべてのプログラムクライアントに 403 forbidden を返すようになりました(エッジのアンチボット遮断)。一方サイト(hh.ru/search/vacancy)はブラウザ風クライアントに完全な結果を返すため、アダプタはその HTML を解析します(Habr Career と同様)。1.64.0 の HH_PROXY 変数と undici 依存を削除 — プロキシ・キー・User-Agent の設定は不要です。HTML パーサ向けにテストを書き直し、スイート 1041/1041。
[1.64.0] — 2026-05-27
feat(scan): HH_PROXY で hh.ru リクエストをロシアのプロキシ経由に. hh.ru は API を User-Agent ではなく IP でブロックするため、HH_USER_AGENT だけでは非ロシアの出口ノードからの 403 を解除できませんでした。HH_PROXY にロシアの HTTP/HTTPS プロキシ URL(例: http://user:pass@ru-host:port)を設定すると、hh.ru へのリクエストのみそのプロキシを経由し、他のソースは直接接続を維持します。undici の ProxyAgent を利用(ランタイム依存を追加)。HH_PROXY 未設定時は dispatcher を一切付与しません。テスト3件追加、スイート 1041/1041。
[1.63.2] — 2026-05-27
feat(scan): #/scan コンソールにライブ % 進捗 + ソース別の詳細。 進捗バーが確定的になりました — スキャナーが進捗イベント(EN: 企業ごと、RU: クエリごと)を SSE で送出し、「Scanning… NN%」 ラベル付きでバーが満ちます(アニメ縞は最初のイベントまで)。各ソースの最初の失敗(タイムアウト / 403 / ネットワーク)はコンソールに詳細出力され、以降の繰り返しは抑制されます。新規テスト 1 件、スイート 1040/1040。
[1.63.1] — 2026-05-27
style(scan): #/scan の進捗バーをより目立つように。 実行中インジケーターに見える 「Scanning…」 ラベルを付け、バーを 8px(細い 4px から)に拡大。スキャン中にはっきり見えます。挙動の変更なし。
[1.63.0] — 2026-05-27
feat(scan): リクエストごとのタイムアウト + #/scan の進捗バー。 ソースのリクエストに期限がなく、停止した upstream(例:ブロックされた IP からの api.hh.ru)がスキャン全体をハングさせる可能性がありました。新しい server/lib/fetch-timeout.mjs がスキャナーの fetchImpl をラップし(makeTimeoutFetch、デフォルト 15秒、SCAN_FETCH_TIMEOUT_MS で変更可)、各リクエストに厳格な期限を設定。タイムアウトしたソースは非致命的エラーとして記録され、スキャンは継続します。#/scan はスキャン中に進捗バーを表示(全 9 ロケールの scan.progress)。新規テスト 7 件、スイート 1039/1039。
[1.62.3] — 2026-05-27
docs: インストールを明確化(career-ops-ui は career-ops/web-ui/ の中で動作)+ init のトラブルシューティング、全 9 ロケール。 インストール節を Option 1(ワンライナー curl)/ Option 2(既存の career-ops プロジェクト内に web-ui として UI をクローン)+ CLI コマンド + プロバイダー設定 + Troubleshooting init ブロックに書き換え。ネスト構成の注記を /help §1 Setup にも追加し、README ハイライトで v1.62.* ライン全体を要約。ドキュメントのみ、コード変更なし。
[1.62.2] — 2026-05-27
fix(help): #/help のフィルターが全文検索になりました(RSS のような H3 サブセクションも見つかります)。 ヘルプページの検索/TOC フィルターは以前 H2 セクションタイトルのみに一致していたため、v1.62.x の RSS ドキュメント(§5 Portals & sources 配下の H3)が見つかりませんでした。各セクションの本文がフィルターにインデックスされるようになり、例えば「RSS」で検索すると §5 が表示されます。クライアント側のみ、API 変更なし。
[1.62.1] — 2026-05-27
feat(scan): ソースフィルターに RSS 追加 + RSS のロケーション修正。 #/scan のソースフィルターのドロップダウンに RSS が表示されるようになりました(server/lib/sources/registry.mjs と SPA のフォールバックリストに追加)。これにより RSS ボード(LaraJobs、WeWorkRemotely など)の結果も他の ATS ソースと同様にフィルターできます。RSS アダプターはフィードの <category> タグを location に割り当てなくなりました — 非ロケーションのタグが location_filter にリモート職を誤って除外させていたためです。現在 location は空になり、フィードはロケーションフィルターを通過します。スキャンボタンのツールチップ/ラベルとソース一覧の i18n 文字列を全 9 ロケールで更新(Workable / SmartRecruiters / Workday / RSS)。i18n スナップショットとソースエンドポイントのテスト(EN 6 → 7)を更新。
[1.62.0] — 2026-05-27
feat(scan): 非ATS求人ボード向けの汎用RSSアダプター。 新しい rss アダプター(server/lib/portals/adapters/rss.mjs + server/lib/sources/rss.mjs)により、スキャナーは任意のRSSフィード(LaraJobs、WeWorkRemotely、RemoteOK、golangprojects など Greenhouse/Ashby/Lever 以外のボード)から求人を取得できます。新しい依存関係なし:フィード解析は正規表現ベースで、CDATA と HTML エンティティに対応(タイトル/会社名はタグ除去、astral コードポイントは安全にデコード)。portals.yml の provider: rss / rss: / feed_url: で企業ごとに有効化され、ATS で一致済みの企業を横取りしません。ALL_ADAPTERS は 6 → 7 に増加。29 件の新規テスト。9 つの README ロケールに記載。
[1.61.1] — 2026-05-22
fix(i18n): テーマトグルの title + aria-label を全 9 ロケールでローカライズ (MINOR-001)。 ダーク/ライトのテーマボタン(#theme-toggle)が index.html に title="Toggle theme" と aria-label="Toggle theme" をハードコードしており — どのロケールでもツールチップとスクリーンリーダーのテキストが翻訳されませんでした。新しい top.themeToggle キー + applyI18n() の data-i18n-title ハンドラ(v1.58.15 の検索 aria-label 修正と同じパターン)が、起動時と言語切替のたびに両属性をローカライズします。tests/playwright-theme-toggle-i18n.mjs(9 ロケール + ランタイム切替)と 2 つの静的ガードでロック。v1.61.0 フランス語サインオフで唯一の LOW 項目。(MINOR-001)
[1.61.0] — 2026-05-22
feat(i18n): フランス語を9番目のUI言語として追加。 新しいロケール別辞書 public/js/lib/locales/i18n-dict.fr.js(window.__I18N_DICT_FR)は英語と668キーの完全な同等性を持ち、新しいヘルプバンドル docs/help/fr.md(19 H2 / 73 H3、en と正確な構造的同等性)。fr は言語スイッチャーとブラウザ自動検出(i18n.js)、アセンブラ(i18n-dict.js)、index.html(アセンブラより前の <script> タグ)、テストスナップショット、すべてのテストロケールリストに登録済み。初期翻訳テーブルは PR #9(コミュニティ貢献)由来。ロジック変更なし:t() とすべてのビューは不変。ユニットテスト 1001 / 1001;Playwright のロケールスイープは9サブテストに拡大。(FR-LOCALE)
[1.60.0] — 2026-05-22
refactor(i18n): 8 言語まとめのメガファイルをロケール別ファイルに分割 (I18N-SPLIT). 翻訳辞書は単一の public/js/lib/i18n-dict.js にありましたが、public/js/lib/locales/ 配下のロケールごとに 1 ファイルと共通の i18n-dict.aliases.js に分割し、翻訳者が 1 言語だけを独立して編集できるようにしました(i18next / OpenWA 方式)。i18n-dict.js は同じ window.__I18N_DICT を再構築するアセンブラになり、t() も各ビューも不変です。<script src> で同期読み込み — ビルドも fetch もなし。スナップショットで無損失移行を保証(678 キー)。ツールと約 25 のテストを分割対応に更新。新規 tests/i18n-locale-files.test.mjs と tests/playwright-locale-sweep.mjs(全ページ × 8 ロケールを実 Chromium で検証)。994 → 1000 ユニット · 62 → 70 Playwright。挙動の変更なし。(I18N-SPLIT)
career-ops-ui v1.267.1 · page 6/10 · mirror of the project changelog for cvstart.org