Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "holdex",
"description": "Holdex workflows as agent skills: contributing rules for issues and PRs, bug attribution, and time tracking.",
"owner": {
"name": "Holdex"
},
"plugins": [
{
"name": "holdex",
"source": "./",
"description": "Holdex workflows as agent skills: contributing rules for issues and PRs, bug attribution, and time tracking."
}
]
}
10 changes: 10 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "holdex",
"description": "Holdex workflows as agent skills: contributing rules for issues and PRs, bug attribution, and time tracking.",
"author": {
"name": "Holdex"
},
"homepage": "https://github.com/holdex/developers",
"repository": "https://github.com/holdex/developers",
"keywords": ["holdex", "contributing", "workflow"]
}
17 changes: 17 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "holdex",
"owner": {
"name": "Holdex"
},
"metadata": {
"description": "Holdex workflows as agent skills"
},
"plugins": [
{
"name": "holdex",
"source": ".",
"description": "Holdex workflows as agent skills: contributing rules for issues and PRs, bug attribution, and time tracking.",
"skills": "skills"
}
]
}
36 changes: 29 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,39 @@ merges.
The `main` branch is the published source of truth, and merged changes are live
for the whole organization immediately. There is no separate hosting to deploy.

## Claude Code Skills
## Skills and plugins

Clone this repository locally and symlink the commands directory to make all
skills available globally across every repo you work in:
The workflows live as standard Agent Skills in `skills/`, and the repository
itself is packaged as a plugin, so any supported tool can install them.

Any coding agent — Claude Code, Codex, Cursor, OpenCode, Copilot, and more:

```bash
npx skills add holdex/developers
```

Add `-g` to install them globally for every repo you work in, and run
`npx skills update` to pick up changes after pulling the repo.

Claude Code, as a plugin from the built-in marketplace:

```bash
ln -s /path/to/holdex/developers/.claude/commands ~/.claude/commands
claude plugin marketplace add holdex/developers
claude plugin install holdex@holdex
```

Skills stay up to date automatically as you pull the repo. Available skills:
Each skill then runs as `/holdex:<skill-name>`, with the bare `/<skill-name>`
working when no other command claims it.

Cursor, from the repository: open Customize and import `holdex/developers` as a
marketplace, then install the `holdex` plugin from it.

