job-forge 2.14.39 → 2.14.40

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.
@@ -17,7 +17,8 @@ model_provider = "openai"
17
17
 
18
18
  [mcp_servers.geometra]
19
19
  command = "npx"
20
- args = ["-y", "@geometra/mcp@1.61.3"]
20
+ args = ["--no-install", "job-forge", "mcp:geometra"]
21
+ env = { GEOMETRA_STEALTH = "1", GEOMETRA_BROWSER = "stealth" }
21
22
 
22
23
  [mcp_servers.gmail]
23
24
  command = "npx"
package/.cursor/mcp.json CHANGED
@@ -3,9 +3,14 @@
3
3
  "geometra": {
4
4
  "command": "npx",
5
5
  "args": [
6
- "-y",
7
- "@geometra/mcp@1.61.3"
8
- ]
6
+ "--no-install",
7
+ "job-forge",
8
+ "mcp:geometra"
9
+ ],
10
+ "env": {
11
+ "GEOMETRA_STEALTH": "1",
12
+ "GEOMETRA_BROWSER": "stealth"
13
+ }
9
14
  },
10
15
  "gmail": {
11
16
  "command": "npx",
package/.mcp.json CHANGED
@@ -3,9 +3,14 @@
3
3
  "geometra": {
4
4
  "command": "npx",
5
5
  "args": [
6
- "-y",
7
- "@geometra/mcp@1.61.3"
8
- ]
6
+ "--no-install",
7
+ "job-forge",
8
+ "mcp:geometra"
9
+ ],
10
+ "env": {
11
+ "GEOMETRA_STEALTH": "1",
12
+ "GEOMETRA_BROWSER": "stealth"
13
+ }
9
14
  },
10
15
  "gmail": {
11
16
  "command": "npx",
package/README.md CHANGED
@@ -1,242 +1,194 @@
1
1
  # JobForge
2
2
 
3
- > AI-powered job search pipeline built on opencode. Evaluate offers, generate tailored CVs, scan portals, negotiate offers, and track everything -- powered by AI agents.
3
+ > AI-powered job search pipeline for opencode: evaluate roles, generate tailored CV PDFs, scan portals, apply to good-fit jobs, and track the whole search locally.
4
4
 
5
5
  ![opencode](https://img.shields.io/badge/opencode-000?style=flat&logoColor=white)
6
6
  ![Node.js](https://img.shields.io/badge/Node.js-339933?style=flat&logo=node.js&logoColor=white)
7
7
  ![Geometra](https://img.shields.io/badge/Geometra_MCP-4A90D9?style=flat&logoColor=white)
8
8
  ![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
9
- ![Made in USA](https://img.shields.io/badge/Made_in-USA_%F0%9F%87%BA%F0%9F%87%B8-red?style=flat)
10
9
 
11
10
  <p align="center">
12
- <img src="demo/demo.gif" alt="JobForge Demo" width="800">
11
+ <img src="demo/demo.gif" alt="JobForge demo" width="800">
13
12
  </p>
14
13
 
15
- <p align="center"><em>Paste a job URL. Get a scored evaluation, tailored CV, and tracked application — in seconds.</em></p>
14
+ <p align="center"><em>Paste a job URL. Get a scored evaluation, tailored CV, and tracker entry.</em></p>
16
15
 
17
- ---
16
+ ## Start Here
18
17
 
19
- ## Quick Start
18
+ Most users should scaffold a personal job-search project instead of cloning this harness repo directly.
19
+
20
+ ### Prerequisites
21
+
22
+ - [opencode](https://opencode.ai) installed and configured
23
+ - Node.js 20.6 or newer
24
+ - Optional: Go, only if you want to build the dashboard TUI
25
+
26
+ ### Create Your Project
20
27
 
21
28
  ```bash
22
29
  npx --package=job-forge create-job-forge my-job-search
23
30
  cd my-job-search
24
31
  npm install
25
- opencode
26
32
  ```
27
33
 
28
- The scaffolded `opencode.json` already has three MCPs wired up — they launch automatically the first time opencode starts:
34
+ Then edit the three personal files the scaffolder creates:
29
35
 
30
- - **Geometra** browser automation + PDF generation
31
- - **Gmail** — reads replies from recruiters
32
- - **state-trace** typed working memory for cross-session context (resumed batches, recent decisions, repeated portal quirks). Install once with `python3 -m pip install "state-trace[mcp]"`; the MCP command is `state-trace-mcp`.
36
+ | File | What to put there |
37
+ |------|-------------------|
38
+ | `cv.md` | Your CV in markdown. This is the source for matching and PDF generation. |
39
+ | `config/profile.yml` | Your identity, target roles, location constraints, compensation, and proof points. |
40
+ | `portals.yml` | Companies, search queries, and title filters for portal scanning. |
33
41
 
34
- JobForge also keeps MCP-free local workflow state and policy: `templates/canon.json` defines URL/company/role identity keys via `@agent-pattern-labs/iso-canon`, `templates/contracts.json` defines tracker/apply artifact shapes via `@agent-pattern-labs/iso-contract`, `templates/score.json` defines weighted scoring and gates via `@agent-pattern-labs/iso-score`, `templates/timeline.json` defines follow-up and next-action windows via `@agent-pattern-labs/iso-timeline`, `templates/prioritize.json` defines next-action ranking via `@agent-pattern-labs/iso-prioritize`, `templates/capabilities.json` defines role capability boundaries via `@agent-pattern-labs/iso-capabilities`, `templates/context.json` defines deterministic mode/reference bundles via `@agent-pattern-labs/iso-context`, `templates/preflight.json` defines safe dispatch rounds/gates via `@agent-pattern-labs/iso-preflight`, `templates/postflight.json` defines safe dispatch settlement via `@agent-pattern-labs/iso-postflight`, `templates/redact.json` defines safe-export redaction rules via `@agent-pattern-labs/iso-redact`, `templates/migrations.json` defines safe consumer-project upgrades via `@agent-pattern-labs/iso-migrate`, `templates/facts.json` defines source-backed fact extraction via `@agent-pattern-labs/iso-facts`, `.jobforge-ledger/events.jsonl` records duplicate/status events via `@agent-pattern-labs/iso-ledger`, `.jobforge-cache/` stores reusable JD/artifact content via `@agent-pattern-labs/iso-cache`, `.jobforge-index.json` indexes artifact source pointers via `@agent-pattern-labs/iso-index`, `.jobforge-facts.json` materializes queryable facts with provenance, `.jobforge-timeline.json` materializes due/overdue follow-up actions, `.jobforge-prioritize.json` materializes the ranked local priority queue, and `.jobforge-lineage.json` records stale-output checks for generated artifacts via `@agent-pattern-labs/iso-lineage`. None of these add always-on prompt or tool-schema tokens.
42
+ Optional: add `article-digest.md` with portfolio links, case studies, or extra proof points.
35
43
 
36
- `npm install` also materializes symlinks for every supported agent harness — OpenCode, Cursor, Claude Code, and Codex — so you can run `opencode`, `cursor`, `claude`, or `codex` in the same project and each picks up the shared MCP config and instructions.
44
+ ### First Run
37
45
 
38
- Then fill in `cv.md`, `config/profile.yml`, and `portals.yml` with your personal data, paste a job URL into opencode, and JobForge evaluates + tracks it.
39
-
40
- **Upgrade later:** `npm run update-harness` (pulls latest `job-forge` from npm, re-syncs symlinks, applies safe consumer migrations, prints the resolved version)
41
-
42
- Full setup guide and alternative install paths (including contributing to the harness itself): **[docs/SETUP.md](docs/SETUP.md)**.
46
+ ```bash
47
+ npx job-forge sync-check
48
+ opencode
49
+ ```
43
50
 
44
- ---
51
+ Inside opencode, paste a job URL or job description. JobForge routes it through the auto-pipeline: evaluation, score, tailored report, PDF, and tracker update.
45
52
 
46
- ## What Is This
53
+ To see the command menu:
47
54
 
48
- JobForge turns opencode into a full job search command center. Instead of manually tracking applications in a spreadsheet, you get an AI-powered pipeline that:
55
+ ```text
56
+ /job-forge
57
+ ```
49
58
 
50
- - **Evaluates offers** with a unified 10-dimension weighted scoring system
51
- - **Generates tailored PDFs** -- ATS-optimized CVs with anti-AI-detection writing rules
52
- - **Scans portals** with fuzzy dedup (catches reposts with new URLs)
53
- - **Processes in batch** -- evaluate 10+ offers in parallel with sub-agents
54
- - **Tracks everything** with pipeline integrity checks and canonical state management
55
- - **Manages follow-ups** -- timing-based nudges so you never miss a window
56
- - **Learns from rejections** -- pattern analysis across all rejections by stage, archetype, and score
57
- - **Negotiates offers** -- structured comp breakdown, leverage assessment, counter-offer strategy
59
+ ## What It Does
60
+
61
+ JobForge is built for selective, high-fit applications. It is not intended for spray-and-pray submission.
62
+
63
+ - Scores opportunities with a consistent weighted rubric.
64
+ - Generates tailored ATS-friendly CV PDFs.
65
+ - Scans configured company portals and job boards.
66
+ - Tracks applications, follow-ups, rejections, offers, reports, and PDFs.
67
+ - Supports batch evaluation and application work through bounded subagents.
68
+ - Uses local helper CLIs for dedupe, scoring, lineage, preflight, postflight, and tracker integrity.
69
+
70
+ ## Common Commands
71
+
72
+ Run these from your personal project root after `npm install`.
73
+
74
+ | Need | Command |
75
+ |------|---------|
76
+ | Verify setup after editing profile and CV | `npx job-forge sync-check` |
77
+ | Check tracker and pipeline health | `npx job-forge verify` |
78
+ | Merge batch tracker additions | `npx job-forge merge` |
79
+ | Generate a CV PDF from the current project | `npx job-forge pdf` |
80
+ | Show token usage | `npx job-forge tokens --days 1` |
81
+ | Rebuild harness symlinks | `npx job-forge sync` |
82
+ | Upgrade the harness | `npm run update-harness` |
83
+
84
+ Useful opencode commands:
85
+
86
+ | Need | Command |
87
+ |------|---------|
88
+ | Evaluate a pasted URL or JD | Paste it directly, or use `/job-forge` |
89
+ | Scan configured portals | `/job-forge scan` |
90
+ | Process queued URLs | `/job-forge pipeline` |
91
+ | Batch evaluate roles | `/job-forge batch` |
92
+ | Fill an application form | `/job-forge apply` |
93
+ | Check application status | `/job-forge tracker` |
94
+ | Check due follow-ups | `/job-forge followup` |
95
+ | Draft LinkedIn outreach | `/job-forge contact` |
96
+ | Research a company | `/job-forge deep` |
97
+ | Handle rejection or offer workflows | `/job-forge rejection` or `/job-forge negotiation` |
98
+
99
+ ## How The Flow Works
100
+
101
+ ```text
102
+ Paste a job URL or JD
103
+ |
104
+ v
105
+ Extract role details and classify fit
106
+ |
107
+ v
108
+ Score against profile, CV, location, comp, and role goals
109
+ |
110
+ v
111
+ Create report + tailored PDF + tracker entry
112
+ |
113
+ v
114
+ Apply, follow up, research, or negotiate from the tracked state
115
+ ```
58
116
 
59
- > **Important: This is NOT a spray-and-pray tool.** The whole point is to apply only where there's a real match. The scoring system helps you focus on high-fit opportunities instead of wasting everyone's time. Always review before submitting.
117
+ ## Project Layout
118
+
119
+ A scaffolded personal project looks like this:
120
+
121
+ ```text
122
+ my-job-search/
123
+ ├── package.json # depends on job-forge from npm
124
+ ├── opencode.json # MCP and opencode configuration
125
+ ├── cv.md # personal, gitignored
126
+ ├── article-digest.md # optional personal proof points, gitignored
127
+ ├── config/profile.yml # personal, gitignored
128
+ ├── portals.yml # personal scanner config, gitignored
129
+ ├── data/ # pipeline, applications, scan history
130
+ ├── reports/ # generated evaluations
131
+ ├── output/ # generated PDFs
132
+ ├── batch/tracker-additions/ # batch apply/eval results before merge
133
+ ├── AGENTS.md # personal overrides
134
+ ├── AGENTS.harness.md # symlink into node_modules/job-forge
135
+ ├── modes/ # symlinked JobForge modes
136
+ ├── templates/ # symlinked policies and templates
137
+ └── node_modules/job-forge/ # the harness package
138
+ ```
60
139
 
61
- ## Features
140
+ Your personal files and generated job-search state are gitignored by the scaffolded project.
62
141
 
63
- | Feature | Description |
64
- |---------|-------------|
65
- | **Auto-Pipeline** | Paste a URL, get a full evaluation + PDF + tracker entry |
66
- | **Unified Scoring** | 10 weighted dimensions, consistent across all modes, with calibration anchors and deterministic `job-forge score:*` checks |
67
- | **Anti-AI-Detection CVs** | Writing rules that avoid ATS filters on Indeed, LinkedIn, Workday |
68
- | **6-Block Evaluation** | Role summary, CV match, level strategy, comp research, personalization, interview prep (STAR+R) |
69
- | **Interview Story Bank** | Curated bank of 10-12 stories with match counts, archetype tags, and automatic pruning |
70
- | **Follow-Up System** | `job-forge timeline:*` computes timing-based nudges from local tracker/pipeline sources: Applied 7+ days ago, Contacted 5+ days ago, Interview 1-day thank-you, and 7-day interview nudge. |
71
- | **Gmail Integration** | MCP server configured to retrieve emails for interview callbacks, offer responses, and application status updates |
72
- | **Rejection Analysis** | Captures stage + reason, surfaces patterns (archetype gaps, scoring miscalibration) |
73
- | **Offer Negotiation** | Total comp breakdown, equity valuation, leverage from pipeline, counter-offer scripts |
74
- | **Deep Research** | Company research that feeds back into scores and interview prep |
75
- | **Smart LinkedIn Outreach** | Reads evaluation reports to craft targeted messages using top proof points |
76
- | **Portal Scanner** | 45+ companies pre-configured with fuzzy dedup for reposts |
77
- | **Batch Processing** | Parallel evaluation with headless AI CLI workers (`opencode run` or `codex exec`), with honest verification flagging |
78
- | **Durable Batch Orchestration** | `batch-runner.sh` uses `@agent-pattern-labs/iso-orchestrator` for resumable bundle execution, bounded fan-out, mutexed state writes, and workflow records in `.jobforge-runs/`. |
79
- | **Pipeline Integrity** | Automated merge, dedup, status normalization, health checks |
80
- | **Cost-Aware Agent Routing** | Three subagents (`@general-free`, `@general-paid`, `@glm-minimal`) with per-task tool surfaces. On OpenCode, JobForge pins all tiers to `opencode-go/deepseek-v4-flash` so application runs avoid overloaded free-model pools. See [Subagent Routing in AGENTS.md](AGENTS.md) for the task-to-agent mapping. |
81
- | **Trace + Telemetry + Guard + Contract + Score + Canon + Ledger + Capabilities + Context + Cache + Index + Facts + Timeline + Prioritize + Lineage + Preflight + Postflight + Redact + Migrate** | `job-forge trace:*` exposes local harness transcripts, `job-forge telemetry:*` summarizes runs, `job-forge guard:*` audits deterministic policy rules, `templates/contracts.json` enforces artifact shape with `iso-contract`, `job-forge score:*` computes/checks weighted offer scores, `job-forge canon:*` derives stable URL/company/role identity keys, `job-forge ledger:*` queries append-only workflow state, `job-forge capabilities:*` checks role boundaries, `job-forge context:*` plans mode/reference context bundles, `job-forge cache:*` reuses fetched JD/artifact content, `job-forge index:*` queries compact source pointers, `job-forge facts:*` materializes source-backed job/application/candidate facts, `job-forge timeline:*` computes due/overdue follow-up actions, `job-forge prioritize:*` ranks local apply/follow-up candidates, `job-forge lineage:*` detects stale reports/PDFs after source changes, `job-forge preflight:*` plans bounded apply dispatch rounds from file-backed candidate facts, `job-forge postflight:*` settles dispatch outcomes/artifacts/post-steps, `job-forge redact:*` sanitizes local exports, and `job-forge migrate:*` applies safe consumer-project upgrades without MCP/tool-schema overhead. |
82
- | **Token Cost Visibility** | `job-forge tokens --days 1` for per-session breakdown; `job-forge session-report --since-minutes 60 --log` to flag sessions over budget and append history to `data/token-usage.tsv`. Auto-logged after every batch run. |
142
+ ## MCPs And Automation
83
143
 
84
- ## Usage
144
+ The scaffolded opencode project wires up the browser and mail automation JobForge needs:
85
145
 
86
- ```
87
- /job-forge → Show all available commands
88
- /job-forge {paste a JD} → Full auto-pipeline (evaluate + PDF + tracker)
89
- /job-forge scan → Scan portals for new offers
90
- /job-forge pdf → Generate ATS-optimized CV
91
- /job-forge batch → Batch evaluate multiple offers
92
- /job-forge tracker → View application status
93
- /job-forge apply → Fill application forms with AI
94
- /job-forge pipeline → Process pending URLs
95
- /job-forge contact → LinkedIn outreach (uses evaluation report)
96
- /job-forge deep → Deep company research (feeds back into scores)
97
- /job-forge followup → Check what needs follow-up action
98
- /job-forge rejection → Record/analyze rejection patterns
99
- /job-forge negotiation → Structured offer negotiation
100
- /job-forge training → Evaluate a course/cert
101
- /job-forge project → Evaluate a portfolio project
102
- ```
146
+ - Geometra MCP for browser automation and PDF generation.
147
+ - Gmail MCP for recruiter replies, interview callbacks, offer responses, and status emails.
103
148
 
104
- Or just paste a job URL or description directly -- JobForge auto-detects it and runs the full pipeline.
149
+ The harness also ships config for Cursor, Claude Code, and Codex through generated symlinks. `npm install` and `npx job-forge sync` refresh those links.
105
150
 
106
- > **The system is designed to be customized by opencode itself.** Modes, archetypes, scoring weights, negotiation scripts -- just ask opencode to change them: "Change the archetypes to backend engineering roles", "Add these 5 companies to portals.yml", "Update my profile with this CV I'm pasting".
151
+ ## Contributor Setup
107
152
 
108
- ## How It Works
153
+ Clone this repo directly only when you want to work on the harness itself: modes, scripts, templates, generated agent configs, or release packaging.
109
154
 
110
- ```
111
- You paste a job URL or description
112
-
113
-
114
- ┌──────────────────┐
115
- │ Archetype │ Classifies: LLMOps / Agentic / PM / SA / FDE / Transformation
116
- │ Detection │
117
- └────────┬─────────┘
118
-
119
- ┌────────▼─────────┐
120
- │ A-F Evaluation │ Match, gaps, comp research, STAR stories
121
- │ (reads cv.md) │ Unified 10-dimension scoring model + iso-score checks
122
- └────────┬─────────┘
123
-
124
- ┌────┼────┐
125
- ▼ ▼ ▼
126
- Report PDF Tracker
127
- .md .pdf .tsv
128
-
129
- ┌────┼────┐
130
- ▼ ▼ ▼
131
- Apply Follow Negotiate
132
- up (if offer)
155
+ ```bash
156
+ git clone https://github.com/Agent-Pattern-Labs/JobForge.git
157
+ cd JobForge
158
+ npm install
159
+ npm run build:config
160
+ npm run verify
133
161
  ```
134
162
 
135
- ## Project Structure
163
+ The source of truth for generated harness configuration is under `iso/`. Run `npm run build:config` after changing `iso/` files.
136
164
 
137
- **Your personal project** (after `npx --package=job-forge create-job-forge my-search`):
165
+ ## Documentation
138
166
 
139
- ```
140
- my-search/
141
- ├── package.json # depends on "job-forge": "^2.0.0" (npm registry)
142
- ├── opencode.json # thin config enables MCPs + states.yml
143
- ├── cv.md # your CV (personal)
144
- ├── article-digest.md # your proof points (optional, personal)
145
- ├── portals.yml # companies to scan (personal)
146
- ├── config/profile.yml # your identity, target roles (personal)
147
- ├── data/ # applications, pipeline, scan history (personal, gitignored)
148
- ├── .jobforge-ledger/ # append-only local workflow events (personal, gitignored)
149
- ├── .jobforge-cache/ # content-addressed local JD/artifact cache (personal, gitignored)
150
- ├── .jobforge-index.json # deterministic artifact lookup index (generated, gitignored)
151
- ├── .jobforge-facts.json # deterministic fact set with provenance (generated, gitignored)
152
- ├── .jobforge-timeline.json # deterministic follow-up action plan (generated, gitignored)
153
- ├── .jobforge-prioritize.json # deterministic next-action ranking (generated, gitignored)
154
- ├── .jobforge-lineage.json # report/PDF lineage and stale-output checks (generated, gitignored)
155
- ├── .jobforge-redacted/ # sanitized local exports (generated, gitignored)
156
- ├── reports/ # generated evaluation reports (personal, gitignored)
157
- ├── batch/{batch-input,batch-state}.tsv, tracker-additions/, logs/ # personal
158
- ├── .jobforge-runs/ # durable batch workflow records (generated)
159
- ├── AGENTS.md # personal overrides (opencode + codex)
160
- ├── CLAUDE.md # personal overrides (Claude Code), @-imports CLAUDE.harness.md
161
-
162
- │ # ↓ symlinks into node_modules/job-forge/, regenerated by postinstall sync.mjs
163
- ├── AGENTS.harness.md # → harness instructions (loaded via opencode.json)
164
- ├── CLAUDE.harness.md # → harness instructions (imported from personal CLAUDE.md)
165
- ├── .mcp.json # → Claude Code MCP config
166
- ├── .codex/config.toml # → Codex MCP config
167
- ├── .cursor/mcp.json # → Cursor MCP config
168
- ├── .cursor/rules/main.mdc # → Cursor always-apply rule
169
- ├── .opencode/skills/job-forge.md # → skill router
170
- ├── .opencode/agents/ # → @general-free, @general-paid, @glm-minimal
171
- ├── modes/ # → _shared.md + skill modes
172
- ├── templates/ # → states.yml, portals.example.yml, cv-template.html, canon.json, score.json, timeline.json, prioritize.json, capabilities.json, context.json, index.json, facts.json, preflight.json, postflight.json, redact.json, migrations.json
173
- ├── batch/batch-prompt.md # → batch worker prompt
174
- ├── batch/batch-runner.sh # → parallel orchestrator
175
-
176
- └── node_modules/job-forge/ # the harness (from npm: `job-forge@2.x`)
177
- ```
167
+ - [Setup](docs/SETUP.md) - full install paths, personalization, tracker setup, token tracking, troubleshooting.
168
+ - [Architecture](docs/ARCHITECTURE.md) - consumer vs harness split, modes, scripts, batch flow, generated config.
169
+ - [Customization](docs/CUSTOMIZATION.md) - profile, archetypes, scanner keywords, states, templates, local overrides.
170
+ - [Model Routing](docs/MODEL-ROUTING.md) - subagent tiers and how to change model routing.
171
+ - [Examples](examples/README.md) - fictional CVs, sample JD, and sample report.
172
+ - [Batch Runner](batch/README.md) - TSV format, durable batch runner, merge flow.
173
+ - [Contributing](CONTRIBUTING.md) - branch workflow and quality checks.
178
174
 
179
- Symlinks are regenerated on every `npm install` via the package's `postinstall` hook. You never have to know about harness internals — just edit `cv.md`, `portals.yml`, and `config/profile.yml`.
175
+ ## Troubleshooting
180
176
 
181
- **The harness itself** (this repo, what gets published as `job-forge` on npm):
177
+ `sync-check` fails before your CV/profile are complete. That is expected until `cv.md` and `config/profile.yml` are filled in.
182
178
 
183
- ```
184
- JobForge/
185
- ├── iso/ # ← SOURCE OF TRUTH for harness configuration
186
- │ ├── instructions.md # → AGENTS.md + CLAUDE.md (Claude Code / Codex / Cursor)
187
- │ ├── mcp.json # → .mcp.json + .cursor/mcp.json + .codex/config.toml + opencode.json
188
- │ ├── agents/*.md # → .opencode/agents/*.md (general-free, general-paid, glm-minimal)
189
- │ ├── commands/job-forge.md # → .opencode/skills/job-forge.md
190
- │ └── config.json # per-harness top-level extras (e.g. opencode `instructions` array)
191
-
192
- ├── package.json # bin: job-forge, create-job-forge; prepack runs iso-harness
193
- ├── bin/
194
- │ ├── job-forge.mjs # CLI dispatcher (merge/verify/pdf/tokens/sync/...)
195
- │ ├── sync.mjs # postinstall: creates symlinks in consumer project
196
- │ └── create-job-forge.mjs # scaffolder
197
- ├── modes/ # _shared.md + 16 skill modes
198
- ├── templates/ # cv-template.html, portals.example.yml, states.yml, canon.json, score.json, timeline.json, prioritize.json, capabilities.json, context.json, facts.json, preflight.json, postflight.json, redact.json, migrations.json
199
- ├── config/profile.example.yml # template for consumer's profile.yml
200
- ├── batch/{batch-prompt.md,batch-runner.sh} # batch orchestrator
201
- ├── scripts/
202
- │ ├── batch-orchestrator.mjs # iso-orchestrator-backed batch control loop
203
- │ ├── tracker-line.mjs # iso-contract-backed tracker TSV renderer
204
- │ ├── ledger.mjs # iso-ledger-backed workflow-state CLI
205
- │ ├── capabilities.mjs # iso-capabilities-backed role policy CLI
206
- │ ├── context.mjs # iso-context-backed context bundle CLI
207
- │ ├── cache.mjs # iso-cache-backed local artifact cache CLI
208
- │ ├── index.mjs # iso-index-backed artifact lookup CLI
209
- │ ├── facts.mjs # iso-facts-backed local fact materialization
210
- │ ├── timeline.mjs # iso-timeline-backed follow-up planning CLI
211
- │ ├── prioritize.mjs # iso-prioritize-backed next-action ranking
212
- │ ├── lineage.mjs # iso-lineage-backed stale artifact checks
213
- │ ├── score.mjs # iso-score-backed offer scoring CLI
214
- │ ├── canon.mjs # iso-canon-backed identity normalization CLI
215
- │ ├── preflight.mjs # iso-preflight-backed dispatch planning CLI
216
- │ ├── postflight.mjs # iso-postflight-backed dispatch settlement CLI
217
- │ ├── redact.mjs # iso-redact-backed safe-export redaction CLI
218
- │ ├── migrate.mjs # iso-migrate-backed consumer-project migrations
219
- │ ├── token-usage-report.mjs # opencode cost analyzer
220
- │ └── release/check-source.mjs # version gate for npm publish
221
- ├── tracker-lib.mjs / merge-tracker.mjs / dedup-tracker.mjs / verify-pipeline.mjs
222
- ├── normalize-statuses.mjs / generate-pdf.mjs / cv-sync-check.mjs
223
- ├── dashboard/ # optional Go TUI
224
- ├── fonts/ # Space Grotesk + DM Sans (for PDF)
225
- ├── docs/ # architecture, setup, customization
226
- └── .github/workflows/ # quality.yml + release.yml (CI publish to npm)
227
- ```
179
+ If symlinks look stale after moving a project, run:
228
180
 
229
- All per-harness config trees (`.opencode/`, `.cursor/`, `.claude/`, `.codex/`, `CLAUDE.md`, `AGENTS.md`, `.mcp.json`, `opencode.json`) are **generated** from `iso/` by [`@agent-pattern-labs/iso-harness`](https://www.npmjs.com/package/@agent-pattern-labs/iso-harness) and gitignored in this repo. `npm run build:config` regenerates them locally; `prepack` regenerates them into the tarball at publish time so consumers get everything pre-baked.
181
+ ```bash
182
+ npx job-forge sync
183
+ ```
230
184
 
231
- ## Documentation
185
+ If PDF or browser automation fails, start with:
232
186
 
233
- Index and cross-links: [docs/README.md](docs/README.md).
187
+ ```bash
188
+ opencode mcp list
189
+ ```
234
190
 
235
- - [Setup](docs/SETUP.md) both install paths, profile, CV, portals, verify, token tracking, troubleshooting
236
- - [Architecture](docs/ARCHITECTURE.md) — package architecture, modes, evaluation flow, batch runner, pipeline scripts
237
- - [Customization](docs/CUSTOMIZATION.md) — archetypes, scanner keywords, CV template, states, customizing symlinked modes
238
- - [Model Routing](docs/MODEL-ROUTING.md) — the three cost-tiered subagents, why the architecture exists, and how to swap models or add your own
239
- - [Contributing](CONTRIBUTING.md) — branch workflow, quality gate, and ideas for PRs
191
+ Then see [docs/SETUP.md](docs/SETUP.md#troubleshooting) for Geometra, Gmail, dashboard, tracker, and merge troubleshooting.
240
192
 
241
193
  ## License
242
194
 
@@ -240,7 +240,11 @@ const opencodeCfg = {
240
240
  mcp: {
241
241
  geometra: {
242
242
  type: 'local',
243
- command: ['npx', '-y', '@geometra/mcp@1.61.3'],
243
+ command: ['npx', '--no-install', 'job-forge', 'mcp:geometra'],
244
+ environment: {
245
+ GEOMETRA_STEALTH: '1',
246
+ GEOMETRA_BROWSER: 'stealth',
247
+ },
244
248
  enabled: true,
245
249
  },
246
250
  gmail: {
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from 'node:child_process';
4
+ import { existsSync } from 'node:fs';
5
+ import { dirname, resolve } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const DEFAULT_FALLBACK_PACKAGE = '@geometra/mcp@1.61.3';
9
+ const RESOLVE_ONLY_FLAG = '--job-forge-resolve-target';
10
+
11
+ function normalizeEnv(value) {
12
+ if (typeof value !== 'string') return null;
13
+ const trimmed = value.trim();
14
+ return trimmed.length > 0 ? trimmed : null;
15
+ }
16
+
17
+ function resolveExplicitPath(rawPath) {
18
+ const resolvedPath = resolve(rawPath);
19
+ if (!existsSync(resolvedPath)) {
20
+ throw new Error(`JOB_FORGE_GEOMETRA_MCP_PATH points to a missing file: ${resolvedPath}`);
21
+ }
22
+ return resolvedPath;
23
+ }
24
+
25
+ export function resolveGeometraMcpLaunchTarget() {
26
+ const explicitPath = normalizeEnv(process.env.JOB_FORGE_GEOMETRA_MCP_PATH);
27
+ if (explicitPath) {
28
+ const resolvedPath = resolveExplicitPath(explicitPath);
29
+ return {
30
+ source: 'env-path',
31
+ command: process.execPath,
32
+ args: [resolvedPath],
33
+ resolvedPath,
34
+ };
35
+ }
36
+
37
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
38
+ const siblingRepoPath = resolve(scriptDir, '../../geometra/mcp/dist/index.js');
39
+ if (existsSync(siblingRepoPath)) {
40
+ return {
41
+ source: 'sibling-repo',
42
+ command: process.execPath,
43
+ args: [siblingRepoPath],
44
+ resolvedPath: siblingRepoPath,
45
+ };
46
+ }
47
+
48
+ const packageSpec = normalizeEnv(process.env.JOB_FORGE_GEOMETRA_MCP_PACKAGE) ?? DEFAULT_FALLBACK_PACKAGE;
49
+ return {
50
+ source: 'npm-package',
51
+ command: 'npx',
52
+ args: ['-y', packageSpec],
53
+ packageSpec,
54
+ };
55
+ }
56
+
57
+ export async function main(argv = process.argv.slice(2)) {
58
+ const target = resolveGeometraMcpLaunchTarget();
59
+
60
+ if (argv.length === 1 && argv[0] === RESOLVE_ONLY_FLAG) {
61
+ process.stdout.write(`${JSON.stringify(target, null, 2)}\n`);
62
+ return;
63
+ }
64
+
65
+ const child = spawn(target.command, [...target.args, ...argv], {
66
+ stdio: 'inherit',
67
+ env: process.env,
68
+ });
69
+
70
+ child.on('error', (error) => {
71
+ console.error(error instanceof Error ? error.message : String(error));
72
+ process.exit(1);
73
+ });
74
+
75
+ child.on('exit', (code, signal) => {
76
+ if (signal) {
77
+ process.kill(process.pid, signal);
78
+ return;
79
+ }
80
+ process.exit(code ?? 0);
81
+ });
82
+ }
83
+
84
+ if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
85
+ void main();
86
+ }
package/bin/job-forge.mjs CHANGED
@@ -16,6 +16,7 @@
16
16
  * normalize Run normalize-statuses.mjs
17
17
  * pdf Run generate-pdf.mjs
18
18
  * sync-check Run cv-sync-check.mjs
19
+ * mcp:geometra Launch Geometra MCP via JobForge's local/npm resolver
19
20
  * tokens Run scripts/token-usage-report.mjs
20
21
  * trace:* Inspect local agent transcripts via iso-trace
21
22
  * telemetry:* Summarize JobForge pipeline status from traces + tracker files
@@ -55,6 +56,7 @@ const commands = {
55
56
  normalize: 'normalize-statuses.mjs',
56
57
  pdf: 'generate-pdf.mjs',
57
58
  'sync-check': 'cv-sync-check.mjs',
59
+ 'mcp:geometra': 'bin/geometra-mcp-launcher.mjs',
58
60
  tokens: 'scripts/token-usage-report.mjs',
59
61
  sync: 'bin/sync.mjs',
60
62
  // Deterministic helpers — agents call these instead of deriving values
@@ -244,6 +246,7 @@ Commands:
244
246
  normalize Normalize status values across the tracker
245
247
  pdf Generate ATS-optimized CV PDF from cv.md
246
248
  sync-check Lint: verify cv.md and profile.yml are filled in
249
+ mcp:geometra Launch Geometra MCP, preferring local JobForge/Geometra dev wiring
247
250
  tokens Show opencode token usage and cost by session/day
248
251
  trace Pass through to iso-trace (e.g. job-forge trace sources)
249
252
  trace:list List recent local agent sessions (defaults: --since 7d --cwd project)
package/docs/SETUP.md CHANGED
@@ -214,7 +214,7 @@ Use it to identify which sessions or models are consuming the most tokens. The `
214
214
  `sync-check` requires `cv.md` and `config/profile.yml` with the fields checked in `cv-sync-check.mjs`. Until you finish the profile and CV steps, that is normal.
215
215
 
216
216
  **PDF generation fails**
217
- The scaffolded `opencode.json` already registers Geometra MCP; if it's not running, check `opencode mcp list` and verify the scaffolded config under the `mcp.geometra` key — its `command` MUST be `["npx", "-y", "@geometra/mcp@1.61.3"]` and `enabled: true`. Geometra manages Chromium via its built-in proxy. JobForge passes `stealth: true` for portal sessions so Geometra launches CloakBrowser's patched Chromium. For standalone CLI usage (outside opencode), `generate-pdf.mjs` also works with standalone Playwright/Chromium — install with `npx playwright install chromium`.
217
+ The scaffolded `opencode.json` already registers Geometra MCP; if it's not running, check `opencode mcp list` and verify the scaffolded config under the `mcp.geometra` key — its `command` MUST be `["npx", "--no-install", "job-forge", "mcp:geometra"]`, `enabled: true`, and its `environment` should include `GEOMETRA_STEALTH=1` (or equivalently `GEOMETRA_BROWSER=stealth`) so proxy-backed portal sessions default to CloakBrowser's patched Chromium. `job-forge mcp:geometra` prefers `JOB_FORGE_GEOMETRA_MCP_PATH` when set, otherwise a sibling `../geometra/mcp/dist/index.js` checkout for local JobForge development, and otherwise falls back to the pinned npm package. Geometra manages Chromium via its built-in proxy. JobForge still passes `stealth: true` for portal sessions explicitly; the env block keeps the default aligned for auto-spawned sessions and local debugging. For standalone CLI usage (outside opencode), `generate-pdf.mjs` also works with standalone Playwright/Chromium — install with `npx playwright install chromium`.
218
218
 
219
219
  **Symlinks are missing or pointing to a stale path**
220
220
  Run `npx job-forge sync` (or `npm run sync`) to recreate them. This happens if you move the project directory after installing, or if `postinstall` didn't run (rare — check `npm install` output for errors).
package/iso/mcp.json CHANGED
@@ -2,7 +2,11 @@
2
2
  "servers": {
3
3
  "geometra": {
4
4
  "command": "npx",
5
- "args": ["-y", "@geometra/mcp@1.61.3"]
5
+ "args": ["--no-install", "job-forge", "mcp:geometra"],
6
+ "env": {
7
+ "GEOMETRA_STEALTH": "1",
8
+ "GEOMETRA_BROWSER": "stealth"
9
+ }
6
10
  },
7
11
  "gmail": {
8
12
  "command": "npx",
@@ -128,7 +128,7 @@ The Geometra MCP partitions its reusable-proxy pool by proxy identity and browse
128
128
  "geometra": {
129
129
  "type": "stdio",
130
130
  "command": "npx",
131
- "args": ["-y", "@geometra/mcp@1.61.3"]
131
+ "args": ["--no-install", "job-forge", "mcp:geometra"]
132
132
  },
133
133
  "gmail": {
134
134
  "type": "stdio",
@@ -139,4 +139,6 @@ The Geometra MCP partitions its reusable-proxy pool by proxy identity and browse
139
139
  }
140
140
  ```
141
141
 
142
+ `job-forge mcp:geometra` resolves Geometra in this order: `JOB_FORGE_GEOMETRA_MCP_PATH` if set, then a sibling local `../geometra/mcp/dist/index.js` checkout for maintainers working across both repos, then the pinned npm fallback.
143
+
142
144
  To check or modify MCP settings, edit `opencode.json` in the project root.
package/opencode.json CHANGED
@@ -17,10 +17,14 @@
17
17
  "type": "local",
18
18
  "command": [
19
19
  "npx",
20
- "-y",
21
- "@geometra/mcp@1.61.3"
20
+ "--no-install",
21
+ "job-forge",
22
+ "mcp:geometra"
22
23
  ],
23
- "environment": {}
24
+ "environment": {
25
+ "GEOMETRA_STEALTH": "1",
26
+ "GEOMETRA_BROWSER": "stealth"
27
+ }
24
28
  },
25
29
  "gmail": {
26
30
  "type": "local",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job-forge",
3
- "version": "2.14.39",
3
+ "version": "2.14.40",
4
4
  "description": "AI-powered job search pipeline built on opencode",
5
5
  "type": "module",
6
6
  "bin": {