@digitalunicorn/workflow-skill
v4.3.0
Published
CLI to install and update the Digital Unicorn Claude Code workflow skill set into a repository.
Maintainers
Readme
DU Workflow Skill
A Claude Code skill suite for the full software-development loop — create Jira tickets, write quality commits, push with automatic worklog, open and review GitLab MRs, and audit your logged hours. Everything is driven by per-developer config, so the same skills work across projects and team members.
Table of Contents
- Installation
- CLI Reference
- Daily Workflow
- Skills Reference
- Skill Details
- Environment Variables
- File Structure
- Changelog
Installation
Requirements
- Claude Code CLI
- Node.js 18+ and
giton PATH (used by the installer) - GitLab access to this repository — it is internal to Digital Unicorn
- Jira access (Atlassian API token)
- GitLab access (Personal Access Token, scope
api) python3andcurlon PATH (used by the Jira/GitLab API calls)
1. Install the skills with the CLI
Run this from the root of the project you want the skills in:
npx @digitalunicorn/workflow-skill installThe CLI clones this repository over your existing git credentials, so sign in to GitLab once beforehand. If you are not on the team the clone is rejected and the CLI tells you so instead of installing anything.
To upgrade later, run update — it backs up anything it overwrites:
npx @digitalunicorn/workflow-skill updateSee CLI Reference for every command and flag.
2. Create your personal config
config.env is gitignored — each developer keeps their own copy. The CLI
installs the example but never writes config.env itself, so your tokens are
never touched by an update.
cp .claude/config.env.example .claude/config.env
# then fill in your Jira/GitLab credentials and project settingsSee Environment Variables for every field.
3. Restart Claude Code
Restart Claude Code in the project so it picks up the new .claude/commands/,
then run /start-work to check everything is wired up.
CLI Reference
@digitalunicorn/workflow-skill installs and updates the skill set in any
repository. Nothing is bundled in the npm package — the skills are always
fetched from this GitLab repository, so update gets the current main.
| Command | What it does |
| --- | --- |
| install | Copies the skill set into this repository's .claude/ |
| update | Fetches the latest skills, backing up anything it overwrites |
| status | Shows the installed version, your local edits, and whether an update exists |
| list | Lists the available skills and what each one does |
| uninstall | Removes the installed skill files, keeping your personal config |
| Option | Applies to | Meaning |
| --- | --- | --- |
| -d, --dir <path> | all | Target repository (default: the current git repo root) |
| -r, --ref <ref> | all | Branch or tag to fetch (default: main) |
| --repo <url> | all | Skill repository URL (default: the internal DU repo) |
| -n, --dry-run | install, update, uninstall | Show what would change without writing |
| -y, --yes | uninstall | Skip the confirmation prompt |
| --remote | list | Read the remote instead of the installed copy |
| --offline | status | Skip the remote check |
| --json | list | Machine-readable output on stdout |
What the CLI will and will not touch
It manages .claude/commands/ and .claude/config.env.example. It records
a checksum of every file it writes in .claude/.du-skill-manifest.json, which
is how status can tell you which files you have edited by hand.
It never writes config.env, settings.local.json, task-state.json or
daily-reports/ — those are yours. Before overwriting or removing anything, it
copies the current version to .claude/.du-skill-backup-<timestamp>/, so an
update that goes wrong is always recoverable.
install also adds the personal files above to your .gitignore so tokens
cannot be committed by accident.
Working on a fork
Point the CLI at any repository that has a .claude/ directory:
# one-off
npx @digitalunicorn/workflow-skill install --repo https://git.example.com/me/skills.git
# or persist it for the shell session
export [email protected]:du-v3/du-workflow-skill.gitDU_SKILL_REPO and DU_SKILL_REF set the defaults; --repo and --ref
override them per run. Use the SSH URL if you authenticate to GitLab with a key
rather than a stored token.
Daily Workflow
Morning During the day Evening
────────────── ─────────────────── ─────────────────────────
/start-work → code... → /push
↓ /review-mine ↓
ticket + branch /commit work auto-logged to Jira
auto-created (quality pipeline) ↓
start date set /create-mr
↓
handoff comment → Jira
(what / impact / how to test)
↓
teammate /review-pr
Anytime: /check-worklog → verify each day hit 8h
/logwork → log a day manually
/daily-report → build the Slack-ready reportStep by step
1. Start a task — /start-work
Enter an existing ticket ID or describe a task to have one created. The skill estimates time, creates the branch, moves the ticket to In Progress, sets the Jira start/due dates, and records state for /push.
2. Self-review — /review-mine
Three independent agents review your uncommitted code from three angles and return concrete file:line issues.
3. Commit — /commit
A multi-step pipeline: quality checks → auto-fix → conventional commit message → pre-push gate → daily-report append.
4. Push + log work — /push
Auto-commits if needed, pushes, computes elapsed time from the recorded start_time, and logs the worklog to Jira after you confirm. Then opens the MR and posts the tester handoff comment.
5. Open an MR — /create-mr
Builds the title from commits, generates a description (commit list + test-plan checklist), and posts it to GitLab.
6. Hand over to QA — /handoff
/push already does this automatically once the MR exists. It posts one Jira comment per MR, written as prose for a tester: what was done, which existing areas it might affect, and how to verify it. Re-pushing edits that comment instead of adding another, so the ticket never fills up with one comment per commit.
7. Review a teammate's MR — /review-pr
Fetches the diff, reviews across the quality dimensions, and posts inline comments to GitLab.
8. Audit your hours — /check-worklog
Read-only check that each working day reached the required hours (default 8h), for today, a specific date, or a whole month.
Skills Reference
Task Management
| Skill | Description | Usage |
|---|---|---|
| /start-work | Start a task: create/select a Jira ticket, AI estimate, branch, In Progress, start/due dates | /start-work |
| /create-branch | Create a branch from a ticket (no estimation) | /create-branch |
| /create-jira-task | Create a Jira ticket with an ADF description | /create-jira-task |
Commit & Push
| Skill | Description | Usage |
|---|---|---|
| /commit | Full commit pipeline with quality checks + auto-fix | /commit |
| /push | Push code, compute elapsed time, auto-log to Jira | /push |
Worklog
| Skill | Description | Usage |
|---|---|---|
| /check-worklog | Read-only audit: did each working day hit the required hours? | /check-worklog [yesterday\|YYYY-MM-DD\|--month=YYYY-MM] [--total=8h] [--all-days] |
| /logwork | Log work for a day, distributed across that day's tickets | /logwork [yesterday\|YYYY-MM-DD] [--total=8h] [--start=09:30] [--lunch=12:00-13:00] |
| /daily-report | Build the Slack-ready daily report from the day's commits | /daily-report [yesterday\|YYYY-MM-DD] |
Building UI
| Skill | Description | Usage |
|---|---|---|
| /build-ui | Build a page from a design, following the page structure already used in this source | /build-ui <PageName> [--like <page>] [--design <figma-url\|path\|text>] |
Code Quality
| Skill | Description | Usage |
|---|---|---|
| /review-mine | Self-review uncommitted code from 3 angles before committing | /review-mine [staged\|HEAD~N] |
| /check-conventions | Score code against the 4-dimension quality checklist | /check-conventions [file\|module] |
| /smart-refactor | Refactor to raise the quality score across 4 dimensions | /smart-refactor [file\|module] |
Review & MR
| Skill | Description | Usage |
|---|---|---|
| /create-mr | Create a GitLab MR with auto-generated title + description | /create-mr [--draft] [--target <branch>] [--reviewer @user] |
| /handoff | Post/refresh the tester handoff comment on Jira for this branch's MR | /handoff |
| /review-pr | Review a teammate's MR, auto-post comments to GitLab | /review-pr <MR_URL> |
Testing & Docs
| Skill | Description | Usage |
|---|---|---|
| /create-test | Write unit tests for a single file | /create-test src/path/to/file.ts |
| /create-readme | Create a README for a module | /create-readme src/modules/payment |
| /update-readme | Refresh an existing README (preserves manual sections) | /update-readme src/modules/payment |
Skill Details
/start-work — Start a task
Flow:
- Enter an existing ticket ID, or a description to create one via
/create-jira-task. - AI estimates time (30 min – 8 h based on type: bug / feature / refactor).
- Maps the issue type to a branch type and creates
{type}/{TICKET_ID}-{kebab-description}off$PROJECT_BASE_BRANCH. - Transitions the ticket to In Progress.
- Sets the Jira start date to today (only if the ticket has none — never overwrites) and asks for a due date (default = start date; accepts
YYYY-MM-DDor+3d/+1w). - Records state to
.claude/task-state.jsonfor/push.
/start-work
> Ticket: PROJ-456 — Add payment modal
> Branch: feature/PROJ-456-add-payment-modal (base: dev)
> Estimate: 3h 30m | Start: 2026-06-04 | Due: 2026-06-04/commit — Commit pipeline
| Step | Description | |---|---| | 0 | Read the ticket ID from the branch name | | 1 | Analyze changes (git status, diff) | | 2 | Score code quality (4 dimensions) | | 3 | Auto-fix: Correctness → Design → Security → Efficiency | | 4 | Check test coverage | | 5 | Write a conventional commit message | | 6 | Pre-push: 10 sub-gate final check | | 7 | Append to the daily report | | 8 | Post a comment on the Jira ticket |
4 quality dimensions:
| Dimension | Example violations |
|---|---|
| Correctness | Unchecked nulls, wrong logic, missing types |
| Design | Functions > 30 lines, nesting > 3 levels, magic numbers |
| Security | Hardcoded secrets, sensitive data logged without __DEV__ |
| Efficiency | Inline objects in JSX, missing useCallback, unoptimized FlatList |
/push — Push and auto-log work
Flow:
- Validates the branch (rejects the base branch directly).
- Auto-runs
/commitif there are uncommitted changes. git push -u origin <branch>.- Computes elapsed time from
start_timein the state file. - Shows a time-distribution table → waits for confirmation.
- POSTs the worklog to Jira and updates the task state.
- Runs
/create-mr(idempotent — never duplicates an existing MR). - Posts the tester handoff comment on Jira for that MR.
Edge cases handled: multiple tickets at once, re-push (skips duplicate worklog), no ticket, corrupt state, negative elapsed (clock drift), wrong commit author.
/handoff — Tester handoff comment
Posts one Jira comment per MR aimed at BA, QA and PM — not developers, answering in plain prose: what changed, what still does not work, what else it might break, and how to verify it.
Developers already have the MR, so the comment deliberately omits file paths, build and lint output, commit stats, technical open questions and test-count scorecards. Those read as thorough while burying the parts only this comment provides.
It also states what is not wired up yet in the first paragraph, as something the reader will observe — "submitting valid credentials will not sign you in" rather than "no API integration". A half-finished slice handed over silently gets bug reports filed against working code, or worse, gets signed off as done.
Keyed by MR, not by ticket. Pushing again to the same MR edits the existing comment instead of appending a new one, so it always reflects the branch's current state and the ticket never accumulates one comment per push. A ticket with two MRs gets two comments, each maintained independently.
The impact section is built in two tiers: a mechanical scan finds which files import the changed files, then those consumers are translated into screens and flows a tester recognises. When a change cannot be traced to a named feature it says so plainly instead of guessing — a tester re-testing the wrong area is worse off than one reading "scope unclear".
/push runs this automatically. Call it directly when the automatic run failed (missing
token, network error), when the MR was created by hand, or after a rebase left the comment
stale. Re-running is always safe.
Skipped, not failed, when: there is no open MR for the branch (nothing is ready to test yet), or the Jira/GitLab tokens are unset. A handoff failure never fails the push.
/check-worklog — Audit logged hours (read-only)
Checks your real Jira worklogs (filtered by your JIRA_ASSIGNEE_ID) across all JIRA_PROJECT_KEYS and reports whether each working day reached WORK_HOURS (default 8h). It never writes — to fill a gap, run /logwork.
/check-worklog # today
/check-worklog yesterday
/check-worklog 2026-06-02 # a specific day
/check-worklog --month=2026-06 # per-day table for the month (weekends skipped)
/check-worklog --total=7h # override required hours/day
/check-worklog --month=2026-06 --all-days # also expect weekends to hit the targetMonth mode prints a Date | Day | Logged | Status table, marks short days, and lists them so you know which to top up.
/logwork — Log a day manually
/logwork # today
/logwork yesterday
/logwork 2026-06-02 # a specific date
/logwork --total=6h # override total hours
/logwork --start=09:30 # set the start time
/logwork --lunch=12:00-13:00 # exclude a lunch breakFlow: reads the daily report → computes per-ticket complexity (files / insertions / deletions) → distributes the day's hours proportionally in 15-minute buckets → shows a confirmation table → POSTs the worklog and (optionally) sets originalEstimate.
/build-ui — Build a page that matches the source
Builds a UI page from a design without letting the design dictate the file structure. The structure comes from the pages a dev already wrote in this repo; the design only fills it in.
The order is deliberate. Given a Figma frame, the fast path is to build it the way the design is organised — one file, sections in visual order — which yields a page that looks correct and fits nothing: different folder shape, naming, state pattern and styling from every other page in the source. So STEP 1 reads the source before any file is created and extracts the page skeleton: folder shape, container/presentational split, where state lives, styling approach, route registration, i18n handling, and which shared components already exist.
Two ways to learn the convention. With --like <page> it mirrors one reference page exactly —
use this when there is a known-good page to copy. Without it, the skill samples at least 3 recently
modified pages and derives the majority pattern, reporting the counts ("4/5 pages co-locate a
hooks/ folder") so a convention claim is never an unbacked guess. Aspects it cannot determine are
reported as unclear rather than invented.
Source wins on structure, design wins on appearance. A design that visually groups three unrelated blocks does not force one big component if this repo splits pages into children. When the design genuinely needs something the skeleton has no slot for, the skill extends it deliberately and records the deviation with a reason in its output — it never quietly starts a second convention.
It prints the file plan and then builds, matching how /commit runs here. It stops to ask only on a
page-name collision, an unclear folder or state pattern, or a new shared component that would
affect other pages. STEP 5 re-reads a peer page side by side and verifies each aspect, then runs the
project's real typecheck and lint scripts and reports their actual output.
Design input is optional: --design takes a Figma URL (read through the Figma MCP tools, reusing
Code Connect-mapped components where they exist), a screenshot path, or plain text. With no design it
builds the skeleton with explicit TODO(design) slots.
/review-pr — Review an MR
/review-pr https://gitlab.company.com/group/project/-/merge_requests/123
/review-pr # review the local diff
/review-pr --confirm # preview before postingSeverity levels: 🔴 BLOCKING (must fix) · 🟡 SHOULD IMPROVE · 🔵 SUGGESTION. Each issue is posted as its own discussion; auto-posts to GitLab when a URL is given.
Environment Variables
All settings live in .claude/config.env (gitignored). Copy config.env.example and fill these in:
Jira
| Variable | Description |
|---|---|
| JIRA_BASE_URL | e.g. https://your-company.atlassian.net |
| JIRA_EMAIL | Your Atlassian login email |
| JIRA_TOKEN | API token — create one here |
| JIRA_PROJECT_KEYS | Comma-separated project keys, e.g. PROJ,PROJ2 |
| JIRA_BOARD_IDS | Board IDs matching the project keys (same order/count) |
| JIRA_SPRINT_FIELD | Sprint custom field (Cloud: usually customfield_10020) |
| JIRA_START_DATE_FIELD | Start-date custom field (usually customfield_10015; due date uses the built-in duedate) |
| JIRA_ASSIGNEE_ID | Your accountId — used to auto-assign and to filter your worklogs |
Get your accountId:
curl -u "$JIRA_EMAIL:$JIRA_TOKEN" "$JIRA_BASE_URL/rest/api/3/myself" | python3 -c "import json,sys; print(json.load(sys.stdin)['accountId'])"
GitLab
| Variable | Description |
|---|---|
| GITLAB_BASE_URL | GitLab instance URL (self-hosted or https://gitlab.com) |
| GITLAB_TOKEN | Personal Access Token, scope api |
| GITLAB_DEFAULT_REVIEWER | Default MR reviewer username (optional) |
Role / Persona
| Variable | Description |
|---|---|
| DEV_ROLE | Persona for build skills, e.g. Senior React Native Developer |
| REVIEW_ROLE | Persona for review skills (review-pr, review-mine, check-conventions), e.g. Senior Tech Lead |
Project
| Variable | Description |
|---|---|
| PROJECT_NAME | Project name shown in skill descriptions |
| PROJECT_SRC_PATH | Relative path to the main source dir, e.g. src/modules |
| PROJECT_I18N_PATH | Path to the i18n directory (if multilingual) |
| PROJECT_BASE_BRANCH | Base branch for new branches and MRs, e.g. dev |
| PROJECT_STACK | rn | web | backend | generic (default rn) — selects the framework-specific quality checklist used by /check-conventions, /smart-refactor, /review-pr |
| WORK_HOURS | Required logged hours per working day (default 8), used by /check-worklog and /logwork |
File Structure
.claude/
├── config.env # your credentials + settings (gitignored)
├── config.env.example # template — copy this
├── settings.json # Claude Code tool permissions
├── task-state.json # active task state (gitignored)
├── daily-reports/ # auto-generated daily reports (gitignored)
│ └── YYYY-MM-DD.md
└── commands/
├── start-work.md
├── create-branch.md
├── create-jira-task.md
├── commit.md
├── push.md
├── check-worklog.md
├── logwork.md
├── daily-report.md
├── review-mine.md
├── review-pr.md
├── check-conventions.md
├── smart-refactor.md
├── build-ui.md
├── create-mr.md
├── handoff.md
├── create-test.md
├── create-readme.md
├── update-readme.md
├── confirm-prompt.md
└── _shared/ # shared modules reused across skills
├── _README.md
├── ai-checklist.md
├── anti-gaming.md
├── changelog.md
├── commit-step-5-message.md
├── commit-step-6-prepush.md
├── commit-step-7-8-report.md
├── jira-handoff.md
└── migration-v3.1.0.mdChangelog
Full history: .claude/commands/_shared/changelog.md.
| Version | Highlights |
|---|---|
| v4.3.0 | /build-ui — build UI pages against the structure already used in the source, not the design's own layout |
| v4.2.0 | /handoff tester comment — one per MR, edited on re-push; Jira commenting removed from the commit pipeline |
| v3.4.0 | Stack-aware quality checklist (PROJECT_STACK: rn / web / backend / generic) |
| v3.3.0 | /check-worklog audit; /start-work sets Jira start/due dates; base branch de-hardcoded |
| v3.2.0 | Accurate time tracking: AI estimate + auto-log via /push |
| v3.1.0 | Added /create-mr |
| v3.0.0 | Restored auto-post in /review-pr, softened noise filter |
| v2.0.0 | Modularized commit.md into _shared/ |
