feat: add dev-workflow and forge-cli skills
Add two engineering skills for implementing tracker tickets end to end: - dev-workflow: selects workflow:ready-for-agent tickets, runs them in isolated worktrees, opens one PR/MR per ticket, reviews, merges, and cleans up. - forge-cli: detects the forge from origin and wraps gh, glab, and tea for Gitea/Forgejo, GitHub, and GitLab. Docs cover install, prerequisites, ticket labels, and per-forge CLI usage.
This commit is contained in:
@@ -0,0 +1,146 @@
|
|||||||
|
# Pi development workflow skill
|
||||||
|
|
||||||
|
`dev-workflow` implements already-planned tracker tickets from issue selection through isolated implementation worktrees, pull/merge requests, review, merge, and cleanup.
|
||||||
|
|
||||||
|
It supports:
|
||||||
|
|
||||||
|
- Tea-compatible Gitea/Forgejo repositories through `tea`
|
||||||
|
- GitHub repositories through `gh`
|
||||||
|
- GitLab repositories through `glab`
|
||||||
|
|
||||||
|
The forge is selected from `origin`, or explicitly with `DEV_WORKFLOW_FORGE`.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
From this checkout, install globally for your user:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pi install /absolute/path/to/ws-developement-workflow
|
||||||
|
```
|
||||||
|
|
||||||
|
Or install it only for the current project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pi install -l /absolute/path/to/ws-developement-workflow
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart Pi after installation, or run `/reload` in an existing session. Review the package before installing it: skills can instruct Pi to run commands with your account's permissions.
|
||||||
|
|
||||||
|
## When to use it
|
||||||
|
|
||||||
|
Use this after the human-led wayfinder, planning, specification, and ticket phases have produced implementation tickets.
|
||||||
|
|
||||||
|
The skill does **not** create planning tickets. It only implements tickets that are already labelled:
|
||||||
|
|
||||||
|
```text
|
||||||
|
workflow:ready-for-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
Invoke it with an optional ticket ID or URL:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# Process only ticket 43
|
||||||
|
/skill:dev-workflow 43
|
||||||
|
|
||||||
|
# Process all available tickets in the current repository
|
||||||
|
/skill:dev-workflow
|
||||||
|
```
|
||||||
|
|
||||||
|
The ID must be a tracker issue/ticket, not a branch name, PR/MR ID, or session ID. With an ID, only that ticket is processed. With no ID, the skill considers all open tickets in the current repository.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before invoking the skill:
|
||||||
|
|
||||||
|
1. Run it from a checkout of the target repository.
|
||||||
|
2. Ensure `origin` points to the correct forge repository.
|
||||||
|
3. Install and authenticate the matching CLI:
|
||||||
|
- Tea/Gitea/Forgejo: `tea`
|
||||||
|
- GitHub: `gh`
|
||||||
|
- GitLab: `glab`
|
||||||
|
4. Create implementation tickets, optionally grouped under a root issue.
|
||||||
|
5. Mark implementable tickets `workflow:ready-for-agent`.
|
||||||
|
6. Add native child/dependency relationships where supported. Otherwise put explicit issue URLs or the documented blocker marker in the ticket.
|
||||||
|
7. Configure `DEV_WORKFLOW_HUMAN_REVIEWER` if the agent may assign human review automatically.
|
||||||
|
|
||||||
|
Run the read-only preflight manually from the target repository if needed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash /path/to/this-package/skills/forge-cli/scripts/detect-forge.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output resembles:
|
||||||
|
|
||||||
|
```text
|
||||||
|
forge=gh
|
||||||
|
remote=https://github.com/acme/project.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## What happens
|
||||||
|
|
||||||
|
For the supplied ticket, or all tickets when no ticket is supplied, the skill:
|
||||||
|
|
||||||
|
1. Verifies the repository, forge CLI, authentication, default branch, and capabilities.
|
||||||
|
2. Reads only the supplied ticket; otherwise reads all open tickets in the repository.
|
||||||
|
3. Selects only open, unassigned, unblocked `workflow:ready-for-agent` tickets.
|
||||||
|
4. For a supplied ticket, runs only that ticket; with no ticket, runs currently unblocked tickets in parallel, up to three isolated workers. Dependent tickets wait for their blockers.
|
||||||
|
5. Claims each selected ticket and changes it to `workflow:implementing`, then gives it to one worker in an isolated Git worktree.
|
||||||
|
6. Runs local checks, pushes the branch, and creates exactly one PR/MR per ticket.
|
||||||
|
7. Records URLs, status, evidence, blockers, and handoffs in tracker comments.
|
||||||
|
8. Reviews each PR/MR for correctness/spec and standards, allowing at most three fix rounds.
|
||||||
|
9. Resolves conflicts through the conflict workflow instead of aborting or guessing.
|
||||||
|
10. Merges only when review, local checks, CI, target branch, and blocker gates are clean.
|
||||||
|
11. Closes the integrated ticket, records the merge receipt, and removes the worktree.
|
||||||
|
12. Re-queries the scoped ticket set after every merge so newly unblocked tickets can run.
|
||||||
|
|
||||||
|
Default worker parallelism is three, subject to the available subagent limit.
|
||||||
|
|
||||||
|
## Ticket labels
|
||||||
|
|
||||||
|
The skill uses one active workflow label per ticket:
|
||||||
|
|
||||||
|
```text
|
||||||
|
workflow:ready-for-agent
|
||||||
|
workflow:ready-for-human
|
||||||
|
workflow:implementing
|
||||||
|
workflow:pr-open
|
||||||
|
workflow:review
|
||||||
|
workflow:changes-requested
|
||||||
|
workflow:conflict
|
||||||
|
workflow:blocked
|
||||||
|
workflow:merged
|
||||||
|
```
|
||||||
|
|
||||||
|
Existing `workflow:ready-for-human` tickets are left untouched and reported as human handoffs. Missing requirements, unsafe ambiguity, credentials, product decisions, unavailable CI, and missing permissions stop the workflow instead of being guessed around.
|
||||||
|
|
||||||
|
## Forge CLI recipes
|
||||||
|
|
||||||
|
After preflight, the shared `forge-cli` skill contains the common rules and automatically selects one recipe:
|
||||||
|
|
||||||
|
- `skills/forge-cli/references/tea.md`
|
||||||
|
- `skills/forge-cli/references/gh.md`
|
||||||
|
- `skills/forge-cli/references/glab.md`
|
||||||
|
|
||||||
|
Other skills can use it too: install this package globally, then instruct them to load the shared `forge-cli` skill instead of duplicating CLI syntax.
|
||||||
|
|
||||||
|
## Completion states
|
||||||
|
|
||||||
|
The final report includes:
|
||||||
|
|
||||||
|
- merged tickets and PR/MR URLs;
|
||||||
|
- remaining eligible tickets;
|
||||||
|
- tickets waiting for human review;
|
||||||
|
- blocked tickets and exact reasons;
|
||||||
|
- failed checks and review rounds.
|
||||||
|
|
||||||
|
`done` means no open implementation or human tickets remain in the selected scope. If only human tickets remain, the result is `waiting-on-human`.
|
||||||
|
|
||||||
|
## Development checks
|
||||||
|
|
||||||
|
Validate the package with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash tests/test-workflow.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This checks skill metadata, references, shell syntax, forge detection, and eligibility filtering.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
name: dev-workflow
|
||||||
|
description: Implements ready-for-agent tracker tickets through isolated worktrees, pull requests, review, conflict resolution, and merge. Use after wayfinder and planning have produced tickets, when the user gives a ticket ID, asks to process available tickets, or asks to run the development workflow. Does not create planning tickets.
|
||||||
|
disable-model-invocation: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# Development workflow
|
||||||
|
|
||||||
|
Use this skill only after the human-led wayfinder, plan, spec, and ticket phases. The optional argument is a **tracker ticket ID or URL**. With an argument, process only that ticket. With no argument, scope the run to all open tickets in the current repository. An ID means the forge's issue/ticket identifier, not a branch, session, or PR ID.
|
||||||
|
|
||||||
|
## Compose before acting
|
||||||
|
|
||||||
|
Read and use these skills for their specialized work:
|
||||||
|
|
||||||
|
- `pi-subagents` for parallel workers and managed worktrees
|
||||||
|
- `worktrees` for worktree conventions and cleanup
|
||||||
|
- `code-review` for independent correctness/spec and standards review
|
||||||
|
- `resolving-merge-conflicts` for conflicts; never abort a merge or rebase
|
||||||
|
- `forge-cli` for forge selection, authentication, and CLI recipes
|
||||||
|
|
||||||
|
Load the shared `forge-cli` skill and run its bundled read-only preflight with the target repository as the working directory. Read only the detected CLI recipe; copy those commands instead of rediscovering syntax. Run `<cli> <command> --help` only when a recipe fails with an unknown command or flag. Do not add an API client or dependency.
|
||||||
|
|
||||||
|
## Durable state
|
||||||
|
|
||||||
|
The tracker is the source of truth. Read the root, every candidate ticket, and their existing comments before acting. Use one active label per ticket:
|
||||||
|
|
||||||
|
- `workflow:ready-for-agent`
|
||||||
|
- `workflow:ready-for-human`
|
||||||
|
- `workflow:implementing`
|
||||||
|
- `workflow:pr-open`
|
||||||
|
- `workflow:review`
|
||||||
|
- `workflow:changes-requested`
|
||||||
|
- `workflow:conflict`
|
||||||
|
- `workflow:blocked`
|
||||||
|
- `workflow:merged`
|
||||||
|
|
||||||
|
Comments are the message board. Record claims, status, evidence, questions, decisions, handoffs, PR URLs, check results, and recovery details there. If a worker has an issue with a ticket, comment on the ticket and wait for the human or another agent rather than guessing. For PR/MR issues, use the PR/MR's native comment/review function and also link the discussion from the ticket. Use `DEV_WORKFLOW_HUMAN_REVIEWER` or repository workflow configuration for the human identity; if none is configured, ask before assigning and do not invent an identity.
|
||||||
|
|
||||||
|
## Run loop
|
||||||
|
|
||||||
|
1. **Scope.** If a ticket ID/URL is supplied, confirm it belongs to the current repository and inspect only that ticket; do not process its siblings, parent, or descendants. If omitted, query all open tickets in the current repository. Use native child/dependency relationships; otherwise require explicit linked URLs or the documented blocker marker. Never infer order from titles.
|
||||||
|
2. **Schedule.** Eligible means open, unassigned, unblocked, and labelled `workflow:ready-for-agent`. Already `workflow:ready-for-human` tickets are skipped and reported. For a supplied ticket, process only that ticket; if it is blocked, report it and do not process its blockers. With no supplied ticket, build the dependency frontier: launch currently unblocked tickets in parallel, up to three workers, and hold dependent tickets until every blocker is merged or otherwise resolved. Re-query after each merge and launch newly unblocked tickets; dependency chains therefore run sequentially while unrelated tickets remain parallel.
|
||||||
|
3. **Claim.** Assign each selected ticket to the current forge identity before work. Replace its state with `workflow:implementing` and comment the claim.
|
||||||
|
4. **Implement.** Launch one worker per ticket with `pi-subagents` in an isolated worktree, maximum three in flight by default. Pass the complete ticket, comments, acceptance criteria, non-goals, linked context, and validation contract. Each worker makes only ticket-scoped changes, commits them, and reports changed files and checks.
|
||||||
|
5. **Escalate.** For missing requirements, unsafe ambiguity, credentials, unrelated scope, or a product/architecture decision, stop. For human review or judgment, assign the ticket to the configured human reviewer, apply `workflow:ready-for-human`, and comment the exact request. If no human identity is configured, ask before assigning and changing the state. Use `workflow:blocked` for non-human blockers. Preserve the worktree on failure.
|
||||||
|
6. **PR.** Run documented local checks. Push the branch and create exactly one PR/MR for the ticket. Link the ticket's tracker ID and title in the PR/MR, set `workflow:pr-open`, and comment the PR/MR URL on the ticket. Keep the worktree.
|
||||||
|
7. **Review.** Set `workflow:review`. Run a fresh-context `code-review` review with correctness/spec and standards axes separate. Post findings through the PR/MR comment/review function. For actionable findings, set `workflow:changes-requested`, send one fix worker, rerun checks, and repeat. Allow at most three rounds.
|
||||||
|
8. **Conflict.** Set `workflow:conflict`, then follow `resolving-merge-conflicts`. Inspect both intents, preserve them where possible, never invent behavior, never abort, rerun local checks, and update the PR/MR. If judgment is needed, assign the PR/MR and ticket to the configured human reviewer, apply `workflow:ready-for-human`, and comment the request in both places. If no human identity is configured, ask before assigning.
|
||||||
|
9. **Merge.** Merge only after independent review is clean, local checks pass, forge CI is green, the target is still the expected default branch, and no human decision or blocker remains. Comment the merge receipt and outcome, close the ticket, apply `workflow:merged` when supported, verify integration, then remove the worktree.
|
||||||
|
10. **Finish.** Report merged tickets and PR/MR URLs, human handoffs, blocked tickets, failed checks, review rounds, and remaining eligible tickets. Report `done` only when no open implementation or human tickets remain in the selected scope. If only human tickets remain, report `waiting-on-human`.
|
||||||
|
|
||||||
|
Never parallel-write a shared checkout. Never silently relabel an existing human ticket. Never merge around a failed check, unresolved review finding, conflict, or missing decision.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Development Workflow"
|
||||||
|
short_description: "Implements ready-for-agent tracker tickets through isolated worktrees"
|
||||||
|
policy:
|
||||||
|
allow_implicit_invocation: false
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||||
|
skill="$root/skills/dev-workflow/SKILL.md"
|
||||||
|
shared_skill="$root/skills/forge-cli/SKILL.md"
|
||||||
|
recipes=(
|
||||||
|
"$root/skills/forge-cli/references/tea.md"
|
||||||
|
"$root/skills/forge-cli/references/gh.md"
|
||||||
|
"$root/skills/forge-cli/references/glab.md"
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ -f "$skill" && -f "$shared_skill" && -f "${recipes[0]}" && -f "${recipes[1]}" && -f "${recipes[2]}" ]] || {
|
||||||
|
echo 'Missing skill or reference file' >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
head -1 "$skill" | grep -qx -- '---'
|
||||||
|
grep -q '^name: dev-workflow$' "$skill"
|
||||||
|
grep -q '^description: ' "$skill"
|
||||||
|
head -1 "$shared_skill" | grep -qx -- '---'
|
||||||
|
grep -q '^name: forge-cli$' "$shared_skill"
|
||||||
|
grep -q '^description: ' "$shared_skill"
|
||||||
|
node -e 'JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"))' "$root/package.json"
|
||||||
|
bash -n "$root/skills/forge-cli/scripts/detect-forge.sh"
|
||||||
|
|
||||||
|
printf '%s\n' 'dev-workflow skill is valid'
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: forge-cli
|
||||||
|
description: Provides copy-paste, non-interactive tea, gh, and glab commands for issue and pull or merge request work. Use whenever a task needs tracker inspection, assignment, labels, comments, reviews, CI, or merge operations.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Forge CLI
|
||||||
|
|
||||||
|
Use this shared skill instead of reproducing forge CLI syntax in another skill.
|
||||||
|
|
||||||
|
Run the bundled read-only preflight with the target repository as the working directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash <resolved-skill-dir>/scripts/detect-forge.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Resolve `<resolved-skill-dir>` from this `SKILL.md`, not from the target repository.
|
||||||
|
|
||||||
|
It prints one selected CLI: `forge=tea`, `forge=gh`, or `forge=glab`. Read **only** the matching recipe:
|
||||||
|
|
||||||
|
- `forge=tea` → `references/tea.md`
|
||||||
|
- `forge=gh` → `references/gh.md`
|
||||||
|
- `forge=glab` → `references/glab.md`
|
||||||
|
|
||||||
|
Do not load or compare the other recipes. This keeps one forge's syntax in context.
|
||||||
|
|
||||||
|
Commands assume the current checkout identifies the repository. Replace `ID` (issue), `PR` (pull/merge request), `USER`, `OLD`, `NEW`, `BASE`, `HEAD`, `TITLE`, and `BODY_FILE`. Keep bodies in a file to avoid quoting and interactive prompts.
|
||||||
|
|
||||||
|
## Shared safety rules
|
||||||
|
|
||||||
|
1. Use JSON output for reads; inspect the returned object before deciding eligibility, dependencies, or merge readiness.
|
||||||
|
2. Use one mutation per state transition, then re-read and confirm the state/label/comment changed.
|
||||||
|
3. If a recipe returns an unknown command or flag, run that CLI command's `--help`; do not switch forge CLIs or guess.
|
||||||
|
4. Check command exit status. Authentication, repository resolution, missing permissions, unsupported relationships, and unavailable CI are blockers.
|
||||||
|
5. Do not use auto-merge, admin/bypass, or force options. Merge only after every workflow gate passes.
|
||||||
|
|
||||||
|
Honor `DEV_WORKFLOW_FORGE=tea`, `gh`, or `glab` when explicitly configured; otherwise use GitHub → `gh`, GitLab → `glab`, and other Tea-compatible hosts → `tea`.
|
||||||
|
|
||||||
|
Keep these identifiers distinct: tracker issue/ticket ID, PR/MR ID, durable URL, and local branch name. Never use a branch name as ticket identity.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
interface:
|
||||||
|
display_name: "Forge CLI"
|
||||||
|
short_description: "Copy-paste, non-interactive CLI for Forge"
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# GitHub CLI recipe
|
||||||
|
|
||||||
|
Use `gh` commands in the current repository. Use `--json` for reads and `--body-file` for multiline bodies.
|
||||||
|
|
||||||
|
## Read
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh issue view ID --comments --json number,state,url,title,body,assignees,labels,comments,parent,subIssues,blockedBy
|
||||||
|
gh issue list --state all --limit 100 --json number,state,url,title,body,assignees,labels,parent,subIssues,blockedBy
|
||||||
|
gh pr view PR --comments --json number,state,url,title,body,assignees,labels,baseRefName,headRefName,comments,reviews,reviewDecision,statusCheckRollup,mergeable
|
||||||
|
gh pr checks PR --required --json bucket,name,state,completedAt
|
||||||
|
```
|
||||||
|
|
||||||
|
If an installed version rejects an optional JSON field, remove that field and rerun the same read. Native parent, child, and dependency fields may be unavailable; otherwise use the explicit links documented in the ticket.
|
||||||
|
|
||||||
|
## Issue lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh issue edit ID --add-assignee USER
|
||||||
|
gh issue edit ID --add-label NEW --remove-label OLD
|
||||||
|
gh issue comment ID --body-file BODY_FILE
|
||||||
|
gh issue close ID
|
||||||
|
```
|
||||||
|
|
||||||
|
`@me` means the current authenticated user.
|
||||||
|
|
||||||
|
## Pull request lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh pr create --base BASE --head HEAD --title TITLE --body-file BODY_FILE
|
||||||
|
gh pr comment PR --body-file BODY_FILE
|
||||||
|
gh pr review PR --comment --body-file BODY_FILE
|
||||||
|
gh pr review PR --request-changes --body-file BODY_FILE
|
||||||
|
gh pr merge PR --squash --delete-branch
|
||||||
|
```
|
||||||
|
|
||||||
|
Re-read the issue/PR after every mutation. Do not use `--admin` or `--auto`.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# GitLab CLI recipe
|
||||||
|
|
||||||
|
Use `glab` commands in the current repository. Use JSON output for reads and file-backed descriptions for multiline bodies.
|
||||||
|
|
||||||
|
## Read
|
||||||
|
|
||||||
|
```bash
|
||||||
|
glab issue view ID --comments --output json
|
||||||
|
glab issue list --all --per-page 100 --output json
|
||||||
|
glab mr view PR --comments --output json
|
||||||
|
```
|
||||||
|
|
||||||
|
Native parent, child, and dependency fields may be unavailable. If absent, use the explicit links documented in the ticket.
|
||||||
|
|
||||||
|
## Issue lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
glab issue update ID --assignee USER
|
||||||
|
glab issue update ID --label NEW --unlabel OLD
|
||||||
|
glab issue note ID --message "$(cat BODY_FILE)"
|
||||||
|
glab issue close ID
|
||||||
|
```
|
||||||
|
|
||||||
|
`--assignee USER` replaces existing assignees; prefix with `+` to add without replacing.
|
||||||
|
|
||||||
|
## Merge request lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
glab mr create --target-branch BASE --source-branch HEAD --title TITLE --description-file BODY_FILE --yes
|
||||||
|
glab mr note create PR --message "$(cat BODY_FILE)"
|
||||||
|
glab mr merge PR --squash --remove-source-branch --auto-merge=false --yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `glab mr note create` for review findings or requested changes. Re-read the issue/MR after every mutation. Do not use auto-merge or bypass options.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Tea recipe
|
||||||
|
|
||||||
|
Tea calls the numeric identifier an `index`; it is still the tracker issue/PR ID. Use `--output json` for reads. Tea accepts comma-separated usernames/labels for the plural flags.
|
||||||
|
|
||||||
|
## Read
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea issues ID --comments --output json --fields index,state,url,title,body,assignees,labels,comments
|
||||||
|
tea issues list --state all --limit 100 --output json --fields index,state,url,title,body,assignees,labels
|
||||||
|
tea pulls PR --comments --output json --fields index,state,url,title,body,assignees,labels,base,head,comments,ci
|
||||||
|
```
|
||||||
|
|
||||||
|
Native parent, child, and dependency fields may be unavailable. If absent, use the explicit links documented in the ticket.
|
||||||
|
|
||||||
|
## Issue lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea issues edit --add-assignees USER ID
|
||||||
|
tea issues edit --add-labels NEW --remove-labels OLD ID
|
||||||
|
tea comments add ID --description "$(cat BODY_FILE)"
|
||||||
|
tea issues close ID
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pull request lifecycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea pulls create --base BASE --head HEAD --title TITLE --description "$(cat BODY_FILE)"
|
||||||
|
tea comments add PR --description "$(cat BODY_FILE)"
|
||||||
|
tea pulls merge PR --style squash
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `tea comments add` for review findings or requested changes. Re-read the issue/PR after every mutation.
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -u
|
||||||
|
|
||||||
|
remote="$(git remote get-url origin 2>/dev/null || true)"
|
||||||
|
if [[ -z "$remote" ]]; then
|
||||||
|
printf '%s\n' 'No origin remote found; run this inside a checked-out forge repository.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
choice="${DEV_WORKFLOW_FORGE:-}"
|
||||||
|
if [[ -z "$choice" ]]; then
|
||||||
|
case "$remote" in
|
||||||
|
*github.com*) choice=gh ;;
|
||||||
|
*gitlab.com* | *gitlab.*) choice=glab ;;
|
||||||
|
*) choice=tea ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
tea | gh | glab) ;;
|
||||||
|
*)
|
||||||
|
printf 'Unsupported DEV_WORKFLOW_FORGE=%s (use tea, gh, or glab).\n' "$choice" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! command -v "$choice" >/dev/null 2>&1; then
|
||||||
|
printf 'Required forge CLI not found: %s\n' "$choice" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
tea) "$choice" login list >/dev/null 2>&1 || {
|
||||||
|
printf '%s authentication check failed.\n' "$choice" >&2
|
||||||
|
exit 1
|
||||||
|
} ;;
|
||||||
|
gh) "$choice" auth status >/dev/null 2>&1 || {
|
||||||
|
printf '%s authentication check failed.\n' "$choice" >&2
|
||||||
|
exit 1
|
||||||
|
} ;;
|
||||||
|
glab) "$choice" auth status >/dev/null 2>&1 || {
|
||||||
|
printf '%s authentication check failed.\n' "$choice" >&2
|
||||||
|
exit 1
|
||||||
|
} ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
printf 'forge=%s\nremote=%s\n' "$choice" "$remote"
|
||||||
Reference in New Issue
Block a user