The repository is also a conformant Agent Plugin (a root `plugin.json` following
the [Agent Plugins](https://agent-plugins.org) open standard), so any other
spec-conformant tool can install it directly. Available skills:

| Command | When to use |
| Skill | When to use |
| --- | --- |
| `/holdex-contributing` | Before creating or updating a GitHub issue or PR in any Holdex repository |
| `holdex-contributing` | Before creating or updating a GitHub issue or PR in any Holdex repository |
| `report-bug` | Post the bug attribution comment a `fix` PR needs before review |
| `submit-time` | Record time spent on a pull request |
12 changes: 12 additions & 0 deletions plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "holdex",
"description": "Holdex workflows as agent skills: contributing rules for issues and PRs, bug attribution, and time tracking.",
"version": "1.0.0",
"author": {
"name": "Holdex"
},
"homepage": "https://github.com/holdex/developers",
"repository": "https://github.com/holdex/developers",
"keywords": ["holdex", "contributing", "workflow"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: Holdex contributing rules for GitHub issues and PRs. Invoke before
# Holdex Contributing

All PRs and issues must follow the
[Holdex Contributing Guidelines](https://github.com/holdex/developers/blob/main/docs/CONTRIBUTING.md).
[Holdex Contributing Guidelines][contributing].

## Issues

Expand All @@ -29,20 +29,25 @@ All PRs and issues must follow the
- Good: `docs: protect client funds from unauthorized contractor custody`
- Bad: `Add FUND_HANDLING.md`
- **Scope**: one `type(scope): action`, 3 to 15 minutes of work, per
[DEV-320](../../docs/rules/DEV-320.md). Decompose if larger.
[DEV-320][dev-320]. Decompose if larger.
- **`fix` PRs**: must carry a
`@holdex bug commit <commit-url> && bug author @<handle>` comment attributing
the commit/author that introduced the bug — use the `/report-bug` command.
Required before marking ready for review.
the commit/author that introduced the bug — use the `/report-bug` skill
(`/holdex:report-bug` when installed as a Claude Code plugin). Required before
marking ready for review.
- **Lifecycle** (in order):
1. Open as a **draft PR** immediately when starting work.
1. Link to the Problem issue using a closing keyword (`Closes #123`).
1. Assign yourself.
1. If the PR title starts with `fix`, post the bug attribution comment
(`/report-bug`).
(`/report-bug`, or `/holdex:report-bug` as a Claude Code plugin).
1. Resolve all CI checks.
1. Assign a reviewer when DEV-405 requires a human (a security change, or a
Spec others work from).
1. Mark ready for review only when all steps above are done.
- **Do not merge** until agent review is clean and CI passes, per
[DEV-405](../../docs/rules/DEV-405.md). You merge it and own the result.
[DEV-405][dev-405]. You merge it and own the result.

[contributing]: https://github.com/holdex/developers/blob/main/docs/CONTRIBUTING.md
[dev-320]: https://github.com/holdex/developers/blob/main/docs/rules/DEV-320.md
[dev-405]: https://github.com/holdex/developers/blob/main/docs/rules/DEV-405.md
85 changes: 44 additions & 41 deletions .claude/commands/report-bug.md → skills/report-bug/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,57 @@
Post a `@holdex bug commit` or `@holdex bug dispute` comment on a pull
request to attribute the commit and author that introduced a bug.
---
name: report-bug
description: Post a `@holdex bug commit` or `@holdex bug dispute` comment on a pull request to attribute the commit and author that introduced a bug. Required for every `fix` PR before it is ready for review.
---

**Required for every PR whose title starts with `fix` (Conventional
Commits type).** A `fix` PR is not ready for review until this comment is
posted — it's how the original bug source gets attributed.
# Report Bug

Post a `@holdex bug commit` or `@holdex bug dispute` comment on a pull request
to attribute the commit and author that introduced a bug.

**Required for every PR whose title starts with `fix` (Conventional Commits
type).** A `fix` PR is not ready for review until this comment is posted — it's
how the original bug source gets attributed.

## Input

`$ARGUMENTS` holds the commit URL and the GitHub handle of the commit's
author, optionally prefixed with `dispute` to correct a previous report
instead of filing a new one:
`$ARGUMENTS` holds the commit URL and the GitHub handle of the commit's author,
optionally prefixed with `dispute` to correct a previous report instead of
filing a new one:

- `<commit-url> @<github-handle>` — report the commit/author that introduced
the bug (e.g.
`https://github.com/holdex/my-repo/commit/1234567890 @usershandle`).
- `dispute <commit-url> @<github-handle>` — dispute a previous bug report
after the PR it was filed on has already been merged, to correct an
incorrect attribution.
- `<commit-url> @<github-handle>` — report the commit/author that introduced the
bug (e.g. `https://github.com/holdex/my-repo/commit/1234567890 @usershandle`).
- `dispute <commit-url> @<github-handle>` — dispute a previous bug report after
the PR it was filed on has already been merged, to correct an incorrect
attribution.

If `$ARGUMENTS` is empty, ask the user for the commit URL and the author's
GitHub handle before proceeding.

Determine which mode applies:

- No `dispute` prefix: **report** — attribute the commit/author that
introduced the bug this PR fixes.
- `dispute` prefix: **dispute** — strip the `dispute` prefix to get the
commit URL and handle; use this to correct a wrong attribution after
merge.
- No `dispute` prefix: **report** — attribute the commit/author that introduced
the bug this PR fixes.
- `dispute` prefix: **dispute** — strip the `dispute` prefix to get the commit
URL and handle; use this to correct a wrong attribution after merge.

Validate the input against strict patterns — reject anything that doesn't
fully match, don't just check a prefix:
Validate the input against strict patterns — reject anything that doesn't fully
match, don't just check a prefix:

- Commit URL must match
`^https://github\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+/(commit|pull/[0-9]+/(commits|changes))/[0-9a-f]{7,40}$`.
- Handle must match `^@[A-Za-z0-9](-?[A-Za-z0-9])*$` (a bare GitHub
username, `@` + up to 39 alphanumeric/hyphen characters, no spaces or
shell metacharacters).
- Handle must match `^@[A-Za-z0-9](-?[A-Za-z0-9])*$` (a bare GitHub username,
`@` + up to 39 alphanumeric/hyphen characters, no spaces or shell
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
metacharacters).

If either fails to match, tell the user and stop — don't attempt to sanitize
or partially accept it.
If either fails to match, tell the user and stop — don't attempt to sanitize or
partially accept it.

## Resolve the PR

Detect the current PR from the git worktree. **Report** mode targets the
PR still in progress, so open PRs are enough. **Dispute** mode corrects a
PR that "has already been merged" (per its own description above), so the
lookup must include closed/merged PRs too:
Detect the current PR from the git worktree. **Report** mode targets the PR
still in progress, so open PRs are enough. **Dispute** mode corrects a PR that
"has already been merged" (per its own description above), so the lookup must
include closed/merged PRs too:

```bash
# report
Expand All @@ -56,20 +61,18 @@ gh pr list --head "$(git branch --show-current)" --json number,url,title --limit
gh pr list --head "$(git branch --show-current)" --state all --json number,url,title,comments --limit 1
```

If no PR is found for the current branch, ask the user for the PR number or
URL.
If no PR is found for the current branch, ask the user for the PR number or URL.

If the PR title does not start with `fix`, confirm with the user that they
still want to post a bug report comment before continuing — this command is
only required for `fix` PRs, but can be used on any PR.
If the PR title does not start with `fix`, confirm with the user that they still
want to post a bug report comment before continuing — this skill is only
required for `fix` PRs, but can be used on any PR.

For **dispute** mode specifically, before posting: check the resolved PR's
comments for a prior `@holdex bug commit <COMMIT_URL> && bug author
<HANDLE>` comment whose commit URL matches the one given in `$ARGUMENTS`
(the handle is expected to differ — that's the attribution being
corrected). Require exactly one such PR/comment match. If none match, or
more than one PR matches the branch/commit, stop without posting and tell
the user why instead of guessing.
comments for a prior `@holdex bug commit <COMMIT_URL> && bug author <HANDLE>`
comment whose commit URL matches the one given in `$ARGUMENTS` (the handle is
expected to differ — that's the attribution being corrected). Require exactly
one such PR/comment match. If none match, or more than one PR matches the
branch/commit, stop without posting and tell the user why instead of guessing.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

## Post the comment

Expand Down
14 changes: 11 additions & 3 deletions .claude/commands/submit-time.md → skills/submit-time/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
Post a `@holdex pr submit-time` or `@holdex pr add-time` comment on a pull request to record time spent.
---
name: submit-time
description: Post a `@holdex pr submit-time` or `@holdex pr add-time` comment on a pull request to record time spent.
---

# Submit Time

Post a `@holdex pr submit-time` or `@holdex pr add-time` comment on a pull
request to record time spent.

## Input

Expand All @@ -12,8 +20,8 @@ Determine which mode applies:

- No `add` prefix: **submit/update total time** — replaces any previously
recorded time for this PR with the given value.
- `add` prefix: **add time on top of the previous submission** — strip the
`add` prefix to get the time value.
- `add` prefix: **add time on top of the previous submission** — strip the `add`
prefix to get the time value.

Validate the time format — accepted patterns: `15m`, `1h`, `2h30m`, `1.5h`. If
the format is invalid, tell the user and stop.
Expand Down
Loading