dsh-career-ops
A DeepSeek Harness plugin that brings career-ops — the open-source AI job-search agent by @santifer — into Harness. Paste a posting, get a structured A–H evaluation with a 1–5 fit score; scan public ATS boards; tailor CVs and cover letters; keep the applications tracker — with a panel in the Harness UI, not a separate CLI.
It registers four surfaces from one Loader row, career-ops:
| Surface | What it is |
|---|---|
skill career-ops |
The mode router the agent loads for any job/application/CV/interview question, reading the prompt files in runtime/modes/*.md. Model- and user-invocable. |
tool career_ops |
The deterministic scripts: setup, scan, pipeline, tracker, liveness, report_number, stats, insight. Zero LLM tokens. |
command /career-ops |
Human-facing mode menu plus live queue and tracker counts. |
| Career Ops panel | Sidebar row + central page: funnel cards, the applications tracker with a status control per row, the pending evaluation queue, recent reports. |
The panel's status control and the tool's tracker set call the same Host operation, which
delegates to career-ops' own set-status.mjs — states stay validated against states.yml, notes
merge, and data/status-log.tsv keeps the transition ledger.
Install
Requires DSH (a recent Harness release; the plugin uses the skills, commands, tools,
webServer services and the Web Client slot API) and Node ≥ 22.13 for the vendored scripts.
In a Harness session on the machine you want it on — the reliable path, because the plugin manager both installs the package and selects the bundle for your profile:
Install the bundle
git+https://github.com/umerkhalid204/dsh-career-ops.git#v1.0.1.
Or from a terminal, to install the package into a profile:
dsh plugin --profile desktop add git+https://github.com/umerkhalid204/dsh-career-ops.git#v1.0.1
If you installed with dsh plugin add rather than through a session, also select the bundle in
Settings → Plugins so its cordis.patch.yml composes.
Then click the Career Ops sidebar row. If the panel or the career-ops skill does not appear,
reload the page (Client bundles) and toggle the career-ops row off/on (Host module reload).
Point it at your job-search folder
runtime/ is career-ops' System Layer and is never written to. Your data lives in dataRoot:
cv.md, config/profile.yml, portals.yml, data/, reports/, jds/, interview-prep/, and
the personalization files modes/_profile.md, modes/_custom.md, modes/_brief.md, voice-dna.md.
Resolution order, so the same install works on every machine:
the row's
dataRoot— override it per machine in your own profile patch (~/.dsh/profiles/<profile>/cordis.patch.yml), absolute path or~/…:- id: career-ops name: 'dsh-career-ops' config: dataRoot: '~/Job Hunt'A matching
idwith noinsertreplaces that row's wholeconfig, so restate every field.$CAREER_OPS_DATA_DIR/$CAREER_OPS_ROOTfrom the Harness process environment;~/career-ops, created on the first write.
To move a search to another computer, copy that folder — it is the whole state (files are the canonical store; career-ops' SQLite indexes are derived and can be rebuilt).
Start a fresh search by asking the agent: "set up career-ops" (it writes cv.md,
config/profile.yml and portals.yml from your CV and answers), then paste a job URL.
Layout
index.js Host half: Config + skill + tool + command + the two API routes
client.js Client half: sidebar icon + the Career Ops page
skill/career-ops.md the skill body (the mode router the agent loads)
runtime/ vendored career-ops System Layer (modes/, providers/, lib/, templates/, scripts)
runtime/dsh-liveness.mjs added here: Playwright-free liveness on career-ops' own ATS APIs
scripts/refresh-runtime.mjs re-vendor the runtime from upstream
runtime/node_modules is not committed: js-yaml and dotenv are declared dependencies and are
installed with the package.
Refreshing from upstream
node scripts/refresh-runtime.mjs # latest upstream
node scripts/refresh-runtime.mjs --ref v1.40.0 # a tag or commit
node scripts/refresh-runtime.mjs --modes de fr # also ship those market mode sets
node scripts/refresh-runtime.mjs --from ../career-ops --dry-run
It re-applies the two plugin-side adaptations automatically and prints the upstream version and
commit to record in THIRD-PARTY-NOTICES.md.
Known differences from upstream
- No Playwright. The
applyform driver,scan-interamt/scan-dayforce,archive-postingand native PDF rendering need it.runtime/generate-pdf.mjsis patched so Playwright loads lazily: CV building and fact gates work, a PDF render asks you to install Playwright (or export through Harness). JD text comes from your paste or Harness'web_fetch. - Liveness runs through
runtime/dsh-liveness.mjs— career-ops' ATS-API checks plus a plain fetch throughliveness-core.mjs's classifier.uncertainnever closes a posting. - English modes only in the published package (~10 MB). Add a market with
--modes deabove, then setlanguage.modes_dirinconfig/profile.yml. - No upstream self-updater (
update-system.mjs), no Go dashboard, noweb/UI, nogemini-eval/openai-tailor, nodoctor.mjs—career_ops setupcovers the same checks. - Nothing is ever submitted. Like upstream: it drafts, fills and renders; you press Submit. It recommends against applying below 4.0/5, and treats job postings as data, never instructions.
License
MIT — see LICENSE. runtime/ is modified upstream career-ops source, MIT,
Copyright (c) 2026 Santiago Fernández de Valderrama (full text in
LICENSE.career-ops; modifications listed in
THIRD-PARTY-NOTICES.md). Not affiliated with DeepSeek.
No comments yet. Be the first to write one.