skill-creator
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-09
- Stars
- ★ 344
- Forks
- 7
01 前言 Front Matter
- name
- commit-skill
- description
- Commit a skill authored in this workspace to the liferay-portal repository, collapsing the workspace's duplicated agent trees into the repository's symlinked layout. Use when the user asks to commit, contribute, or upstream a skill, and as the handoff from `author-skill`.
02 资源文件 17
- 参考文档agents/analyzer.md10.1 KB
- 参考文档agents/comparator.md7.1 KB
- 参考文档agents/grader.md8.8 KB
- 资产文件assets/eval_review.html6.9 KB
- 脚本eval-viewer/generate_review.py16.0 KB
- 参考文档eval-viewer/viewer.html43.9 KB
- 许可证LICENSE.txt11.1 KB
- 参考文档references/schemas.md11.8 KB
- 脚本scripts/__init__.py—
- 脚本scripts/aggregate_benchmark.py14.0 KB
- 脚本scripts/generate_report.py12.5 KB
- 脚本scripts/improve_description.py10.9 KB
- 脚本scripts/package_skill.py4.1 KB
- 脚本scripts/quick_validate.py3.9 KB
- 脚本scripts/run_eval.py11.2 KB
- 脚本scripts/run_loop.py13.3 KB
- 脚本scripts/utils.py1.6 KB
03 SKILL.md 正文
Commit Skill
Take a skill that exists only in this workspace and commit it to liferay-portal/workspaces/liferay-sample-workspace, the source the published skill pack is built from.
The finish line is a local commit on a fresh branch. There is no push and no pull request — the user sends it for review themselves.
When to Invoke
- "Commit my skill"
- "Contribute this skill to liferay-portal"
- "Upstream the skill I just wrote"
- As the handoff at the end of
author-skill, which publishes into the workspace and stops at the workspace boundary
Prerequisites
The Workspace Root
The workspace root is the directory holding gradle.properties and settings.gradle. Every workspace relative path below resolves against it.
The Portal Repository
Ask the user for the absolute path to their liferay-portal clone.
The repository's own rules and skills then have to be brought into scope for the agent. Step 5 needs both: .claude/rules/commit.md for the message format, and the format-source skill, which that rule mandates before any commit. Reading a file out of the repository works without this, but a skill that is not in scope cannot be invoked at all — so format-source is the part that fails silently.
Adding a directory to a session is the user's to do, and each agent exposes it differently — a slash command, a launch flag, a setting. In Claude Code, it is /add-dir <portal-repo>. Ask the user to add the repository root in whatever way their agent provides, wait for their reply, then confirm that format-source is invokable before continuing.
Store the resolved path so later runs can offer it instead of asking again.
The Canonical Remote
Resolve the remote by URL, never by the name upstream. A clone may carry several forks under names that say nothing about which is canonical:
git remote -v | awk '$3=="(fetch)" && $2 ~ /[:/]liferay\/liferay-portal(\.git)?$/ {print $1}'
The [:/] prefix matches both git@github.com: and https://github.com/ forms, and (\.git)?$ anchors past an inconsistent suffix. Anchoring is what keeps forks under liferay-devtools, liferay-one, and personal accounts from matching.
A clone with no such remote is not expected. When it happens, say so and ask the user whether to add it — do not guess a fork.
Workflow
Step 1: Determine What to Commit
Check three sources in order, and stop at the first that answers.
Session context. The common case is author-skill having just run, so the names are already known. Confirm them with the user rather than deriving them again.
Repository detection. When the workspace is itself a Git repository, everything below counts as a candidate:
| Candidate | How It Presents |
|---|---|
| Untracked skill files | git status --porcelain lines beginning ?? |
| Uncommitted edits to an existing skill | lines beginning M or M |
| Already committed skill changes | git log against the tracking branch |
Baseline comparison. When the workspace is not a repository, diff it against the portal repo's own tree, which has the same layout:
diff --recursive --brief \
"${WORKSPACE}/.agents/skills" \
"${PORTAL_REPO}/workspaces/liferay-sample-workspace/.agents/skills"
Present what was found and confirm before doing anything else.
Step 2: Assemble the Full Changeset
A skill is more than its SKILL.md. author-skill also edits the Skill Router and may add a rules card, and every one of those edits belongs in the commit:
| Part | Workspace Path |
|---|---|
| The skill | .agents/skills/<name>/SKILL.md |
| Its mirrors | <vendor>/skills/<name>/SKILL.md, one per vendor directory |
| Skill Router row | .agents/liferay-rules.md and each vendor twin |
| Preflight Rule row | same files, when the skill must load before authoring an artifact type |
| New rules card | .agents/rules/<card>.md and its mirrors |
Discover the vendor directories rather than hardcoding them:
for dir in .*/; do
[ -d "${dir}skills" ] && [ "${dir}" != ".agents/" ] && echo "${dir}"
done
A skill committed without its Skill Router row loads only when named exactly. The file is present, the skill is effectively invisible, and nothing fails.
Before collapsing, confirm the mirrors still agree with .agents/. Nothing regenerates them and nothing fails when they drift, so a stale mirror means Step 4 silently picks a winner:
for dir in "${WORKSPACE}"/.*/; do
[ -d "${dir}skills/<name>" ] || continue
[ "$(basename "${dir}")" = ".agents" ] && continue
diff "${WORKSPACE}/.agents/skills/<name>/SKILL.md" "${dir}skills/<name>/SKILL.md"
done
Step 3: Prepare the Branch
Work from a freshly pulled master so the baseline and the commit share a revision:
-
Stash any working changes in the portal repo. Leave the stash in place and report it — do not pop it. Capture the ref, since an existing stash stack makes
stash@{0}ambiguous within minutes:git -C "${PORTAL_REPO}" stash push --include-untracked --message "commit-skill: <name>" git -C "${PORTAL_REPO}" stash list | head -1 -
Check out
master, then pull from the remote resolved in Prerequisites. -
Ask the user for the branch name, then create it.
When the workspace turns out to live inside the portal repo, stop. The stash would capture the very skill being contributed, and the branch switch would move it out from under the user. Say so and let them decide.
Step 4: Collapse Into the Repo Layout
The two trees are not the same shape. A workspace populated by updateWorkspace holds independent copies, because the published artifact contains no symlinks; the repo holds one real file and symlinks beside it:
| File | Workspace | Repo |
|---|---|---|
.agents/skills/<name>/SKILL.md |
real file | real file |
<vendor>/skills/<name>/SKILL.md |
identical copy | symlink to ../../../.agents/skills/<name>/SKILL.md |
.agents/liferay-rules.md |
real file | real file |
<vendor>/<entry-point> |
identical copy | symlink to ../.agents/liferay-rules.md |
So committing is a collapse, never a straight copy: write one real file under .agents/, then create the symlinks. The relative depth differs between the two cases above — count it from the link's own directory rather than reusing a path.
Each vendor names its entry point differently, so read the existing one in the repo rather than assuming a name. Match whatever vendor directories the repository already carries; adding a tree it does not have is a separate decision, not part of contributing a skill.
Skill Router and Preflight Rule edits collapse the same way. Two separately edited files in the workspace become one edit to .agents/liferay-rules.md, since each vendor entry point already points at it.
Skills and rules cards in this repository end without a trailing newline. Check the last byte, where 0a means one is still there:
tail -c 1 "${PORTAL_REPO}/workspaces/liferay-sample-workspace/.agents/skills/<name>/SKILL.md" | xxd -p
Step 5: Resolve the Ticket and Commit
Follow .claude/rules/commit.md in the portal repo — it owns the message format and mandates format-source first.
Its ticket resolution reads the current branch and recent commits, which on a freshly created branch describe whatever the user was last working on rather than this contribution. Resolve the ticket by situation instead:
| Situation | Where the Ticket Comes From |
|---|---|
| Branch was just created | Ask. When the branch name the user gave carries a ticket, offer it as the suggestion rather than asking blind |
| Branch already existed | Read that branch's own commits first, then fall back to asking |
Never take the ticket from master's log or from the branch the repo happened to be on.
Commit, then stop. Report the branch, the commit, and the stash.
Patterns and Gotchas
- A straight copy produces the wrong tree. The workspace's vendor copies are real files; the repo expects symlinks. Copying them over commits duplicated content that the publish step already produces on its own.
- The Skill Router row is the difference between shipped and invisible. It is the single most commonly dropped part of the changeset, and its absence never produces an error.
commit.md's ticket rules read stale state here. Both of its inference sources describe the user's previous work, not this contribution, and both answer confidently.- Mirror drift is silent. When
.agents/and a vendor copy disagree, the collapse resolves it without telling anyone. Diff before, not after. - The stash is the one step that looks destructive. Report its ref every time. The user decides when to restore it.
- Do not push or open a pull request. The commit is the deliverable; review is the user's to start.
Success Signal
The branch exists carrying one new commit, the repository tree holds a real file with symlinks beside it, and the Skill Router names the skill:
git -C "${PORTAL_REPO}" log --oneline --name-status -1
ls -la "${PORTAL_REPO}"/workspaces/liferay-sample-workspace/.*/skills/<name>/SKILL.md
grep --count "<name>" "${PORTAL_REPO}/workspaces/liferay-sample-workspace/.agents/liferay-rules.md"
The symlink listing should show lrwxrwxrwx and the .agents/ target. Whether the contribution is accepted is decided in review, not here.
See Also
.claude/rules/commit.mdin the portal repo — the commit message format this skill follows.skills/author-skill/SKILL.md— writes the skill and hands off to this one.
04 同仓库更多 Skills
promptscript
PromptScript language expert for reading, writing, modifying, and troubleshooting .prs files. Use when working with PromptScript syntax, creating or editing .prs files, adding blocks like @identity, @standards, @restrictions, @shortcuts, @skills, or @agents, configuring promptscript.yaml, resolving compilation errors, understanding inheritance (@inherit), composition (@use, @extend, @override), contextual @header metadata, or migrating AI instructions to PromptScript. Also use when asked about the 50 built-in coding agent compilation targets, including GitHub Copilot, Claude Code, Cursor, Antigravity, Factory AI, and AGENTS.md-based platforms, or about the bundle and prompt-text targets for application prompts.
expert
Base expert skill
tdd-workflow
Test-driven development workflow
alpha
Alpha skill
pdf-processing
Extract PDF text, fill forms, merge files. Use when handling PDFs.
react-component-patterns
Conventions for writing React components in this codebase.