jobhunt-kit 0.2.0

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.
Files changed (50) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +14 -0
  3. package/AGENTS.md +23 -0
  4. package/CLAUDE.md +5 -0
  5. package/README.md +122 -0
  6. package/bin/jobhunt-kit.mjs +95 -0
  7. package/installer-assets/gitignore.txt +22 -0
  8. package/installer-assets/runtime-lock.json +492 -0
  9. package/installer-assets/workspace-lock.json +495 -0
  10. package/package.json +52 -0
  11. package/plugins/jobhunt-kit/.claude-plugin/plugin.json +9 -0
  12. package/plugins/jobhunt-kit/.codex-plugin/plugin.json +18 -0
  13. package/plugins/jobhunt-kit/THIRD_PARTY.md +18 -0
  14. package/plugins/jobhunt-kit/package-lock.json +492 -0
  15. package/plugins/jobhunt-kit/package.json +14 -0
  16. package/plugins/jobhunt-kit/references/cli.md +125 -0
  17. package/plugins/jobhunt-kit/references/cover-guidance.md +24 -0
  18. package/plugins/jobhunt-kit/references/hirify/LICENSE +202 -0
  19. package/plugins/jobhunt-kit/references/hirify/NOTICE +2 -0
  20. package/plugins/jobhunt-kit/references/hirify/SKILL.md +139 -0
  21. package/plugins/jobhunt-kit/references/hirify/reference.md +286 -0
  22. package/plugins/jobhunt-kit/references/matching.md +28 -0
  23. package/plugins/jobhunt-kit/references/resume-guidance.md +47 -0
  24. package/plugins/jobhunt-kit/references/storage.md +120 -0
  25. package/plugins/jobhunt-kit/references/workflow.md +89 -0
  26. package/plugins/jobhunt-kit/scripts/cli.mjs +9 -0
  27. package/plugins/jobhunt-kit/scripts/commands.mjs +157 -0
  28. package/plugins/jobhunt-kit/scripts/extract-resume.mjs +27 -0
  29. package/plugins/jobhunt-kit/scripts/hirify.mjs +31 -0
  30. package/plugins/jobhunt-kit/scripts/profile.mjs +79 -0
  31. package/plugins/jobhunt-kit/scripts/resume.mjs +92 -0
  32. package/plugins/jobhunt-kit/scripts/send-packet.mjs +36 -0
  33. package/plugins/jobhunt-kit/scripts/setup.mjs +25 -0
  34. package/plugins/jobhunt-kit/scripts/tracker.mjs +332 -0
  35. package/plugins/jobhunt-kit/skills/job-apply/SKILL.md +61 -0
  36. package/plugins/jobhunt-kit/skills/job-profile/SKILL.md +33 -0
  37. package/plugins/jobhunt-kit/skills/job-resume/SKILL.md +29 -0
  38. package/plugins/jobhunt-kit/skills/job-search/SKILL.md +39 -0
  39. package/plugins/jobhunt-kit/skills/job-track/SKILL.md +30 -0
  40. package/plugins/jobhunt-kit/templates/cover-letter.md +17 -0
  41. package/plugins/jobhunt-kit/templates/intake.md +62 -0
  42. package/plugins/jobhunt-kit/templates/policy.json +6 -0
  43. package/plugins/jobhunt-kit/templates/profile.json +29 -0
  44. package/plugins/jobhunt-kit/templates/profile.md +21 -0
  45. package/plugins/jobhunt-kit/templates/resume-review.md +30 -0
  46. package/plugins/jobhunt-kit/templates/scheduled-search.md +21 -0
  47. package/scripts/check-package.mjs +62 -0
  48. package/tests/commands.test.mjs +143 -0
  49. package/tests/installer.test.mjs +52 -0
  50. package/tests/tracker.test.mjs +180 -0
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "personal",
3
+ "interface": {
4
+ "displayName": "Personal"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "jobhunt-kit",
9
+ "source": {
10
+ "source": "local",
11
+ "path": "./plugins/jobhunt-kit"
12
+ },
13
+ "policy": {
14
+ "installation": "AVAILABLE",
15
+ "authentication": "ON_INSTALL"
16
+ },
17
+ "category": "Productivity"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "jobhunt-kit-marketplace",
3
+ "owner": {
4
+ "name": "Jobhunt Kit contributors"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "jobhunt-kit",
9
+ "source": "./plugins/jobhunt-kit",
10
+ "description": "Candidate intake, resume review, Hirify search and local tracking",
11
+ "version": "0.2.0"
12
+ }
13
+ ]
14
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,23 @@
1
+ # Jobhunt Kit template
2
+
3
+ This repository is a reusable template, not the owner's job search. Do not populate a
4
+ real profile, call Hirify account/search APIs, apply, or schedule tasks while developing
5
+ the template. Use temporary directories and clearly fictional fixtures for validation.
6
+
7
+ When the user requests a job search, initialize their local data through job-profile.
8
+ Keep personal files under local/ (gitignored), never in plugins/ or examples/.
9
+
10
+ The portable plugin is plugins/jobhunt-kit. For job-search use, read the relevant entry:
11
+
12
+ - skills/job-profile/SKILL.md — initialize/update candidate and reusable answers.
13
+ - skills/job-resume/SKILL.md — evidence-based resume review.
14
+ - skills/job-search/SKILL.md — bounded Hirify search and matching.
15
+ - skills/job-apply/SKILL.md — cover letter, approval, sending, manual handoff.
16
+ - skills/job-track/SKILL.md — local statuses, reports and optional schedule setup.
17
+
18
+ All paths above are relative to plugins/jobhunt-kit. Shared rules are in
19
+ references/workflow.md. SQLite is authoritative for vacancy/application history;
20
+ profile.json is authoritative for candidate facts. Markdown summaries are derived.
21
+
22
+ Use `npm test` for offline checks. Never test sending on real vacancies. Do not push
23
+ candidate files. Installing a plugin does not authorize applications or account changes.
package/CLAUDE.md ADDED
@@ -0,0 +1,5 @@
1
+ # Jobhunt Kit
2
+
3
+ Read AGENTS.md for project scope and skill routing. The portable plugin is
4
+ plugins/jobhunt-kit; its skills and references work without a particular agent vendor.
5
+ This checkout is a universal template. Do not infer a candidate from the repository owner.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Jobhunt Kit
2
+
3
+ ```sh
4
+ npx jobhunt-kit install
5
+ ```
6
+
7
+ Поиск работы вместе с AI-агентом: профиль кандидата, проверка резюме, подбор вакансий
8
+ через Hirify, сопроводительные письма и история откликов.
9
+
10
+ Нужны **Node.js 24+, Git и Codex или Claude Code**. Установщик создаст папку
11
+ `my-jobhunt` и установит зависимости. Чтобы выбрать другую папку, добавьте путь
12
+ в конце команды: `install ./my-folder`.
13
+
14
+ ## Начало работы
15
+
16
+ 1. Откройте `my-jobhunt` в агенте.
17
+ 2. Напишите: **«Инициализируй мой профиль поиска работы»**. Агент запросит резюме,
18
+ уточнит опыт, предпочтения и условия поиска.
19
+ 3. В терминале этой папки выполните `npm run hirify -- login` для входа в Hirify.
20
+ 4. После подтверждения профиля попросите: **«Найди до пяти новых подходящих вакансий»**.
21
+ 5. Выберите вакансию и попросите подготовить отклик. Перед отправкой агент запросит
22
+ согласование.
23
+
24
+ Страны, роли и формат занятости задаются в профиле. Для независимых профилей
25
+ используйте отдельные рабочие папки.
26
+
27
+ ## Возможности
28
+
29
+ | Навык | Что делает |
30
+ |---|---|
31
+ | [job-profile](plugins/jobhunt-kit/skills/job-profile/SKILL.md) | Собирает профиль, предпочтения и ответы на вопросы анкет |
32
+ | [job-resume](plugins/jobhunt-kit/skills/job-resume/SKILL.md) | Проверяет содержание, читаемость и соответствие резюме выбранным ролям |
33
+ | [job-search](plugins/jobhunt-kit/skills/job-search/SKILL.md) | Подбирает до пяти новых подходящих вакансий за запуск и объясняет выбор |
34
+ | [job-apply](plugins/jobhunt-kit/skills/job-apply/SKILL.md) | Готовит письмо и отправляет согласованный отклик через Hirify |
35
+ | [job-track](plugins/jobhunt-kit/skills/job-track/SKILL.md) | Ведёт историю, обновляет статусы и помогает настроить поиск по расписанию |
36
+
37
+ По умолчанию каждый отклик согласуется отдельно. Автоматическую отправку можно
38
+ включить с ограничением срока и количества откликов. Для внешних форм агент готовит
39
+ ссылку, письмо и ответы, а отправку выполняете вы.
40
+
41
+ При отправке через Hirify используется выбранный профиль сервиса. Локальный файл
42
+ резюме автоматически туда не загружается. О приглашениях и ответах рекрутеров
43
+ сообщайте агенту, чтобы он обновил статусы.
44
+
45
+ ## Команды
46
+
47
+ Запускайте из установленной папки:
48
+
49
+ ```sh
50
+ npx jobhunt-kit doctor
51
+ npx jobhunt-kit profile init
52
+ npx jobhunt-kit resume ./resume.pdf
53
+ npx jobhunt-kit profile check
54
+ npx jobhunt-kit search
55
+ npx jobhunt-kit track
56
+ npx jobhunt-kit report
57
+ ```
58
+
59
+ `resume` извлекает текст PDF, DOCX, TXT или Markdown и готовит материалы для проверки
60
+ агентом. `search` собирает контекст для агента, который выполняет поиск и оценивает
61
+ вакансии. Команды также позволяют управлять профилем, черновиками и статусами.
62
+
63
+ [Справочник команд](plugins/jobhunt-kit/references/cli.md).
64
+
65
+ ## Локальные данные
66
+
67
+ Профиль, резюме и история хранятся в `local/jobhunt-kit/`:
68
+
69
+ | Путь | Содержимое |
70
+ |---|---|
71
+ | `profile.json` | Факты, предпочтения и ответы кандидата |
72
+ | `policy.json` | Условия поиска и согласования откликов |
73
+ | `history.sqlite` | История поисков, вакансий и откликов |
74
+ | `resumes/` | Версии резюме |
75
+ | `materials/` | Письма, ответы и материалы проверки |
76
+ | `reports/latest.md` | Сводный отчёт |
77
+
78
+ Папка `local/` исключена из Git. Храните личные файлы в ней; для резервной копии
79
+ сохраняйте всю папку при остановленных процессах. Данные на диске не зашифрованы.
80
+
81
+ ## Подключение как плагина
82
+
83
+ В установленной рабочей папке навыки доступны через инструкции для агента.
84
+ При необходимости их можно подключить отдельно как плагин.
85
+
86
+ **Codex** — из корня установленной папки:
87
+
88
+ ```sh
89
+ codex plugin marketplace add .
90
+ codex plugin add jobhunt-kit@personal
91
+ ```
92
+
93
+ После установки начните новую сессию. `personal` — имя каталога плагинов,
94
+ включённого в шаблон.
95
+
96
+ **Claude Code** — для текущей сессии:
97
+
98
+ ```sh
99
+ claude --plugin-dir ./plugins/jobhunt-kit
100
+ ```
101
+
102
+ Вызов навыка: `/jobhunt-kit:job-profile`. Для постоянной установки используйте
103
+ `/plugin marketplace add .`, затем `/plugin install jobhunt-kit@jobhunt-kit-marketplace`.
104
+
105
+ При отдельной установке плагина агент подготовит локальные зависимости во время
106
+ инициализации профиля. Вход в Hirify выполняется отдельно.
107
+
108
+ ## Разработка
109
+
110
+ ```sh
111
+ npm ci --ignore-scripts
112
+ npm test
113
+ npm run check
114
+ ```
115
+
116
+ Тесты работают с вымышленными данными и не отправляют реальные отклики.
117
+
118
+ Руководства: [формат данных](plugins/jobhunt-kit/references/storage.md),
119
+ [проверка резюме](plugins/jobhunt-kit/references/resume-guidance.md),
120
+ [сопроводительные письма](plugins/jobhunt-kit/references/cover-guidance.md).
121
+
122
+ Автор этого шаблона никак не аффилирован с Hirify.
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, writeFileSync, realpathSync } from 'node:fs';
3
+ import { dirname, join, relative, resolve } from 'node:path';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
+ import { spawnSync } from 'node:child_process';
6
+
7
+ const SOURCE = resolve(dirname(fileURLToPath(import.meta.url)), '..');
8
+ const roots = ['bin', 'installer-assets', 'plugins/jobhunt-kit', 'scripts', 'tests',
9
+ 'AGENTS.md', 'CLAUDE.md', 'README.md', 'package.json',
10
+ '.agents/plugins/marketplace.json', '.claude-plugin/marketplace.json'];
11
+ function collect(path) {
12
+ const stat = lstatSync(path);
13
+ if (stat.isSymbolicLink()) throw new Error(`Symlink in template: ${path}`);
14
+ if (!stat.isDirectory()) return [path];
15
+ return readdirSync(path).filter(n => !['node_modules', '__pycache__', '.git'].includes(n))
16
+ .flatMap(n => collect(join(path, n)));
17
+ }
18
+ function noSymlinks(path) {
19
+ let current = resolve(path);
20
+ while (true) {
21
+ if (existsSync(current) && lstatSync(current).isSymbolicLink()) throw new Error(`Destination contains a symlink: ${current}`);
22
+ const parent = dirname(current);
23
+ if (parent === current) break;
24
+ current = parent;
25
+ }
26
+ }
27
+ export function install(destination, { source = SOURCE, installDependencies = true } = {}) {
28
+ if (Number(process.versions.node.split('.')[0]) < 24) throw new Error('Node.js 24 or newer is required');
29
+ const target = resolve(destination);
30
+ source = resolve(source);
31
+ if (target === source || !relative(source, target).startsWith('..')) throw new Error('Choose a destination outside the installer package');
32
+ const files = new Map();
33
+ for (const root of roots) for (const path of collect(join(source, root))) files.set(relative(source, path), path);
34
+ // npm omits package-lock.json and may omit .gitignore; ship them under explicit asset names.
35
+ files.set('.gitignore', join(source, 'installer-assets/gitignore.txt'));
36
+ files.set('package-lock.json', join(source, 'installer-assets/workspace-lock.json'));
37
+ files.set('plugins/jobhunt-kit/package-lock.json', join(source, 'installer-assets/runtime-lock.json'));
38
+ const pending = [];
39
+ for (const [name, input] of files) {
40
+ const output = join(target, name);
41
+ noSymlinks(output);
42
+ let parent = dirname(output);
43
+ while (parent !== dirname(parent)) {
44
+ if (existsSync(parent) && !lstatSync(parent).isDirectory()) throw new Error(`Destination directory is a file: ${parent}`);
45
+ parent = dirname(parent);
46
+ }
47
+ if (existsSync(output)) {
48
+ if (!lstatSync(output).isFile() || !readFileSync(output).equals(readFileSync(input))) {
49
+ throw new Error(`Existing file differs; nothing copied: ${output}. Choose an empty folder or keep your existing installation.`);
50
+ }
51
+ } else pending.push([input, output]);
52
+ }
53
+ for (const [input, output] of pending) {
54
+ mkdirSync(dirname(output), { recursive: true });
55
+ copyFileSync(input, output);
56
+ }
57
+ if (installDependencies) {
58
+ const options = { cwd: target, stdio: 'inherit', windowsHide: true };
59
+ const result = process.platform === 'win32'
60
+ ? spawnSync('cmd.exe', ['/d', '/s', '/c', 'npm ci --ignore-scripts --no-audit --no-fund'], options)
61
+ : spawnSync('npm', ['ci', '--ignore-scripts', '--no-audit', '--no-fund'], options);
62
+ if (result.error || result.status !== 0) throw new Error(`Template copied to ${target}, but dependencies were not installed. Retry the same init command. ${result.error?.message || ''}`);
63
+ }
64
+ const binDir = join(target, 'node_modules', '.bin');
65
+ noSymlinks(binDir);
66
+ noSymlinks(join(binDir, 'jobhunt-kit.cmd'));
67
+ noSymlinks(join(binDir, 'jobhunt-kit'));
68
+ mkdirSync(binDir, { recursive: true });
69
+ writeFileSync(join(binDir, 'jobhunt-kit.cmd'), '@echo off\r\nnode "%~dp0..\\..\\bin\\jobhunt-kit.mjs" %*\r\n');
70
+ writeFileSync(join(binDir, 'jobhunt-kit'), '#!/bin/sh\nexec node "$(dirname "$0")/../../bin/jobhunt-kit.mjs" "$@"\n', { mode: 0o755 });
71
+ return { directory: target, copied: pending.length, dependencies_installed: installDependencies };
72
+ }
73
+ export async function main(args) {
74
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
75
+ console.log('Usage: jobhunt-kit <command> [arguments] [--workspace dir | --data dir]\n\ninstall [directory] Install template (default: ./my-jobhunt)\ninit <directory> Alias with an explicit destination\nprofile init|show|check Initialize/view/validate local profile\nprofile save --input file Save profile and clear confirmation\nprofile confirm --note text Record explicit candidate confirmation\nresume [file] Import file, fingerprint and mechanical checks\nresume check|reviewed Inspect file / record agent review (--input file)\nsearch [plan] Prepare context for agent; no live search\nsearch start|event|record|finish Persist search operations (--input file)\napply preview|export|begin slug Review/export/reserve application\napply prepare|approve|send|finish|resolve --input file\ntrack list|show slug|status slug --input file\nhistory | runs | report Inspect history or generate Markdown report\npolicy show|set --input file Inspect/set application policy\nschedule --input file Generate scheduler prompt; does not schedule\ndoctor Check local setup without network\n\nNode.js 24+ required. Default data: ./local/jobhunt-kit. Only apply send performs a live application call.');
76
+ return;
77
+ }
78
+ if (!['init', 'install'].includes(args[0])) {
79
+ const { runCommand } = await import('../plugins/jobhunt-kit/scripts/commands.mjs');
80
+ const result = runCommand(args);
81
+ console.log(JSON.stringify(result, null, 2));
82
+ if (result && Object.hasOwn(result, 'valid') && result.valid === false) process.exitCode = 1;
83
+ if (result?.attempt_id && Object.hasOwn(result, 'exit_code')) process.exitCode = result.exit_code ?? 1;
84
+ return;
85
+ }
86
+ if (args.length > 2 || (args[0] === 'init' && !args[1]) || args[1]?.startsWith('-')) {
87
+ throw new Error('Usage: jobhunt-kit install [directory] (default: ./my-jobhunt), or jobhunt-kit init <directory>');
88
+ }
89
+ const result = install(args[1] || './my-jobhunt');
90
+ console.log(`\nJobhunt Kit ready: ${result.directory}\nCopied files: ${result.copied}\nOpen this folder in Codex or Claude Code and ask: use job-profile to initialize my profile.\nWhen needed, sign in yourself from that folder: npm run hirify -- login\nNo profile, schedule, search or application was created.`);
91
+ }
92
+ if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
93
+ try { await main(process.argv.slice(2)); }
94
+ catch (e) { console.error(`jobhunt-kit: ${e.message}`); process.exitCode = 1; }
95
+ }
@@ -0,0 +1,22 @@
1
+ node_modules/
2
+ *.log
3
+ .env
4
+ .DS_Store
5
+
6
+ # All candidate information and generated materials stay local.
7
+ local/
8
+ .env.*
9
+ !.env.example
10
+ **/node_modules/
11
+ *.sqlite*
12
+ *.db
13
+ *.db-*
14
+ *.pdf
15
+ *.docx
16
+ *.doc
17
+ *.rtf
18
+ *.zip
19
+ .claude/settings.local.json
20
+ __pycache__/
21
+ .tmp/
22
+ *.tgz