job-forge 2.0.0 → 2.0.1
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.
- package/README.md +58 -45
- package/bin/create-job-forge.mjs +1 -1
- package/docs/ARCHITECTURE.md +32 -19
- package/docs/README.md +3 -3
- package/docs/SETUP.md +21 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npx
|
|
22
|
+
npx --package=job-forge create-job-forge my-job-search
|
|
23
23
|
cd my-job-search
|
|
24
24
|
npm install
|
|
25
25
|
opencode
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
The scaffolded `opencode.json` already has the Geometra MCP (browser automation + PDF) and Gmail MCP (reading replies) wired up — they launch automatically the first time opencode starts.
|
|
28
|
+
The scaffolded `opencode.json` already has the Geometra MCP (browser automation + PDF) and Gmail MCP (reading replies) wired up — they launch automatically the first time opencode starts. `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.
|
|
29
29
|
|
|
30
30
|
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.
|
|
31
31
|
|
|
32
|
-
**Upgrade later:** `npm run update-harness` (pulls latest
|
|
32
|
+
**Upgrade later:** `npm run update-harness` (pulls latest `job-forge` from npm, re-syncs symlinks, prints the resolved version)
|
|
33
33
|
|
|
34
34
|
Full setup guide and alternative install paths (including contributing to the harness itself): **[docs/SETUP.md](docs/SETUP.md)**.
|
|
35
35
|
|
|
@@ -125,61 +125,74 @@ You paste a job URL or description
|
|
|
125
125
|
|
|
126
126
|
## Project Structure
|
|
127
127
|
|
|
128
|
-
**Your personal project** (after `npx create-job-forge my-search`):
|
|
128
|
+
**Your personal project** (after `npx --package=job-forge create-job-forge my-search`):
|
|
129
129
|
|
|
130
130
|
```
|
|
131
131
|
my-search/
|
|
132
|
-
├── package.json
|
|
133
|
-
├── opencode.json
|
|
134
|
-
├── cv.md
|
|
135
|
-
├── article-digest.md
|
|
136
|
-
├── portals.yml
|
|
137
|
-
├── config/profile.yml
|
|
138
|
-
├── data/
|
|
139
|
-
├── reports/
|
|
140
|
-
├── batch/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
│
|
|
144
|
-
│
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
├──
|
|
148
|
-
├──
|
|
149
|
-
├── .
|
|
150
|
-
|
|
132
|
+
├── package.json # depends on "job-forge": "^2.0.0" (npm registry)
|
|
133
|
+
├── opencode.json # thin config — enables MCPs + states.yml
|
|
134
|
+
├── cv.md # your CV (personal)
|
|
135
|
+
├── article-digest.md # your proof points (optional, personal)
|
|
136
|
+
├── portals.yml # companies to scan (personal)
|
|
137
|
+
├── config/profile.yml # your identity, target roles (personal)
|
|
138
|
+
├── data/ # applications, pipeline, scan history (personal, gitignored)
|
|
139
|
+
├── reports/ # generated evaluation reports (personal, gitignored)
|
|
140
|
+
├── batch/{batch-input,batch-state}.tsv, tracker-additions/, logs/ # personal
|
|
141
|
+
├── AGENTS.md # personal overrides (opencode + codex)
|
|
142
|
+
├── CLAUDE.md # personal overrides (Claude Code), @-imports CLAUDE.harness.md
|
|
143
|
+
│
|
|
144
|
+
│ # ↓ symlinks into node_modules/job-forge/, regenerated by postinstall sync.mjs
|
|
145
|
+
├── AGENTS.harness.md # → harness instructions (loaded via opencode.json)
|
|
146
|
+
├── CLAUDE.harness.md # → harness instructions (imported from personal CLAUDE.md)
|
|
147
|
+
├── .mcp.json # → Claude Code MCP config
|
|
148
|
+
├── .codex/config.toml # → Codex MCP config
|
|
149
|
+
├── .cursor/mcp.json # → Cursor MCP config
|
|
150
|
+
├── .cursor/rules/main.mdc # → Cursor always-apply rule
|
|
151
|
+
├── .opencode/skills/job-forge.md # → skill router
|
|
152
|
+
├── .opencode/agents/ # → @general-free, @general-paid, @glm-minimal
|
|
153
|
+
├── modes/ # → _shared.md + skill modes
|
|
154
|
+
├── templates/ # → states.yml, portals.example.yml, cv-template.html
|
|
155
|
+
├── batch/batch-prompt.md # → batch worker prompt
|
|
156
|
+
├── batch/batch-runner.sh # → parallel orchestrator
|
|
157
|
+
│
|
|
158
|
+
└── node_modules/job-forge/ # the harness (from npm: `job-forge@2.x`)
|
|
151
159
|
```
|
|
152
160
|
|
|
153
161
|
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`.
|
|
154
162
|
|
|
155
|
-
**The harness itself** (this repo, what gets
|
|
163
|
+
**The harness itself** (this repo, what gets published as `job-forge` on npm):
|
|
156
164
|
|
|
157
165
|
```
|
|
158
166
|
JobForge/
|
|
159
|
-
├──
|
|
167
|
+
├── iso/ # ← SOURCE OF TRUTH for harness configuration
|
|
168
|
+
│ ├── instructions.md # → AGENTS.md + CLAUDE.md (Claude Code / Codex / Cursor)
|
|
169
|
+
│ ├── mcp.json # → .mcp.json + .cursor/mcp.json + .codex/config.toml + opencode.json
|
|
170
|
+
│ ├── agents/*.md # → .opencode/agents/*.md (general-free, general-paid, glm-minimal)
|
|
171
|
+
│ ├── commands/job-forge.md # → .opencode/skills/job-forge.md
|
|
172
|
+
│ └── config.json # per-harness top-level extras (e.g. opencode `instructions` array)
|
|
173
|
+
│
|
|
174
|
+
├── package.json # bin: job-forge, create-job-forge; prepack runs iso-harness
|
|
160
175
|
├── bin/
|
|
161
|
-
│ ├── job-forge.mjs
|
|
162
|
-
│ ├── sync.mjs
|
|
163
|
-
│ └── create-job-forge.mjs
|
|
164
|
-
├──
|
|
165
|
-
├──
|
|
166
|
-
├──
|
|
167
|
-
├──
|
|
168
|
-
├──
|
|
169
|
-
├──
|
|
170
|
-
|
|
171
|
-
├── tracker-lib.mjs
|
|
172
|
-
├──
|
|
173
|
-
├──
|
|
174
|
-
├──
|
|
175
|
-
├──
|
|
176
|
-
|
|
177
|
-
├── cv-sync-check.mjs # setup lint
|
|
178
|
-
├── dashboard/ # optional Go TUI
|
|
179
|
-
├── fonts/ # Space Grotesk + DM Sans (for PDF)
|
|
180
|
-
└── docs/ # architecture, setup, customization
|
|
176
|
+
│ ├── job-forge.mjs # CLI dispatcher (merge/verify/pdf/tokens/sync/...)
|
|
177
|
+
│ ├── sync.mjs # postinstall: creates symlinks in consumer project
|
|
178
|
+
│ └── create-job-forge.mjs # scaffolder
|
|
179
|
+
├── modes/ # _shared.md + 16 skill modes
|
|
180
|
+
├── templates/ # cv-template.html, portals.example.yml, states.yml
|
|
181
|
+
├── config/profile.example.yml # template for consumer's profile.yml
|
|
182
|
+
├── batch/{batch-prompt.md,batch-runner.sh} # batch orchestrator
|
|
183
|
+
├── scripts/
|
|
184
|
+
│ ├── token-usage-report.mjs # opencode cost analyzer
|
|
185
|
+
│ └── release/check-source.mjs # version gate for npm publish
|
|
186
|
+
├── tracker-lib.mjs / merge-tracker.mjs / dedup-tracker.mjs / verify-pipeline.mjs
|
|
187
|
+
├── normalize-statuses.mjs / generate-pdf.mjs / cv-sync-check.mjs
|
|
188
|
+
├── dashboard/ # optional Go TUI
|
|
189
|
+
├── fonts/ # Space Grotesk + DM Sans (for PDF)
|
|
190
|
+
├── docs/ # architecture, setup, customization
|
|
191
|
+
└── .github/workflows/ # quality.yml + release.yml (CI publish to npm)
|
|
181
192
|
```
|
|
182
193
|
|
|
194
|
+
All per-harness config trees (`.opencode/`, `.cursor/`, `.claude/`, `.codex/`, `CLAUDE.md`, `AGENTS.md`, `.mcp.json`, `opencode.json`) are **generated** from `iso/` by [`@razroo/iso-harness`](https://www.npmjs.com/package/@razroo/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.
|
|
195
|
+
|
|
183
196
|
## Documentation
|
|
184
197
|
|
|
185
198
|
Index and cross-links: [docs/README.md](docs/README.md).
|
package/bin/create-job-forge.mjs
CHANGED
|
@@ -117,7 +117,7 @@ const consumerPkg = {
|
|
|
117
117
|
'update-harness': 'npm update job-forge @razroo/opencode-model-fallback @razroo/gmail-mcp @geometra/mcp && job-forge sync && node -e "console.log(\'✅ harness at\', require(\'./package-lock.json\').packages[\'node_modules/job-forge\'].resolved)"',
|
|
118
118
|
},
|
|
119
119
|
dependencies: {
|
|
120
|
-
'job-forge': '
|
|
120
|
+
'job-forge': '^2.0.0',
|
|
121
121
|
// Model-fallback plugin: rotates agents through their fallback_models
|
|
122
122
|
// chain on rate-limit / 5xx errors so a rate-limited free-tier model
|
|
123
123
|
// doesn't wedge the whole flow. The chains live upstream in each
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -2,31 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
## Package architecture (v2.0.0+)
|
|
4
4
|
|
|
5
|
-
JobForge ships as an npm package. There are two kinds of repo involved:
|
|
5
|
+
JobForge ships as an npm package at [`job-forge`](https://www.npmjs.com/package/job-forge). There are two kinds of repo involved:
|
|
6
6
|
|
|
7
|
-
- **Harness** — this repo, `razroo/JobForge`.
|
|
8
|
-
- **Consumer project** — what users interact with day-to-day. Scaffolded via `npx create-job-forge <dir>`, or hand-authored with `job-forge` listed in `package.json` dependencies.
|
|
7
|
+
- **Harness** — this repo, `razroo/JobForge`. Published to npm. Contains `iso/` (single source of truth), modes, scripts, skill router, templates, fonts, dashboard, and bin entries. Per-harness config trees are **generated** from `iso/` by [`@razroo/iso-harness`](https://www.npmjs.com/package/@razroo/iso-harness) — gitignored here, baked into the tarball by `prepack` at publish time, and landed in consumer projects via symlinks.
|
|
8
|
+
- **Consumer project** — what users interact with day-to-day. Scaffolded via `npx --package=job-forge create-job-forge <dir>`, or hand-authored with `job-forge` listed in `package.json` dependencies.
|
|
9
9
|
|
|
10
|
-
The consumer's project root contains
|
|
10
|
+
The consumer's project root contains personal data plus symlinks into `node_modules/job-forge/`:
|
|
11
11
|
|
|
12
12
|
```
|
|
13
13
|
my-search/
|
|
14
|
-
├── package.json
|
|
15
|
-
├── opencode.json
|
|
16
|
-
├── cv.md
|
|
17
|
-
├── config/profile.yml
|
|
18
|
-
├── portals.yml
|
|
19
|
-
├── data/
|
|
20
|
-
├── reports/
|
|
21
|
-
├──
|
|
22
|
-
├──
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
├──
|
|
26
|
-
|
|
14
|
+
├── package.json # depends on "job-forge": "^2.0.0"
|
|
15
|
+
├── opencode.json # instructions: ["templates/states.yml"]
|
|
16
|
+
├── cv.md # personal
|
|
17
|
+
├── config/profile.yml # personal
|
|
18
|
+
├── portals.yml # personal
|
|
19
|
+
├── data/ # personal (gitignored)
|
|
20
|
+
├── reports/ # personal (gitignored)
|
|
21
|
+
├── AGENTS.md # personal overrides (opencode + codex)
|
|
22
|
+
├── CLAUDE.md # personal overrides (Claude Code); @-imports CLAUDE.harness.md
|
|
23
|
+
│
|
|
24
|
+
│ # ↓ symlinks regenerated on every `npm install` by bin/sync.mjs
|
|
25
|
+
├── AGENTS.harness.md # → node_modules/job-forge/AGENTS.md
|
|
26
|
+
├── CLAUDE.harness.md # → node_modules/job-forge/CLAUDE.md
|
|
27
|
+
├── .mcp.json # → Claude Code MCP config
|
|
28
|
+
├── .codex/config.toml # → Codex MCP config
|
|
29
|
+
├── .cursor/mcp.json # → Cursor MCP config
|
|
30
|
+
├── .cursor/rules/main.mdc # → Cursor always-apply rule
|
|
31
|
+
├── .opencode/skills/job-forge.md # → skill router
|
|
32
|
+
├── .opencode/agents/ # → @general-free, @general-paid, @glm-minimal
|
|
33
|
+
├── modes/ # → mode files
|
|
34
|
+
├── templates/ # → states.yml, portals.example.yml, cv-template.html
|
|
35
|
+
├── batch/batch-prompt.md # → batch worker prompt
|
|
36
|
+
├── batch/batch-runner.sh # → parallel orchestrator
|
|
37
|
+
└── node_modules/job-forge/ # harness, installed from npm
|
|
27
38
|
```
|
|
28
39
|
|
|
29
|
-
Symlinks are created by the harness's `postinstall` hook (`bin/sync.mjs`) on every `npm install`.
|
|
40
|
+
Symlinks are created by the harness's `postinstall` hook (`bin/sync.mjs`) on every `npm install`. Real files at those paths are preserved — if a user locally customizes a mode file, the sync skips that symlink and warns.
|
|
30
41
|
|
|
31
42
|
The consumer's `opencode.json` loads a small set of stable files as always-present instructions: `AGENTS.harness.md` (harness operational rules), `templates/states.yml` (canonical application states), `modes/_shared.md` (scoring model), and `cv.md` (the candidate's CV). Caching these in the prefix means agents never Read them as tool calls. Churning content (score calibration anchors, specific mode files) stays out of `instructions` and is Read on demand.
|
|
32
43
|
|
|
@@ -34,7 +45,9 @@ The skill router (`.opencode/skills/job-forge.md`) loads mode and data files on
|
|
|
34
45
|
|
|
35
46
|
**Cost-tiered subagents** live in `.opencode/agents/` (`general-free`, `general-paid`, `glm-minimal`) — the orchestrator delegates procedural work to free-tier models and reserves paid models for quality-sensitive writing. See [MODEL-ROUTING.md](MODEL-ROUTING.md) for the routing architecture, why it exists, and how to customize.
|
|
36
47
|
|
|
37
|
-
**
|
|
48
|
+
**Multi-harness support.** Because `iso/` is the single source of truth, publishing ships config for OpenCode, Cursor, Claude Code, and Codex in one tarball. Consumers run any of `opencode`, `cursor`, `claude`, or `codex` in the project and each picks up the shared MCP config + instructions via the symlinks above.
|
|
49
|
+
|
|
50
|
+
**Upgrading** the harness in a consumer project is `npm run update-harness` — pulls the latest `job-forge` from npm, refreshes the fallback plugin + pinned MCPs, re-runs symlink sync, and prints the resolved version.
|
|
38
51
|
|
|
39
52
|
## System Overview
|
|
40
53
|
|
package/docs/README.md
CHANGED
|
@@ -4,12 +4,12 @@ Guides for installing JobForge, understanding how pieces fit together, and tailo
|
|
|
4
4
|
|
|
5
5
|
## Install paths
|
|
6
6
|
|
|
7
|
-
JobForge ships
|
|
7
|
+
JobForge ships on npm as [`job-forge`](https://www.npmjs.com/package/job-forge) (v2.0.0+). Pick the path that matches your goal:
|
|
8
8
|
|
|
9
9
|
| Path | Who it's for | How |
|
|
10
10
|
|------|--------------|-----|
|
|
11
|
-
| **A — Scaffold a personal project** | Most users. You want a job search project with the harness in `node_modules`, updatable via `npm update job-forge`. | `npx
|
|
12
|
-
| **B — Clone the harness directly** | Contributors and hackers working on modes, scripts, or the scoring model. Personal files are gitignored. | `git clone https://github.com/razroo/JobForge.git && cd JobForge && npm install` |
|
|
11
|
+
| **A — Scaffold a personal project** | Most users. You want a job search project with the harness in `node_modules`, updatable via `npm update job-forge`. | `npx --package=job-forge create-job-forge my-search && cd my-search && npm install` |
|
|
12
|
+
| **B — Clone the harness directly** | Contributors and hackers working on `iso/`, modes, scripts, or the scoring model. Personal files are gitignored. | `git clone https://github.com/razroo/JobForge.git && cd JobForge && npm install && npm run build:config` |
|
|
13
13
|
|
|
14
14
|
See [SETUP.md](SETUP.md) for both paths.
|
|
15
15
|
|
package/docs/SETUP.md
CHANGED
|
@@ -10,16 +10,22 @@
|
|
|
10
10
|
|
|
11
11
|
### Path A — Scaffold a personal project (recommended)
|
|
12
12
|
|
|
13
|
-
JobForge is
|
|
13
|
+
JobForge is published on npm as [`job-forge`](https://www.npmjs.com/package/job-forge). Use the scaffolder to create a new project that keeps only your personal data (CV, profile, portals, tracker) while the harness (modes, skills, scripts, per-harness configs) lives in `node_modules/job-forge` and updates with one command.
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
# 1. Scaffold
|
|
17
|
-
npx
|
|
17
|
+
npx --package=job-forge create-job-forge my-job-search
|
|
18
18
|
cd my-job-search
|
|
19
19
|
|
|
20
|
-
# 2. Install the harness
|
|
21
|
-
# creates symlinks
|
|
22
|
-
#
|
|
20
|
+
# 2. Install the harness. `npm install` fetches job-forge@^2.0.0 from npm;
|
|
21
|
+
# its postinstall hook creates symlinks into your project root for:
|
|
22
|
+
# .opencode/{skills/job-forge.md, agents/}
|
|
23
|
+
# .cursor/mcp.json, .cursor/rules/main.mdc
|
|
24
|
+
# .mcp.json (Claude Code MCP config)
|
|
25
|
+
# .codex/config.toml (Codex MCP config)
|
|
26
|
+
# AGENTS.harness.md, CLAUDE.harness.md
|
|
27
|
+
# modes/, templates/
|
|
28
|
+
# batch/{batch-prompt.md, batch-runner.sh, README.md}
|
|
23
29
|
npm install
|
|
24
30
|
|
|
25
31
|
# 3. Fill in personal files
|
|
@@ -41,18 +47,25 @@ Paste a job URL or run `/job-forge` to see the command menu.
|
|
|
41
47
|
To **upgrade the harness** later:
|
|
42
48
|
|
|
43
49
|
```bash
|
|
44
|
-
npm update job-forge # pulls latest
|
|
50
|
+
npm update job-forge # pulls latest job-forge from the npm registry
|
|
45
51
|
npx job-forge sync # refresh symlinks if anything drifted
|
|
46
52
|
```
|
|
47
53
|
|
|
54
|
+
Or simpler, via the scaffolded script: `npm run update-harness` (also refreshes the fallback plugin + pinned MCPs, reprints the resolved version).
|
|
55
|
+
|
|
48
56
|
### Path B — Clone the harness directly
|
|
49
57
|
|
|
50
|
-
Use this if you want to hack on the harness itself (
|
|
58
|
+
Use this if you want to hack on the harness itself (edit `iso/`, tune the scoring model, add modes, contribute back). Personal files are gitignored.
|
|
51
59
|
|
|
52
60
|
```bash
|
|
53
61
|
git clone https://github.com/razroo/JobForge.git
|
|
54
62
|
cd JobForge
|
|
55
63
|
npm install
|
|
64
|
+
npm run build:config # regenerate per-harness trees from iso/ (CLAUDE.md,
|
|
65
|
+
# AGENTS.md, .mcp.json, .codex/, .cursor/, .opencode/,
|
|
66
|
+
# opencode.json) — these are gitignored but materialized
|
|
67
|
+
# locally so OpenCode/Cursor/Claude Code/Codex can read
|
|
68
|
+
# them while you develop
|
|
56
69
|
|
|
57
70
|
# Add personal files the same way as Path A
|
|
58
71
|
cp config/profile.example.yml config/profile.yml
|
|
@@ -60,7 +73,7 @@ cp templates/portals.example.yml portals.yml
|
|
|
60
73
|
# Create cv.md in the project root
|
|
61
74
|
```
|
|
62
75
|
|
|
63
|
-
When you're inside this repo, the `postinstall` symlink step is a no-op (detected and skipped). All npm scripts run the harness code directly. The repo's `opencode.json` at the project root registers the same Geometra + Gmail MCPs as the scaffolder ships to consumers.
|
|
76
|
+
When you're inside this repo, the `postinstall` symlink step is a no-op (detected and skipped). All npm scripts run the harness code directly. The repo's generated `opencode.json` at the project root registers the same Geometra + Gmail MCPs as the scaffolder ships to consumers. Re-run `npm run build:config` any time you edit something under `iso/`; `prepack` runs the same build automatically at publish time so tarballs always match `iso/`.
|
|
64
77
|
|
|
65
78
|
## Personalization
|
|
66
79
|
|