From theclauu
Create Linear tickets proactively with dedup + collision detection. For intentional new work the engineer is starting — not for discovered follow-ups (use /theclauu:file-issue for those). Always asks whether the ticket should go to Work-In-Progress or TODO.
npx claudepluginhub artemis-xyz/theclauu --plugin theclauuThis skill uses the workspace's default tool permissions.
Single skill for Linear ticket workflows. Use when the engineer is *starting*
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Single skill for Linear ticket workflows. Use when the engineer is starting work that doesn't yet have a Linear ticket, or when you want to check the ticket-landscape before creating something.
For discovered follow-up work during an existing PR, use
/theclauu:file-issue instead — those fire fast, file a GitHub Issue, and
auto-promote to Linear on PR merge. This skill is for intentional, ticketed
work the engineer is committing to do.
========================================
Status: implemented (Slice 7, TheClauu v0.4.0+)
Default mode if the user invokes /theclauu:linear <description> with no
leading mode keyword.
Build a title (short, imperative, no trailing period) and description (structured) from the engineer's input + session context:
Branch: <git-branch-name or "no branch yet">
PR: <github-pr-url if one exists; else "none">
Intent: <one or two sentences from the engineer's description>
If the engineer hasn't given a description, ask for one before proceeding. Don't infer from random code state — the agent should know the user's intent, not guess.
Fire all four checks in parallel; they're independent.
2a. Linear dedup (open tickets on the data team, keyword-matched):
Use the plugin helper:
from bin.sources import linear as linear_src
tokens = linear_src.distinctive_tokens(f"{title} {description}")
matches = linear_src.search_tickets(token, team_id, tokens)
Present matches whose title shares ≥3 distinctive tokens with the intent (or whose full title is a substring of the intent). Skip the rest.
2b. Linear collision (in-progress by others on the same team):
collisions = linear_src.in_progress_by_others(token, team_id)
Client-side-filter by: title shares ≥2 distinctive tokens with the intent. These are collision warnings — flag louder than dedup:
⚠ collision: Sarah is actively working on ART-NNNN — "<title>" (updated <ago>)
URL: <url>
Check with her before starting; your ticket may be duplicate.
2c. Open PRs on Artemis-xyz repos (title/body match):
gh search prs --owner Artemis-xyz --state open --match title "<top 2-3 tokens>" --json repository,number,title,url,author
Surface any hit with ≥2 distinctive token overlap.
2d. discovered-by:theclauu GH Issues (staged dupes):
gh search issues --owner Artemis-xyz --label 'discovered-by:theclauu' --state open --json repository,number,title,url
An open discovered-by:theclauu issue whose title overlaps with the intent
likely means this work has already been queued and will auto-promote. Present
it and suggest waiting for the auto-promotion rather than double-filing.
Use AskUserQuestion with all distinct matches. Example:
Before creating, I found these:
⚠ collision — ART-1234 (Sarah, In Progress, updated 2h ago)
"Refactor SCD2 macro to accept attribute_hash"
~ dedup — ART-1120 (Backlog, updated 8d ago)
"SCD2 silent-loss audit"
~ staged GH — dbt#5410 (`discovered-by:theclauu`, open)
"fix change_id collisions in SCD2 bronze"
Options:
[1] Cancel — this is already being tracked
[2] Attach to ART-1234 (mark yourself as a collaborator, do not create new)
[3] Attach to ART-1120 (reopen or continue)
[4] Separate — create a new ticket regardless (I'll note the siblings)
Never pick a default. The intentional choice at creation time is the whole point of this skill.
Create as:
[1] Work-In-Progress — assigned to you, state = In Progress (start now)
[2] TODO — unassigned, state = Todo (triage first, start later)
[3] Skip — don't create
Fetch the team's state list + viewer ID (cached in config once resolved):
states = linear_src.get_team_states(token, team_id)
labels = linear_src.get_team_labels(token, team_id)
state_id = linear_src.pick_state_id(states, "started" if choice == 1 else "unstarted")
assignee_id = viewer_id if choice == 1 else None
# Optional: attach `theclauu-created` label if it exists on the team
theclauu_label = next((l for l in labels if l["name"] == "theclauu-created"), None)
label_ids = [theclauu_label["id"]] if theclauu_label else []
issue = linear_src.create_issue(
token=token,
team_id=team_id,
title=title,
description=description,
state_id=state_id,
assignee_id=assignee_id,
label_ids=label_ids,
)
If the theclauu-created label doesn't exist yet, don't create it silently
— just skip. The team admin can pre-create it in Linear once; afterwards
all future tickets auto-attach.
If config["linear_viewer_id"] is missing, resolve it via
linear_src.resolve_viewer(token) and persist to ~/.theclauu/config.json
via bin.config.write(). This happens once, transparently.
Output format:
Created: ART-NNNN — "<title>"
URL: <url>
State: In Progress (assigned to you) [or: Todo (unassigned)]
Then AskUserQuestion (only if state is In Progress AND no branch was set):
Create and switch to a branch for this ticket?
[1] Yes — `<engineer-handle>/ART-NNNN-<slug>`
[2] No — I'll handle it
If yes:
git checkout -b "<engineer-handle>/ART-NNNN-<slug>"
Where <slug> is the title, lowercased, non-alphanumerics → -, capped at
~30 chars.
If ~/.theclauu/pending-nudge.json exists and was the trigger for this
invocation, delete it. Don't double-prompt the engineer on the next session.
========================================
Status: not implemented yet (future v0.5). Placeholder.
Planned: walk the data team's Backlog/Todo tickets without assignees; agent proposes priorities + assignees based on keywords + author history; engineer confirms or adjusts.
========================================
Status: not implemented yet (future v0.5). Placeholder.
Planned: /theclauu:linear status ART-NNNN <args> — update state, assignee,
priority, labels on an existing ticket via issueUpdate mutation.
========================================
TheClauu fires the dedup/collision scan automatically in two situations. Neither path ever creates a ticket — both surface findings for the agent to show the user, and creation always requires explicit confirmation.
The UserPromptSubmit hook reads every user message and passes it through
bin/detect_new_work_intent.py. If the message shows new-work intent
("I want to build…", "let's refactor…", "going to implement…", etc.),
bin/scan_new_work.py runs a read-only Linear scan (dedup + collision)
with a 3-second timeout and prints a <theclauu-new-work-scan> advisory
block into the agent's context.
The advisory tells the agent to:
/theclauu:linear?"Detection is conservative — regex + stopword + question/past-tense/meta filters mean the scan only fires on clear new-work intent, not on questions or exploration. On non-matching prompts, the hook exits in <10ms with zero API calls.
If a session ends with work done but no ART-NNNN reference in the
branch, recent commits, or transcript, the SessionEnd hook writes
~/.theclauu/pending-nudge.json. The next session's SessionStart
surfaces a one-line nudge: "your last session did work in <branch>
without a Linear ticket — want me to file one?"
Engineers dismiss with /theclauu:linear dismiss (clears the marker
without creating a ticket) or by running this skill's new-ticket mode
(which clears the marker on success).
========================================
config["linear_team_id"] (data team). Multi-team
ticketing is v0.5.Branch: / PR: / Intent:.theclauu-created if the team has it; else skip silently.