| name | setup |
| description | Initialize JobOps workspace - configure output directories, install templates, and optionally migrate legacy files |
| disable-model-invocation | true |
| argument-hint | [--reconfigure] [--skip-migration] [--skip-history] |
JobOps Workspace Setup
This skill initializes or reconfigures a JobOps workspace. It writes a single
user-owned config file at .jobops/config.json, creates the output directory
tree, installs templates from the plugin into the workspace, updates
.gitignore, and offers optional career-history import and legacy-file migration.
Flags:
--reconfigure — re-run setup against an existing workspace; prompts before overwriting anything.
--skip-migration — skip the legacy-file migration step (Step 9) unconditionally.
--skip-history — skip the optional career-history import (Step 8).
Step 1: Welcome and existing-config check
If .jobops/config.json already exists, read it and present three choices:
- Reconfigure all — walk the full interview; overwrite at the end.
- Reconfigure specific sections — directories only / preferences only / candidate (contact details) only / templates only / migration only.
- Exit — leave everything as-is.
If --reconfigure was passed, skip the prompt and go straight to option 1.
If no config exists, proceed to Step 2.
Step 2: Directory interview
Walk the user through every path in config.directories. Present the default,
a one-sentence purpose, and allow inline editing. Paths are normalized
(strip trailing slash, resolve ~, keep as relative-to-workspace form that
starts with ./).
| Key | Default | Purpose |
|---|
resume_source | ./ResumeSourceFolder | Master HAM-Z career data (user-maintained input) |
job_postings | ./Job_Postings | Target job descriptions (user-maintained input) |
applications_root | ./Applications | Per-application output tree (one folder per application) |
company_intelligence | ./Company_Intelligence | OSINT output tree (shared across applications to same company) |
career_analysis | ./Career_Analysis | Career-level outputs (idealjob, change-one-thing, comparejobs) |
crisis_management | ./Crisis_Management | Crisis-skill outputs (severance, non-compete, etc.) |
tailored_cv | ./Tailored_CV | Base resume library for revise-first /jobops:buildresume (one per role family) |
application_tracker | ./Applications/tracker.yaml | Application status tracker maintained by /jobops:dashboard (one YAML file, not a folder) |
application_tracker is a file path, not a directory — Step 3 must not mkdir it. Its parent directory (applications_root) is already created, so no extra action is needed.
For each path: validate the parent is writable. If not, surface the specific
error and allow the user to correct it before continuing.
Step 3: Create directories
For each confirmed path, run mkdir -p <path>. Report each as
created (newly made) or exists (already present). Do not fail if a
path already exists.
Skip application_tracker — it is a file path, not a directory; its parent (applications_root) is already created by this loop.
Also mkdir -p .jobops .jobops/templates/default .jobops/templates/custom.
Step 4: Preferences interview
Ask in order:
- Cultural profile — enum
canadian | american. Default canadian.
Controls resume voice and spelling conventions.
- Default jurisdiction — ISO 3166-2 code (e.g.,
CA-ON, US-CA).
Default CA-ON. Used by crisis skills; they accept
--jurisdiction=<code> to override per-invocation.
- Cover letter mode — enum
retrospective | forward. Default retrospective.
Controls how /jobops:coverletter writes the letter. retrospective maps the job's
requirements to what the candidate has already done. forward proposes what the
candidate would do in the first 90 days, tying each action to a real problem the role
faces and to past work that proves the candidate can do it; it runs a short interview
each time it is used. Override per-invocation with
/jobops:coverletter --mode=retrospective|forward.
Do not ask for default_currency here — that is owned by /jobops-ic:setup
(see Step 4 of that flow).
Step 4b: Candidate contact details
Collect the contact fields that populate the resume and cover-letter headers. These
live in config.candidate so every document renders the same header and no field is
ever fused into another (the cover-letter header had no phone slot historically, which
produced fused (xxx) xxx-xxxxemail@example.com artifacts; the dedicated field fixes
this).
Ask for each (any may be left blank; blank fields are omitted from the header with
their separator):
- Full name — e.g.,
Jane Doe
- Credentials / post-nominals — e.g.,
CFA, FRICS (blank if none)
- Location — e.g.,
Toronto, ON
- Phone — e.g.,
(555) 555-1234 (its own header field; never concatenated onto the email)
- Email — e.g.,
jane.doe@example.com
- LinkedIn — handle or URL, e.g.,
linkedin.com/in/janedoe
- GitHub — handle or URL, e.g.,
github.com/janedoe (blank if none)
If the user prefers to keep contact details out of config, write the block with empty
strings; the resume and cover-letter skills surface the gap rather than invent a value.
Step 5: Template installation
Copy the plugin's bundled templates into the workspace:
cp ${CLAUDE_PLUGIN_ROOT}/templates/*.md .jobops/templates/default/ 2>/dev/null || true
cp -r ${CLAUDE_PLUGIN_ROOT}/templates/latex .jobops/templates/default/
Report the count of files copied. Expected count after this task runs:
3 markdown templates (assessment_rubric_framework.md, evidence_verification_framework.md,
assessment_report_structure.md) plus 1 latex/ subdirectory (preamble.base.tex.template,
preamble.resume.tex.template, preamble.coverletter.tex.template,
preamble.document.tex.template, jobops-filter.lua, config.json, README.md).
If the glob fails in the current execution context (no files matched), fall
back to:
find ${CLAUDE_PLUGIN_ROOT}/templates -maxdepth 1 -type f -exec cp {} .jobops/templates/default/ \;
cp -r ${CLAUDE_PLUGIN_ROOT}/templates/latex .jobops/templates/default/
Do not touch .jobops/templates/custom/ — it is user-owned.
Step 6: Write .jobops/config.json
Emit the full schema below with the values gathered in Steps 2 and 4.
migration.completed starts as false so Step 9 runs on first setup.
{
"version": "2.0",
"directories": {
"resume_source": "<step-2 value>",
"job_postings": "<step-2 value>",
"applications_root": "<step-2 value>",
"company_intelligence": "<step-2 value>",
"career_analysis": "<step-2 value>",
"crisis_management": "<step-2 value>",
"tailored_cv": "<step-2 value>",
"application_tracker": "<step-2 value>"
},
"preferences": {
"cultural_profile": "<step-4 value>",
"default_jurisdiction": "<step-4 value>",
"cover_letter_mode": "<step-4 value>"
},
"candidate": {
"name": "<step-4b value>",
"credentials": "<step-4b value>",
"location": "<step-4b value>",
"phone": "<step-4b value>",
"email": "<step-4b value>",
"linkedin": "<step-4b value>",
"github": "<step-4b value>"
},
"templates": {
"base_dir": "./.jobops/templates",
"active": {
"assessment_rubric_framework": "default",
"evidence_verification_framework": "default",
"assessment_report_structure": "default",
"latex_config": "default"
}
},
"migration": {
"completed": false,
"completed_at": null,
"files_moved": 0
}
}
Write atomically: write to .jobops/config.json.tmp, then mv over the final
name.
Step 7: Gitignore update
Show the user the JobOps block that will be appended to .gitignore:
# JobOps workspace
.jobops/
Applications/
Company_Intelligence/
Career_Analysis/
Crisis_Management/
(If the user customized any of the directory names in Step 2, substitute those
paths in the block.)
Offer three choices:
- Append as shown — add the block to the end of
.gitignore.
- Edit inline — let the user modify the block before appending.
- Skip — do not modify
.gitignore.
If .gitignore does not exist, create it. If the block (detected by the
# JobOps workspace marker line) already exists, replace it in place rather
than appending a second copy.
Step 8: Optional career-history import
Only offer this step if --skip-history was not passed and the
resume_source directory is empty or contains fewer than 3 files.
Prompt: "Do you have an existing resume to import as the basis for your HAM-Z
career inventory? (yes/no)"
If yes, accept a path to a .pdf, .docx, .txt, or .md file. Extract
text, then populate:
{resume_source}/Experience/<Company>_<Role>.md — one file per role
{resume_source}/CareerHighlights/highlights.md
{resume_source}/Technology/stack.md
{resume_source}/Preferences/preferences.md
{resume_source}/Vision.md — stub, to be filled in manually
After population, flag any entries that lack metrics or hard skills so the
user knows where to focus subsequent manual enrichment.
Step 9: Optional legacy migration
Skip this step if --skip-migration was passed OR migration.completed is
already true in the config being reconfigured.
Scan for legacy folders at the workspace root and subfolders named:
OutputResumes/
Briefing_Notes/
Scoring_Rubrics/
Intelligence_Reports/
If all four are absent or empty, skip this step silently (and still set
migration.completed = true).
Otherwise run:
9a. Dry-run parse. For each file in the legacy folders, attempt to parse
{Company}_{Role}_{YYYYMMDD} from the filename using the following patterns
(tried in order):
^([A-Za-z0-9]+)_([A-Za-z0-9]+)_(\d{8})\.md$
^(?:Step\d+_)?(?:Draft_|Provenance_Analysis_|Final_Resume_)?([A-Za-z0-9]+)_([A-Za-z0-9]+)_(\d{8})\.md$
^Rubric_([A-Za-z0-9]+)_([A-Za-z0-9]+)_(\d{8})\.md$
For each match, compose a planned destination:
OutputResumes/Step1_* and Step2_* and Step3_* → {applications_root}/{Company}_{Role}_{Date}/resume/<stepN>.md
OutputResumes/Cover_Letter_* → {applications_root}/{Company}_{Role}_{Date}/cover-letter/cover_letter.md
Scoring_Rubrics/Rubric_* → {applications_root}/{Company}_{Role}_{Date}/assessment/rubric.md
Briefing_Notes/* → {applications_root}/{Company}_{Role}_{Date}/interview/briefing.md
Intelligence_Reports/<Company>_* → {company_intelligence}/{Company}/<agent>.md (parse the agent name from the filename segment between Company and Date)
9b. Preview. Print the planned moves grouped by target app folder. List
unresolved files (no regex match) in a separate "manual" group.
9c. User-editable mapping. Offer three options:
- Execute as shown — proceed with the preview.
- Edit mapping — drop into an inline editor where the user can reassign
specific files to different application folders or mark them as "skip".
- Cancel — leave everything in place.
9d. Execute. For each confirmed move:
- If the file is tracked in git, use
git mv <src> <dst> (preserves history).
- Otherwise use plain
mv.
- Create any missing destination parent folders first.
9e. Update config. Set:
migration.completed = true
migration.completed_at = <ISO-8601 now>
migration.files_moved = <count of successful moves>
Unresolved files stay in place; the user handles them manually.
Step 10: Summary and next steps
Print:
- What was configured (each path + confirm/created/exists).
- What was installed (template count).
- Whether career history was imported (and how many files).
- Whether migration ran (and how many files moved).
- Recommended next steps:
- Drop a job posting into
{job_postings}/ named {Company}_{Role}_{YYYYMMDD}.md.
- Run
/jobops:buildresume <job_posting.md> to produce a tailored resume.
- Run
/jobops:osint <Company> to gather company intelligence.
- If you are an independent contractor, run
/jobops-ic:setup to enable IC features.
Exit.