@jaggerxtrm/specialists 3.2.0 → 3.2.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jaggerxtrm/specialists",
3
- "version": "3.2.0",
4
- "description": "OmniSpecialist \u2014 7-tool MCP orchestration layer powered by the Specialist System. Discover and execute .specialist.yaml files across project/user/system scopes via pi.",
3
+ "version": "3.2.1",
4
+ "description": "OmniSpecialist 7-tool MCP orchestration layer powered by the Specialist System. Discover and execute .specialist.yaml files across project/user/system scopes via pi.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
7
7
  "files": [
@@ -9,7 +9,7 @@ specialist:
9
9
 
10
10
  execution:
11
11
  mode: tool
12
- model: google-gemini-cli/gemini-3-flash-preview
12
+ model: anthropic/claude-haiku-4-5
13
13
  fallback_model: anthropic/claude-sonnet-4-6
14
14
  timeout_ms: 180000
15
15
  response_format: markdown
@@ -0,0 +1,87 @@
1
+ specialist:
2
+ metadata:
3
+ name: planner
4
+ version: 1.0.0
5
+ description: "Structured planning specialist for xtrm projects. Explores the
6
+ codebase (GitNexus + Serena), creates a phased bd issue board with rich
7
+ descriptions, and applies test-planning per layer. Outputs a ready-to-implement
8
+ epic: child issues created, dependencies wired, test issues generated. Fully
9
+ autonomous — give it a task description and get back an epic ID and first
10
+ task to claim."
11
+ category: workflow
12
+ tags: [planning, bd, issues, epic, gitnexus, test-planning]
13
+ updated: "2026-03-22"
14
+
15
+ execution:
16
+ mode: tool
17
+ model: anthropic/claude-sonnet-4-6
18
+ fallback_model: google-gemini-cli/gemini-3.1-pro-preview
19
+ timeout_ms: 600000
20
+ response_format: markdown
21
+ permission_required: HIGH
22
+
23
+ prompt:
24
+ system: |
25
+ You are the Planner specialist for xtrm projects.
26
+
27
+ Read the planning skill and follow its 6-phase workflow:
28
+
29
+ cat $skill_path
30
+
31
+ If $skill_path is not readable, fall back to this condensed workflow:
32
+ Phase 2 Explore codebase — GitNexus + Serena, read-only
33
+ Phase 3 Structure plan — phases, dependencies, CoT reasoning
34
+ Phase 4 Create bd issues — epic + child tasks, rich descriptions
35
+ Phase 5 Apply test-planning — test issues per layer (core/boundary/shell)
36
+ Phase 6 Output result — epic ID, all issue IDs, first task to claim
37
+
38
+ ## Background execution overrides
39
+
40
+ These replace the interactive behaviors in the skill:
41
+
42
+ - **Skip Phase 1 (clarification)**: the task prompt is fully specified —
43
+ proceed directly to Phase 2
44
+ - **Phase 4**: use `bd` CLI directly to create real issues — no approval step
45
+ - **Phase 5**: apply test-planning logic inline; do NOT invoke /test-planning
46
+ as a slash command
47
+ - **Phase 6**: do NOT claim any issue — output the structured result and stop
48
+
49
+ ## Required output format
50
+
51
+ End your response with this block (fill in real IDs):
52
+
53
+ ```
54
+ ## Planner result
55
+
56
+ Epic: <epic-id> — <epic title>
57
+ Children: <id1>, <id2>, <id3>, ...
58
+ Test issues: <test-id1>, <test-id2>, ...
59
+ First task: <id> — <title>
60
+
61
+ To start: bd update <first-task-id> --claim
62
+ ```
63
+
64
+ task_template: |
65
+ Plan the following task and create a bd issue board:
66
+
67
+ Task: $prompt
68
+
69
+ Working directory: $cwd
70
+ Planning skill: ~/.agents/skills/planning/SKILL.md
71
+
72
+ Follow the planning skill workflow (Phases 2–6). Explore the codebase with
73
+ GitNexus and Serena before creating any issues. Create real bd issues via
74
+ the bd CLI. Apply test-planning logic to add test issues per layer.
75
+ End with the structured "## Planner result" block.
76
+
77
+
78
+ capabilities:
79
+ required_tools: [bash, read, grep, glob]
80
+ external_commands: [bd, git]
81
+ diagnostic_scripts:
82
+ - "bd ready"
83
+ - "bd stats"
84
+
85
+ communication:
86
+ publishes: [epic_id, issue_ids, first_task, plan_summary]
87
+ subscribes: []
@@ -0,0 +1,56 @@
1
+ specialist:
2
+ metadata:
3
+ name: specialist-author
4
+ version: 1.0.0
5
+ description: "Guides an agent through writing a valid .specialist.yaml file using the schema reference and common error fixes."
6
+ category: authoring
7
+ updated: "2026-03-22"
8
+ tags: [authoring, yaml, specialist, schema, guide]
9
+
10
+ execution:
11
+ mode: tool
12
+ model: anthropic/claude-sonnet-4-6
13
+ timeout_ms: 180000
14
+ response_format: markdown
15
+ permission_required: LOW
16
+
17
+ prompt:
18
+ system: |
19
+ You are a specialist authoring assistant. Your job is to help agents and developers
20
+ write valid .specialist.yaml files that pass schema validation on the first attempt.
21
+
22
+ You have deep knowledge of the SpecialistSchema (Zod) and the runtime behavior of
23
+ SpecialistRunner. You know every required field, every valid enum value, and every
24
+ common pitfall.
25
+
26
+ When asked to create a specialist, you:
27
+ 1. Ask for (or infer from context): name, purpose, model, permission level
28
+ 2. Output a complete, annotated YAML
29
+ 3. Show the bundled schema validator command to verify it
30
+ 4. Highlight any fields the user should customize
31
+
32
+ When asked to fix a specialist, you:
33
+ 1. Identify the exact Zod error and map it to the fix table
34
+ 2. Output the corrected YAML section
35
+ 3. Explain why the original was invalid
36
+
37
+ task_template: |
38
+ $prompt
39
+
40
+ Working directory: $cwd
41
+
42
+ Use the specialist authoring guide (injected below) to produce or fix a
43
+ .specialist.yaml. Output the complete YAML and the validation command.
44
+
45
+ skills:
46
+ paths:
47
+ - skills/specialist-author/SKILL.md
48
+
49
+ capabilities:
50
+ diagnostic_scripts:
51
+ - bun skills/specialist-author/scripts/validate-specialist.ts specialists/<name>.specialist.yaml
52
+
53
+ communication:
54
+ publishes: [specialist_yaml, validation_command]
55
+
56
+ beads_integration: auto
@@ -0,0 +1,53 @@
1
+ specialist:
2
+ metadata:
3
+ name: sync-docs
4
+ version: 1.0.0
5
+ description: "Audits and syncs project documentation: detects drift, extracts bloated README sections, updates CHANGELOG, and validates docs/ frontmatter."
6
+ category: documentation
7
+ updated: "2026-03-22"
8
+ tags: [docs, readme, changelog, drift, audit, sync]
9
+
10
+ execution:
11
+ mode: tool
12
+ model: anthropic/claude-sonnet-4-6
13
+ fallback_model: google-gemini-cli/gemini-3-flash-preview
14
+ timeout_ms: 300000
15
+ response_format: markdown
16
+ permission_required: LOW
17
+
18
+ prompt:
19
+ system: |
20
+ You are a documentation sync specialist. You audit and fix project documentation
21
+ to keep it in sync with code reality.
22
+
23
+ Follow the sync-docs 5-phase workflow injected in your skill context:
24
+ Phase 1: Gather context (recent changes, bd issues, git log)
25
+ Phase 2: Detect docs/ drift (drift_detector.py)
26
+ Phase 3: Analyze structure (doc_structure_analyzer.py)
27
+ Phase 4: Execute fixes (extract, scaffold, update, changelog)
28
+ Phase 5: Validate (validate_doc.py, final drift scan)
29
+
30
+ **Audit vs Execute:**
31
+ - If the prompt says "audit", "check", "report", or "what's stale" — stop after Phase 3.
32
+ - Only run Phase 4 fixes when the prompt explicitly asks for changes.
33
+
34
+ **Script paths:** Use `~/.agents/skills/sync-docs/scripts/` for global install.
35
+
36
+ task_template: |
37
+ $prompt
38
+
39
+ Working directory: $cwd
40
+
41
+ Follow the sync-docs workflow from your injected skill. Start with Phase 1 context
42
+ gathering, then drift detection, then structure analysis. Report findings before
43
+ making any changes unless the task explicitly asks for fixes.
44
+
45
+ skills:
46
+ paths:
47
+ - ~/.agents/skills/sync-docs/SKILL.md
48
+
49
+ communication:
50
+ output_to: .specialists/sync-docs-report.md
51
+ publishes: [docs_audit, drift_report, changelog_update]
52
+
53
+ beads_integration: auto
@@ -0,0 +1,78 @@
1
+ specialist:
2
+ metadata:
3
+ name: xt-merge
4
+ version: 1.0.0
5
+ description: "Drains the xt worktree PR queue in FIFO order: lists open xt/ PRs sorted by creation time, checks CI status on the oldest, merges it with --rebase --delete-branch, then rebases all remaining branches onto the new default branch and force-pushes them. Handles rebase conflicts, CI re-triggering, and reports final queue state."
6
+ category: workflow
7
+ tags: [git, pr, merge, worktree, xt, rebase, ci]
8
+ updated: "2026-03-22"
9
+
10
+ execution:
11
+ mode: tool
12
+ model: anthropic/claude-sonnet-4-6
13
+ fallback_model: google-gemini-cli/gemini-3-flash-preview
14
+ timeout_ms: 300000
15
+ response_format: markdown
16
+ permission_required: MEDIUM
17
+
18
+ prompt:
19
+ system: |
20
+ You are a PR merge specialist for xt worktree workflows.
21
+
22
+ Your job is to drain the queue of open PRs from xt worktree sessions. These PRs
23
+ were created by `xt end` — each branch was rebased onto origin/main at the time
24
+ it was pushed, so they form an ordered queue that must be merged FIFO.
25
+
26
+ ## FIFO ordering
27
+
28
+ Merge the oldest-created PR first. After each merge, main advances and all
29
+ remaining branches must be rebased onto the new main before their CI results
30
+ are meaningful. Merging out of order increases conflict surface unnecessarily.
31
+
32
+ ## Your workflow
33
+
34
+ 1. List open PRs: `gh pr list --state open --json number,title,headRefName,createdAt,isDraft`
35
+ Filter for branches starting with "xt/", sort by createdAt ascending.
36
+ Skip draft PRs.
37
+
38
+ 2. Check CI on the head PR: `gh pr checks <number>`
39
+ Do NOT merge if checks are pending or failing. Report status and stop.
40
+
41
+ 3. Merge the head PR:
42
+ `gh pr merge <number> --rebase --delete-branch`
43
+ Always use --rebase for linear history. Always --delete-branch to clean up remote.
44
+
45
+ 4. Rebase all remaining xt/ branches onto the new main:
46
+ ```
47
+ git fetch origin main
48
+ git checkout xt/<branch>
49
+ git rebase origin/main
50
+ git push origin xt/<branch> --force-with-lease
51
+ ```
52
+ Repeat in queue order. If a rebase produces conflicts, stop and report the
53
+ conflicted files with enough context for the user to resolve them.
54
+
55
+ 5. Repeat from step 2 until the queue is empty.
56
+
57
+ ## Constraints
58
+
59
+ - Never merge a PR with failing or pending CI.
60
+ - Never use --squash or --merge; always --rebase.
61
+ - Never force-push without --force-with-lease.
62
+ - If you hit a rebase conflict you cannot safely resolve, stop and show the
63
+ conflicted files. Do not guess at conflict resolution.
64
+ - Report the queue state (PR number, branch, CI status) before each merge action.
65
+
66
+ task_template: |
67
+ Drain the xt worktree PR merge queue.
68
+
69
+ $prompt
70
+
71
+ Working directory: $cwd
72
+
73
+ List all open PRs from xt/ branches, sort oldest-first, check CI on the oldest,
74
+ merge it if green, rebase the remaining branches onto the new main, and repeat
75
+ until the queue is empty. Report final state when done.
76
+
77
+ communication:
78
+ output_to: .specialists/merge-prs-result.md
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env node
2
- // beads-close-memory-prompt — Claude Code PostToolUse hook
3
- // After `bd close`: injects a short reminder into Claude's context to capture
4
- // knowledge and consider underused beads features.
5
- // Output to stdout is shown to Claude as additional context.
6
- //
7
- // Installed by: specialists install
8
-
9
- import { readFileSync, existsSync } from 'node:fs';
10
- import { join } from 'node:path';
11
-
12
- let input;
13
- try {
14
- input = JSON.parse(readFileSync(0, 'utf8'));
15
- } catch {
16
- process.exit(0);
17
- }
18
-
19
- // Only fire on Bash tool
20
- if (input.tool_name !== 'Bash') process.exit(0);
21
-
22
- const cmd = (input.tool_input?.command ?? '').trim();
23
-
24
- // Only fire when the command is `bd close ...`
25
- if (!/\bbd\s+close\b/.test(cmd)) process.exit(0);
26
-
27
- // Only fire in projects that use beads
28
- const cwd = input.cwd ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
29
- if (!existsSync(join(cwd, '.beads'))) process.exit(0);
30
-
31
- // Inject reminder into Claude's context
32
- process.stdout.write(
33
- '\n[beads] Issue(s) closed. Before moving on:\n\n' +
34
- ' Knowledge worth keeping?\n' +
35
- ' bd remember "key insight from this work"\n' +
36
- ' bd memories <keyword> -- search what is already stored\n\n' +
37
- ' Discovered related work while implementing?\n' +
38
- ' bd create --title="..." --deps=discovered-from:<id>\n\n' +
39
- ' Underused features to consider:\n' +
40
- ' bd dep add <a> <b> -- link blocking relationships between issues\n' +
41
- ' bd graph -- visualize issue dependency graph\n' +
42
- ' bd orphans -- issues referenced in commits but still open\n' +
43
- ' bd preflight -- PR readiness checklist before gh pr create\n' +
44
- ' bd stale -- issues not touched recently\n'
45
- );
46
-
47
- process.exit(0);
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env node
2
- // beads-commit-gate — Claude Code PreToolUse hook
3
- // Blocks `git commit` when in_progress beads issues still exist.
4
- // Forces: close issues first, THEN commit.
5
- // Exit 0: allow | Exit 2: block (stderr shown to Claude)
6
- //
7
- // Installed by: specialists install
8
-
9
- import { execSync } from 'node:child_process';
10
- import { readFileSync, existsSync } from 'node:fs';
11
- import { join } from 'node:path';
12
-
13
- let input;
14
- try {
15
- input = JSON.parse(readFileSync(0, 'utf8'));
16
- } catch {
17
- process.exit(0);
18
- }
19
-
20
- const tool = input.tool_name ?? '';
21
- if (tool !== 'Bash') process.exit(0);
22
-
23
- const cmd = input.tool_input?.command ?? '';
24
- if (!/\bgit\s+commit\b/.test(cmd)) process.exit(0);
25
-
26
- const cwd = input.cwd ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
27
- if (!existsSync(join(cwd, '.beads'))) process.exit(0);
28
-
29
- let inProgress = 0;
30
- let summary = '';
31
- try {
32
- const output = execSync('bd list --status=in_progress', {
33
- encoding: 'utf8',
34
- cwd,
35
- stdio: ['pipe', 'pipe', 'pipe'],
36
- timeout: 8000,
37
- });
38
- inProgress = (output.match(/in_progress/g) ?? []).length;
39
- summary = output.trim();
40
- } catch {
41
- process.exit(0);
42
- }
43
-
44
- if (inProgress > 0) {
45
- process.stderr.write(
46
- '🚫 BEADS GATE: Close open issues before committing.\n\n' +
47
- `Open issues:\n${summary}\n\n` +
48
- 'Next steps:\n' +
49
- ' 3. bd close <id1> <id2> ... ← you are here\n' +
50
- ' 4. git add <files> && git commit -m "..."\n' +
51
- ' 5. git push -u origin <feature-branch>\n' +
52
- ' 6. gh pr create --fill && gh pr merge --squash\n' +
53
- ' 7. git checkout master && git reset --hard origin/master\n'
54
- );
55
- process.exit(2);
56
- }
57
-
58
- process.exit(0);
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env node
2
- // beads-edit-gate — Claude Code PreToolUse hook
3
- // Blocks file edits when no beads issue is in_progress.
4
- // Only active in projects with a .beads/ directory.
5
- // Exit 0: allow | Exit 2: block (stderr shown to Claude)
6
- //
7
- // Installed by: specialists install
8
-
9
- import { execSync } from 'node:child_process';
10
- import { readFileSync, existsSync } from 'node:fs';
11
- import { join } from 'node:path';
12
-
13
- let input;
14
- try {
15
- input = JSON.parse(readFileSync(0, 'utf8'));
16
- } catch {
17
- process.exit(0);
18
- }
19
-
20
- const cwd = input.cwd ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
21
- if (!existsSync(join(cwd, '.beads'))) process.exit(0);
22
-
23
- let inProgress = 0;
24
- try {
25
- const output = execSync('bd list --status=in_progress', {
26
- encoding: 'utf8',
27
- cwd,
28
- stdio: ['pipe', 'pipe', 'pipe'],
29
- timeout: 8000,
30
- });
31
- inProgress = (output.match(/in_progress/g) ?? []).length;
32
- } catch {
33
- process.exit(0);
34
- }
35
-
36
- if (inProgress === 0) {
37
- process.stderr.write(
38
- '🚫 BEADS GATE: No active issue — create one before editing files.\n\n' +
39
- ' bd create --title="<what you\'re doing>" --type=task --priority=2\n' +
40
- ' bd update <id> --status=in_progress\n\n' +
41
- 'Full workflow (do this every session):\n' +
42
- ' 1. bd create + bd update in_progress ← you are here\n' +
43
- ' 2. Edit files / write code\n' +
44
- ' 3. bd close <id> close when done\n' +
45
- ' 4. git add <files> && git commit\n' +
46
- ' 5. git push -u origin <feature-branch>\n' +
47
- ' 6. gh pr create --fill && gh pr merge --squash\n' +
48
- ' 7. git checkout master && git reset --hard origin/master\n'
49
- );
50
- process.exit(2);
51
- }
52
-
53
- process.exit(0);
@@ -1,52 +0,0 @@
1
- #!/usr/bin/env node
2
- // beads-stop-gate — Claude Code Stop hook
3
- // Blocks the agent from stopping when in_progress beads issues remain.
4
- // Exit 0: allow stop | Exit 2: block stop (stderr shown to Claude)
5
- //
6
- // Installed by: specialists install
7
-
8
- import { execSync } from 'node:child_process';
9
- import { readFileSync, existsSync } from 'node:fs';
10
- import { join } from 'node:path';
11
-
12
- let input;
13
- try {
14
- input = JSON.parse(readFileSync(0, 'utf8'));
15
- } catch {
16
- process.exit(0);
17
- }
18
-
19
- const cwd = input.cwd ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
20
- if (!existsSync(join(cwd, '.beads'))) process.exit(0);
21
-
22
- let inProgress = 0;
23
- let summary = '';
24
- try {
25
- const output = execSync('bd list --status=in_progress', {
26
- encoding: 'utf8',
27
- cwd,
28
- stdio: ['pipe', 'pipe', 'pipe'],
29
- timeout: 8000,
30
- });
31
- inProgress = (output.match(/in_progress/g) ?? []).length;
32
- summary = output.trim();
33
- } catch {
34
- process.exit(0);
35
- }
36
-
37
- if (inProgress > 0) {
38
- process.stderr.write(
39
- '🚫 BEADS STOP GATE: Unresolved issues — complete the session close protocol.\n\n' +
40
- `Open issues:\n${summary}\n\n` +
41
- 'Session close protocol:\n' +
42
- ' 3. bd close <id1> <id2> ... close all in_progress issues\n' +
43
- ' 4. git add <files> && git commit -m "..." commit your changes\n' +
44
- ' 5. git push -u origin <feature-branch> push feature branch\n' +
45
- ' 6. gh pr create --fill create PR\n' +
46
- ' 7. gh pr merge --squash merge PR\n' +
47
- ' 8. git checkout master && git reset --hard origin/master\n'
48
- );
49
- process.exit(2);
50
- }
51
-
52
- process.exit(0);
@@ -1,90 +0,0 @@
1
- #!/usr/bin/env node
2
- // Claude Code PreToolUse hook — block writes and direct master pushes
3
- // Exit 0: allow | Exit 2: block (message shown to user)
4
- //
5
- // Installed by: specialists install
6
-
7
- import { execSync } from 'node:child_process';
8
- import { readFileSync } from 'node:fs';
9
-
10
- let branch = '';
11
- try {
12
- branch = execSync('git branch --show-current', {
13
- encoding: 'utf8',
14
- stdio: ['pipe', 'pipe', 'pipe'],
15
- }).trim();
16
- } catch {}
17
-
18
- // Not in a git repo or not on a protected branch — allow
19
- if (!branch || (branch !== 'main' && branch !== 'master')) {
20
- process.exit(0);
21
- }
22
-
23
- let input;
24
- try {
25
- input = JSON.parse(readFileSync(0, 'utf8'));
26
- } catch {
27
- process.exit(0);
28
- }
29
-
30
- const tool = input.tool_name ?? '';
31
-
32
- const WRITE_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
33
-
34
- if (WRITE_TOOLS.has(tool)) {
35
- process.stderr.write(
36
- `⛔ You are on '${branch}' — never edit files directly on master.\n\n` +
37
- 'Full workflow:\n' +
38
- ' 1. git checkout -b feature/<name> ← start here\n' +
39
- ' 2. bd create + bd update in_progress track your work\n' +
40
- ' 3. Edit files / write code\n' +
41
- ' 4. bd close <id> && git add && git commit\n' +
42
- ' 5. git push -u origin feature/<name>\n' +
43
- ' 6. gh pr create --fill && gh pr merge --squash\n' +
44
- ' 7. git checkout master && git reset --hard origin/master\n'
45
- );
46
- process.exit(2);
47
- }
48
-
49
- // Block direct commits and pushes to master — use feature branches + gh pr create/merge
50
- if (tool === 'Bash') {
51
- const cmd = (input.tool_input?.command ?? '').trim().replace(/\s+/g, ' ');
52
-
53
- if (/^git commit/.test(cmd)) {
54
- process.stderr.write(
55
- `⛔ Don't commit directly to '${branch}' — use a feature branch.\n\n` +
56
- 'Full workflow:\n' +
57
- ' 1. git checkout -b feature/<name> ← start here\n' +
58
- ' 2. bd create + bd update in_progress track your work\n' +
59
- ' 3. Edit files / write code\n' +
60
- ' 4. bd close <id> && git add && git commit\n' +
61
- ' 5. git push -u origin feature/<name>\n' +
62
- ' 6. gh pr create --fill && gh pr merge --squash\n' +
63
- ' 7. git checkout master && git reset --hard origin/master\n'
64
- );
65
- process.exit(2);
66
- }
67
-
68
- if (/^git push/.test(cmd)) {
69
- const tokens = cmd.split(' ');
70
- const lastToken = tokens[tokens.length - 1];
71
- const explicitMaster = /^(master|main)$/.test(lastToken) || /:(master|main)$/.test(lastToken);
72
- const impliedMaster = tokens.length <= 3 && (branch === 'main' || branch === 'master');
73
- if (explicitMaster || impliedMaster) {
74
- process.stderr.write(
75
- `⛔ Don't push directly to '${branch}' — use the PR workflow.\n\n` +
76
- 'Next steps:\n' +
77
- ' 5. git push -u origin <feature-branch> ← push your branch\n' +
78
- ' 6. gh pr create --fill create PR\n' +
79
- ' gh pr merge --squash merge it\n' +
80
- ' 7. git checkout master sync master\n' +
81
- ' git reset --hard origin/master\n\n' +
82
- 'If you\'re not on a feature branch yet:\n' +
83
- ' git checkout -b feature/<name> (then re-commit and push)\n'
84
- );
85
- process.exit(2);
86
- }
87
- }
88
- }
89
-
90
- process.exit(0);