2.7 KiB
jobbsok
Local-first, read-only job search workspace for a single operator, packaged as
a marketplace plugin. The build brief is the contract:
docs/build-brief.md — read it whole before writing any file.
Context
One plugin for Claude Code and Claude Cowork. Cowork is the day-to-day operator
surface; Claude Code is the development surface. Skills under skills/*/SKILL.md
(no commands/), deterministic logic in scripts/*.py, MCP servers declared in
.mcp.json (browser over CDP, read-only IMAP) — both optional; every skill
degrades to manual paste.
Operator-facing content (skill output, sak.md, drafts) is Norwegian bokmål.
Code, identifiers, file names and docs are English.
Invariants
- This repo has a PUBLIC remote (
open/jobbsok).STATE.mdis LOCAL-ONLY and gitignored from the first commit. Repos on a private remote track theirs. - Read-only against external sites. No form submit, no send, no apply.
- No credential handling. Attaches to an already-authenticated browser over CDP. Mail credentials only via environment variables.
- Human approval before any profile mutation.
laeringproposes diffs. - Local-only data. Workspace never committed; no telemetry.
- Untrusted content stays untrusted. Every listing and email body passes
scripts/guard_ingest.py(llm-ingestion-guard, pinned tag) before persist. The trust boundary is the write. - Append-only logs.
beslutninger.jsonl,logg.jsonl: corrections are new entries, never edits. - No autonomous scheduling. Nothing polls, nothing runs in background.
- Build in milestone order (brief §11, M1–M6). Do not skip ahead.
${CLAUDE_PLUGIN_ROOT}for every intra-plugin path. Never hardcode.
Commands
python3 -m pytest tests/ # zero-network tests (brief §12)
Release
Polyrepo rule: a version bump is not finished until the tag vX.Y.Z is pushed
and the catalog ref is bumped to it. Use release-plugin.mjs, never a
hand-edited ref. The catalog README entry for a new plugin is added by hand once.
Communication patterns
Linking to local files
When pointing to local files in responses, always use markdown link syntax with a descriptive name:
- Use
[Human-friendly name](file:///absolute/path)— never barefile:///...URLs or autolinks<file://...>. - Always use absolute paths. Never
~/or relative paths. - For multiple files, render as a bullet list of named markdown links.
Why: bare file:// URLs only render the first as clickable across multiple lines. Named markdown links make each entry independently clickable and look cleaner.
Example: