@open-mercato/cli 0.6.6-develop.6483.1.b623f50e2b → 0.6.6-develop.6484.1.2d3741fd58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -3
- package/dist/agentic/guides/module-facts.json +53 -53
- package/dist/agentic/guides/modules/ai_assistant.md +1 -1
- package/dist/agentic/guides/modules/api_docs.md +1 -1
- package/dist/agentic/guides/modules/api_keys.md +1 -1
- package/dist/agentic/guides/modules/attachments.md +1 -1
- package/dist/agentic/guides/modules/audit_logs.md +1 -1
- package/dist/agentic/guides/modules/auth.md +1 -1
- package/dist/agentic/guides/modules/business_rules.md +1 -1
- package/dist/agentic/guides/modules/catalog.md +1 -1
- package/dist/agentic/guides/modules/channel_gmail.md +1 -1
- package/dist/agentic/guides/modules/channel_imap.md +1 -1
- package/dist/agentic/guides/modules/checkout.md +1 -1
- package/dist/agentic/guides/modules/communication_channels.md +1 -1
- package/dist/agentic/guides/modules/configs.md +1 -1
- package/dist/agentic/guides/modules/content.md +1 -1
- package/dist/agentic/guides/modules/currencies.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts.md +1 -1
- package/dist/agentic/guides/modules/customers.md +1 -1
- package/dist/agentic/guides/modules/dashboards.md +1 -1
- package/dist/agentic/guides/modules/data_sync.md +1 -1
- package/dist/agentic/guides/modules/dictionaries.md +1 -1
- package/dist/agentic/guides/modules/directory.md +1 -1
- package/dist/agentic/guides/modules/entities.md +1 -1
- package/dist/agentic/guides/modules/events.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe.md +1 -1
- package/dist/agentic/guides/modules/generators.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops.md +1 -1
- package/dist/agentic/guides/modules/integrations.md +1 -1
- package/dist/agentic/guides/modules/messages.md +1 -1
- package/dist/agentic/guides/modules/notifications.md +1 -1
- package/dist/agentic/guides/modules/onboarding.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways.md +1 -1
- package/dist/agentic/guides/modules/perspectives.md +1 -1
- package/dist/agentic/guides/modules/planner.md +1 -1
- package/dist/agentic/guides/modules/portal.md +1 -1
- package/dist/agentic/guides/modules/progress.md +1 -1
- package/dist/agentic/guides/modules/query_index.md +1 -1
- package/dist/agentic/guides/modules/record_locks.md +1 -1
- package/dist/agentic/guides/modules/resources.md +1 -1
- package/dist/agentic/guides/modules/sales.md +1 -1
- package/dist/agentic/guides/modules/scheduler.md +1 -1
- package/dist/agentic/guides/modules/search.md +1 -1
- package/dist/agentic/guides/modules/security.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers.md +1 -1
- package/dist/agentic/guides/modules/sso.md +1 -1
- package/dist/agentic/guides/modules/staff.md +1 -1
- package/dist/agentic/guides/modules/storage_s3.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo.md +1 -1
- package/dist/agentic/guides/modules/sync_excel.md +1 -1
- package/dist/agentic/guides/modules/system_status_overlays.md +1 -1
- package/dist/agentic/guides/modules/translations.md +1 -1
- package/dist/agentic/guides/modules/webhooks.md +1 -1
- package/dist/agentic/guides/modules/workflows.md +1 -1
- package/dist/agentic/shared/AGENTS.md.template +16 -10
- package/dist/agentic/shared/ai/agentic.config.json +61 -0
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr/SKILL.md +16 -318
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +16 -581
- package/dist/agentic/shared/ai/skills/om-auto-create-pr/SKILL.md +16 -397
- package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +16 -738
- package/dist/agentic/shared/ai/skills/om-auto-fix-issue/SKILL.md +27 -0
- package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +16 -565
- package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +1 -1
- package/dist/agentic/shared/ai/skills/tiers.json +47 -0
- package/dist/agentic/shared/ai/skills/tiers.schema.json +73 -0
- package/dist/agentic/shared/ai/trackers/github.md +376 -0
- package/dist/agentic/shared/scripts/install-skills.sh +483 -0
- package/dist/lib/agentic-setup.js +9 -40
- package/dist/lib/agentic-setup.js.map +2 -2
- package/package.json +5 -5
- package/src/lib/agentic-setup.ts +19 -42
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr/STANDALONE.md +0 -98
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/STANDALONE.md +0 -96
- package/dist/agentic/shared/ai/skills/om-auto-create-pr/STANDALONE.md +0 -98
- package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/STANDALONE.md +0 -96
- package/dist/agentic/shared/ai/skills/om-auto-fix-github/SKILL.md +0 -419
- package/dist/agentic/shared/ai/skills/om-auto-fix-github/STANDALONE.md +0 -98
- package/dist/agentic/shared/ai/skills/om-auto-review-pr/STANDALONE.md +0 -98
- package/dist/agentic/shared/ai/skills/om-code-review/SKILL.md +0 -108
- package/dist/agentic/shared/ai/skills/om-code-review/references/review-checklist.md +0 -83
- package/dist/agentic/shared/ai/skills/om-integration-tests/SKILL.md +0 -279
- package/dist/agentic/shared/ai/skills/om-prepare-issue/SKILL.md +0 -202
- package/dist/agentic/shared/ai/skills/om-spec-writing/SKILL.md +0 -85
- package/dist/agentic/shared/ai/skills/om-spec-writing/references/spec-checklist.md +0 -67
- package/dist/agentic/shared/ai/skills/om-spec-writing/references/spec-template.md +0 -86
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./tiers.schema.json",
|
|
3
|
+
"default": ["core"],
|
|
4
|
+
"external": {
|
|
5
|
+
"source": "open-mercato/skills",
|
|
6
|
+
"description": "Skills installed from the shared open-mercato/skills collection via `npx skills add` (see scripts/install-skills.sh). Only the subset this standalone app ships is installed. A folder under .ai/skills/ matching one of these names is a repo-local override read by the external skill, never symlinked into the harness directories.",
|
|
7
|
+
"skills": [
|
|
8
|
+
"om-auto-continue-pr",
|
|
9
|
+
"om-auto-continue-pr-loop",
|
|
10
|
+
"om-auto-create-pr",
|
|
11
|
+
"om-auto-create-pr-loop",
|
|
12
|
+
"om-auto-fix-issue",
|
|
13
|
+
"om-auto-review-pr",
|
|
14
|
+
"om-code-review",
|
|
15
|
+
"om-integration-tests",
|
|
16
|
+
"om-prepare-issue",
|
|
17
|
+
"om-spec-writing"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"tiers": {
|
|
21
|
+
"core": {
|
|
22
|
+
"description": "Daily-driver standalone skills installed by default.",
|
|
23
|
+
"skills": [
|
|
24
|
+
"om-help",
|
|
25
|
+
"om-implement-spec",
|
|
26
|
+
"om-backend-ui-design",
|
|
27
|
+
"om-module-scaffold",
|
|
28
|
+
"om-data-model-design",
|
|
29
|
+
"om-system-extension",
|
|
30
|
+
"om-troubleshooter",
|
|
31
|
+
"om-eject-and-customize"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"automation": {
|
|
35
|
+
"description": "Module-management helpers. Opt-in.",
|
|
36
|
+
"skills": ["om-trim-unused-modules"]
|
|
37
|
+
},
|
|
38
|
+
"infra": {
|
|
39
|
+
"description": "Rare, special-case skills.",
|
|
40
|
+
"skills": ["om-integration-builder"]
|
|
41
|
+
},
|
|
42
|
+
"migration": {
|
|
43
|
+
"description": "One-shot, version-pinned migrations. Install only when needed.",
|
|
44
|
+
"skills": ["om-auto-upgrade-0.4.10-to-0.5.0"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://open-mercato.dev/schemas/skills/tiers.schema.json",
|
|
4
|
+
"title": "Open Mercato skills tier manifest",
|
|
5
|
+
"description": "Manifest mapping skill folders under .ai/skills/ to install tiers consumed by scripts/install-skills.sh.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["default", "tiers"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"type": "string"
|
|
12
|
+
},
|
|
13
|
+
"default": {
|
|
14
|
+
"type": "array",
|
|
15
|
+
"minItems": 1,
|
|
16
|
+
"items": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"minLength": 1
|
|
19
|
+
},
|
|
20
|
+
"description": "Tier names installed when install-skills.sh is invoked with no flags."
|
|
21
|
+
},
|
|
22
|
+
"external": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": false,
|
|
25
|
+
"required": ["source", "skills"],
|
|
26
|
+
"description": "Skills owned by an external collection and installed via `npx skills add` instead of local symlinks. Folders under .ai/skills/ matching these names are repo-local overrides, not installable skills.",
|
|
27
|
+
"properties": {
|
|
28
|
+
"source": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"minLength": 1,
|
|
31
|
+
"description": "The skills package source, e.g. a GitHub owner/repo."
|
|
32
|
+
},
|
|
33
|
+
"description": {
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
"skills": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"minItems": 1,
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^[a-z0-9][a-z0-9._-]*$"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"tiers": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"minProperties": 1,
|
|
49
|
+
"propertyNames": {
|
|
50
|
+
"pattern": "^[a-z][a-z0-9-]*$"
|
|
51
|
+
},
|
|
52
|
+
"additionalProperties": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": ["description", "skills"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"description": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"minLength": 1
|
|
60
|
+
},
|
|
61
|
+
"skills": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"minItems": 1,
|
|
64
|
+
"items": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"pattern": "^[a-z0-9][a-z0-9._-]*$"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# Tracker provider: GitHub
|
|
2
|
+
|
|
3
|
+
This file is the GitHub implementation of the tracker operations contract (see `TEMPLATE.md` for the contract itself). Every skill in the collection performs issue/PR state management through **named tracker operations** — `**get-issue**`, `**comment-pr**`, and so on — and this file defines what each operation means for GitHub, using the `gh` CLI.
|
|
4
|
+
|
|
5
|
+
How it is used at runtime: `om-setup-agent-pipeline` copies this file into the repository at `.ai/trackers/github.md`, and the config's `tracker` field selects it. When a skill says "tracker operation **get-pr**", execute the command documented under that operation heading in the repo's copy. The repo's copy is authoritative: teams extend or override any operation by editing it — add flags, swap a command, append repo-specific conventions — and every skill picks the change up on its next run. An operation not covered by an edit keeps its behavior from this file's text as copied.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- `gh` CLI installed and authenticated. Verify with the **auth-check** operation before a batch run; fail fast when unauthenticated.
|
|
10
|
+
- All operations accept an optional `{repo}` (`owner/name`); when omitted, `gh` infers it from the current checkout's git remote. Pass `--repo {owner}/{repo}` explicitly whenever a skill operates on a repository other than the current one.
|
|
11
|
+
|
|
12
|
+
## Conventions
|
|
13
|
+
|
|
14
|
+
- Issue and PR identifiers are numbers; in text they are written `#123`.
|
|
15
|
+
- A PR is linked to the issue it resolves with `Fixes #{issueId}` (or `Closes #{issueId}`) in the PR body; GitHub then closes the issue on merge. To reference without auto-closing, use a plain issue link.
|
|
16
|
+
- PRs open as **drafts** when a skill says so; a human (or **mark-pr-ready**) promotes them.
|
|
17
|
+
- Claim/lock signals on an issue or PR are: assignee set to the automation user, the `in-progress` label, and a `🤖`-prefixed claim comment. All three are set on claim; the label is guarded (below).
|
|
18
|
+
- Long, multi-line comment bodies are posted with `--body-file` (or a heredoc via process substitution) so formatting is preserved.
|
|
19
|
+
- CI status truth comes from **get-pr-checks**; the set of *required* checks comes from **get-required-checks** (branch protection). When branch protection is not readable (404), treat every reported check as required.
|
|
20
|
+
|
|
21
|
+
## Label guards
|
|
22
|
+
|
|
23
|
+
Every label mutation goes through an existence guard so a missing label degrades to a logged skip instead of a failure, and `labels.enabled: false` in the config skips label operations entirely.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
label_exists() {
|
|
27
|
+
gh label list --limit 200 --json name --jq '.[].name' | grep -Fxq "$1"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# PR labels
|
|
31
|
+
apply_label() {
|
|
32
|
+
if [ "$LABELS_ENABLED" != "true" ]; then return 0; fi
|
|
33
|
+
if label_exists "$1"; then
|
|
34
|
+
gh pr edit "$2" --add-label "$1"
|
|
35
|
+
else
|
|
36
|
+
echo "Skipping label '$1' (not defined in this repo). Create it with: gh label create '$1'"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Issue labels
|
|
41
|
+
apply_issue_label() {
|
|
42
|
+
if [ "$LABELS_ENABLED" != "true" ]; then return 0; fi
|
|
43
|
+
if label_exists "$1"; then
|
|
44
|
+
gh issue edit "$2" --add-label "$1"
|
|
45
|
+
else
|
|
46
|
+
echo "Skipping label '$1' (not defined in this repo). Create it with: gh label create '$1'"
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
remove_issue_label() {
|
|
51
|
+
if [ "$LABELS_ENABLED" != "true" ]; then return 0; fi
|
|
52
|
+
if label_exists "$1"; then
|
|
53
|
+
gh issue edit "$2" --remove-label "$1"
|
|
54
|
+
fi
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# Pipeline labels are mutually exclusive: setting one removes the others first.
|
|
58
|
+
set_pipeline_label() {
|
|
59
|
+
if [ "$LABELS_ENABLED" != "true" ]; then return 0; fi
|
|
60
|
+
for label in $PIPELINE_LABELS; do
|
|
61
|
+
[ "$label" = "$2" ] && continue
|
|
62
|
+
gh pr edit "$1" --remove-label "$label" 2>/dev/null || true
|
|
63
|
+
done
|
|
64
|
+
apply_label "$2" "$1"
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
When operating on a different repository than the current checkout, add `--repo "$REPO"` to each command inside the guards and check label existence against that repo (`gh label list --repo "$REPO"`).
|
|
69
|
+
|
|
70
|
+
## Operations
|
|
71
|
+
|
|
72
|
+
### Identity and repository
|
|
73
|
+
|
|
74
|
+
#### auth-check
|
|
75
|
+
Verify the CLI is authenticated. → exit status.
|
|
76
|
+
```bash
|
|
77
|
+
gh auth status
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### current-user
|
|
81
|
+
→ the automation user's login.
|
|
82
|
+
```bash
|
|
83
|
+
CURRENT_USER=$(gh api user --jq '.login')
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### repo-info
|
|
87
|
+
→ `owner/name` handle and default branch of the current repository.
|
|
88
|
+
```bash
|
|
89
|
+
gh repo view --json nameWithOwner,defaultBranchRef
|
|
90
|
+
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### default-branch
|
|
94
|
+
→ the repository's default branch name (used when the config's `baseBranch` is `"auto"`).
|
|
95
|
+
```bash
|
|
96
|
+
BASE_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' 2>/dev/null || true)
|
|
97
|
+
[ -z "$BASE_BRANCH" ] && BASE_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
|
|
98
|
+
[ -z "$BASE_BRANCH" ] && BASE_BRANCH="main"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Issues
|
|
102
|
+
|
|
103
|
+
#### get-issue
|
|
104
|
+
`{issueId}`, field list → issue data. Request only the fields the calling skill names.
|
|
105
|
+
```bash
|
|
106
|
+
gh issue view {issueId} --repo {owner}/{repo} --json number,title,body,state,author,url,labels,assignees,comments
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### search-issues
|
|
110
|
+
Query (text, `in:title,body`, state) → matching issues.
|
|
111
|
+
```bash
|
|
112
|
+
gh issue list --repo {owner}/{repo} --state open --search "<query> in:title,body" --json number,title,url
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### create-issue
|
|
116
|
+
Title, body, assignee, labels → created issue URL.
|
|
117
|
+
```bash
|
|
118
|
+
gh issue create --repo {owner}/{repo} --title "<title>" --assignee <login> --label <labels> --body "<body>"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### close-issue
|
|
122
|
+
`{issueId}`, reason, closing comment.
|
|
123
|
+
```bash
|
|
124
|
+
gh issue close {issueId} --repo {owner}/{repo} --reason completed --comment "<comment>"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### comment-issue
|
|
128
|
+
`{issueId}`, body (use a heredoc/body-file for multi-line bodies).
|
|
129
|
+
```bash
|
|
130
|
+
gh issue comment {issueId} --repo {owner}/{repo} --body "<body>"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### assign-issue / unassign-issue
|
|
134
|
+
```bash
|
|
135
|
+
gh issue edit {issueId} --repo {owner}/{repo} --add-assignee "<login>"
|
|
136
|
+
gh issue edit {issueId} --repo {owner}/{repo} --remove-assignee "<login>"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### label-issue / unlabel-issue
|
|
140
|
+
Always through the guards: `apply_issue_label "<label>" {issueId}` / `remove_issue_label "<label>" {issueId}`.
|
|
141
|
+
|
|
142
|
+
#### get-issue-comment
|
|
143
|
+
Comment id → body, author, URL.
|
|
144
|
+
```bash
|
|
145
|
+
gh api repos/{owner}/{repo}/issues/comments/{commentId} --jq '{body,user:.user.login,url:.html_url}'
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### list-issue-comments
|
|
149
|
+
`{issueId or prNumber}` → conversation comments (PR conversation comments are issue comments on GitHub).
|
|
150
|
+
```bash
|
|
151
|
+
gh api repos/{owner}/{repo}/issues/{number}/comments --jq '.[] | {id,user:.user.login,body}'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Pull requests
|
|
155
|
+
|
|
156
|
+
#### get-pr
|
|
157
|
+
`{prNumber}`, field list → PR data. Request only the fields the calling skill names; the full field set skills use:
|
|
158
|
+
```bash
|
|
159
|
+
gh pr view {prNumber} --json number,title,url,body,state,author,isDraft,baseRefName,baseRefOid,headRefName,headRefOid,headRepository,headRepositoryOwner,isCrossRepository,maintainerCanModify,mergeable,mergeStateStatus,reviewDecision,labels,latestReviews,reviews,commits,files,assignees,comments,mergedAt,mergeCommit,closingIssuesReferences
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### list-prs
|
|
163
|
+
State/search filters, field list, limit → PRs.
|
|
164
|
+
```bash
|
|
165
|
+
gh pr list --state open --json number,title,url,author,labels,reviewDecision,mergeable,mergeStateStatus,headRefName,baseRefName,updatedAt,isDraft,assignees --limit 100
|
|
166
|
+
gh pr list --state merged --search "merged:>=${SINCE_DATE}" --json number,title,url,body,author,mergedAt,mergeCommit,baseRefName,headRefName,closingIssuesReferences,labels --limit {limit}
|
|
167
|
+
gh pr list --state closed --search "closed:>=${SINCE_DATE} is:unmerged" --json number,title,url,body,author,closedAt,baseRefName,headRefName,closingIssuesReferences,labels --limit {limit}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### search-prs
|
|
171
|
+
Free-text query (for example an issue reference) and state → matching PRs.
|
|
172
|
+
```bash
|
|
173
|
+
gh search prs --repo {owner}/{repo} "#{issueId}" --state open --json number,title,url,state
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### create-pr
|
|
177
|
+
Base branch, draft flag, title, body → PR.
|
|
178
|
+
```bash
|
|
179
|
+
gh pr create --repo {owner}/{repo} --base "$BASE_BRANCH" --draft --title "<title>" --body "<body>"
|
|
180
|
+
PR_URL=$(gh pr view --json url --jq .url)
|
|
181
|
+
PR_NUMBER=$(gh pr view --json number --jq .number)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### comment-pr
|
|
185
|
+
`{prNumber}`, body. For long structured comments:
|
|
186
|
+
```bash
|
|
187
|
+
gh pr comment {prNumber} --body-file <path-or-process-substitution>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### attach-image-evidence
|
|
191
|
+
`{prNumber}`, a markdown comment body (without the images), a `{slug}` (e.g. `pr-{prNumber}`), and a list of local PNG paths → post one comment with the images embedded **inline**, and return the comment URL.
|
|
192
|
+
|
|
193
|
+
GitHub does not accept image bytes through the comment API, so make the images referenceable first. For a **public** repo, upload them to a dedicated **slash-free** evidence branch (never the change's own branch) via the Contents API and reference `raw.githubusercontent.com` URLs — those render inline in comments:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
OWNER_REPO=$(gh repo view --json nameWithOwner --jq .nameWithOwner)
|
|
197
|
+
EVIDENCE_BRANCH="qa-evidence-{slug}" # slash-free: some raw URLs 404 on slashed refs
|
|
198
|
+
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
|
|
199
|
+
|
|
200
|
+
# create the evidence branch if missing (branched from the default branch head)
|
|
201
|
+
gh api "repos/${OWNER_REPO}/git/refs/heads/${EVIDENCE_BRANCH}" >/dev/null 2>&1 || {
|
|
202
|
+
SHA=$(gh api "repos/${OWNER_REPO}/git/refs/heads/${DEFAULT_BRANCH}" --jq .object.sha)
|
|
203
|
+
gh api -X POST "repos/${OWNER_REPO}/git/refs" -f ref="refs/heads/${EVIDENCE_BRANCH}" -f sha="$SHA" >/dev/null
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# upload each image. An image-sized base64 string blows the shell arg limit, so it
|
|
207
|
+
# must never touch a command line — write it to a temp file and let `jq --rawfile`
|
|
208
|
+
# read it into the JSON body, which `gh api --input -` sends over stdin. Pass the
|
|
209
|
+
# existing blob sha to overwrite on re-runs.
|
|
210
|
+
BODY_IMAGES=""
|
|
211
|
+
for img in <image-paths>; do
|
|
212
|
+
path="{slug}/$(basename "$img")"
|
|
213
|
+
base64 < "$img" | tr -d '\n' > /tmp/ev-content.b64 # portable across GNU/BSD; no newlines
|
|
214
|
+
existing=$(gh api "repos/${OWNER_REPO}/contents/${path}?ref=${EVIDENCE_BRANCH}" --jq .sha 2>/dev/null || true)
|
|
215
|
+
jq -n --rawfile c /tmp/ev-content.b64 --arg m "qa evidence {slug}" --arg b "$EVIDENCE_BRANCH" --arg s "$existing" \
|
|
216
|
+
'if $s == "" then {message:$m,branch:$b,content:$c} else {message:$m,branch:$b,content:$c,sha:$s} end' \
|
|
217
|
+
| gh api -X PUT "repos/${OWNER_REPO}/contents/${path}" --input - >/dev/null
|
|
218
|
+
url="https://raw.githubusercontent.com/${OWNER_REPO}/${EVIDENCE_BRANCH}/${path}"
|
|
219
|
+
BODY_IMAGES="${BODY_IMAGES}\n"
|
|
220
|
+
done
|
|
221
|
+
|
|
222
|
+
# assemble the comment (caller's body + the image markdown) and post it
|
|
223
|
+
{ cat <body-file>; printf "%b" "$BODY_IMAGES"; } | gh pr comment {prNumber} --body-file -
|
|
224
|
+
gh pr view {prNumber} --json url --jq .url
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Fallbacks: for a **private** repo the raw URLs need auth and will not render — post the comment with the image links plus the local artifact paths and note that inline rendering is unavailable (a private-visibility limit), rather than failing. When even the evidence branch cannot be pushed (no write access), degrade to listing the artifact paths in the comment. Never store evidence on the change's own branch, and never force-push.
|
|
228
|
+
|
|
229
|
+
#### assign-pr / unassign-pr
|
|
230
|
+
```bash
|
|
231
|
+
gh pr edit {prNumber} --add-assignee "<login>"
|
|
232
|
+
gh pr edit {prNumber} --remove-assignee "<login>"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### label-pr / unlabel-pr
|
|
236
|
+
Always through the guards: `apply_label "<label>" {prNumber}` / `set_pipeline_label {prNumber} "<label>"` for the mutually exclusive pipeline group; direct removal:
|
|
237
|
+
```bash
|
|
238
|
+
gh pr edit {prNumber} --remove-label "<label>"
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### get-pr-diff
|
|
242
|
+
`{prNumber}` → full diff, or the changed-file list with `--name-only`.
|
|
243
|
+
```bash
|
|
244
|
+
gh pr diff {prNumber}
|
|
245
|
+
gh pr diff {prNumber} --name-only
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### get-pr-files
|
|
249
|
+
`{prNumber}` → changed files with per-file status (added/modified/removed), paginated.
|
|
250
|
+
```bash
|
|
251
|
+
gh api "repos/{owner}/{repo}/pulls/{prNumber}/files" --paginate --jq '.[] | {path: .filename, status: .status}'
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### checkout-pr
|
|
255
|
+
`{prNumber}` → the PR's head available locally (needed for cross-repository fork PRs where the head branch cannot be fetched from `origin`).
|
|
256
|
+
```bash
|
|
257
|
+
gh pr checkout {prNumber} --recurse-submodules=no
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### review-pr
|
|
261
|
+
`{prNumber}`, verdict (approve / request changes), body.
|
|
262
|
+
```bash
|
|
263
|
+
gh pr review {prNumber} --approve --body "<body>"
|
|
264
|
+
gh pr review {prNumber} --request-changes --body "<body>"
|
|
265
|
+
```
|
|
266
|
+
GitHub rejects self-approval (reviewing your own PR); surface that instead of working around it.
|
|
267
|
+
|
|
268
|
+
#### merge-pr
|
|
269
|
+
`{prNumber}`; squash is the default merge strategy. `--auto` merges when checks pass; `--delete-branch` only when asked.
|
|
270
|
+
```bash
|
|
271
|
+
gh pr merge {prNumber} --squash
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### mark-pr-ready
|
|
275
|
+
Promote a draft PR.
|
|
276
|
+
```bash
|
|
277
|
+
gh pr ready {prNumber}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### get-pr-checks
|
|
281
|
+
`{prNumber}` → CI check runs with name, state, and link.
|
|
282
|
+
```bash
|
|
283
|
+
gh pr checks {prNumber} --json name,state,link
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### get-required-checks
|
|
287
|
+
Base branch → the set of required status checks. A 404 means branch protection is not readable — treat all reported checks as required.
|
|
288
|
+
```bash
|
|
289
|
+
gh api repos/{owner}/{repo}/branches/{baseRefName}/protection/required_status_checks --jq '.contexts[]' 2>/dev/null
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
#### get-pr-comment / get-review-comment
|
|
293
|
+
Conversation comment id (`issuecomment-<id>` links) vs inline review comment id (`discussion_r<id>` links) → body, author, URL.
|
|
294
|
+
```bash
|
|
295
|
+
gh api repos/{owner}/{repo}/issues/comments/{commentId} --jq '{body,user:.user.login,url:.html_url}'
|
|
296
|
+
gh api repos/{owner}/{repo}/pulls/comments/{commentId} --jq '{body,user:.user.login,url:.html_url}'
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### CI runs
|
|
300
|
+
|
|
301
|
+
CI status for a *PR* comes from **get-pr-checks** / **get-required-checks** above. The operations here address CI runs directly — needed when working from a bare branch, or when a failure diagnosis needs the actual logs.
|
|
302
|
+
|
|
303
|
+
#### list-runs
|
|
304
|
+
Branch (or head SHA) → recent workflow runs with id, workflow name, status, and conclusion.
|
|
305
|
+
```bash
|
|
306
|
+
gh run list --branch {branch} --limit 20 --json databaseId,workflowName,name,status,conclusion,headSha,url,createdAt
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### get-run
|
|
310
|
+
Run id → status, conclusion, and per-job breakdown.
|
|
311
|
+
```bash
|
|
312
|
+
gh run view {runId} --json status,conclusion,workflowName,headSha,url,jobs
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### get-run-failed-logs
|
|
316
|
+
Run id → the log output of failed steps only. This is the primary diagnosis input for CI failures.
|
|
317
|
+
```bash
|
|
318
|
+
gh run view {runId} --log-failed
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### rerun-failed
|
|
322
|
+
Run id → re-execute only the failed jobs of that run. Use to disambiguate flaky failures before changing any code.
|
|
323
|
+
```bash
|
|
324
|
+
gh run rerun {runId} --failed
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### watch-run
|
|
328
|
+
Run id → block until the run completes, exiting non-zero on failure. Prefer this over sleep-polling; fall back to periodic **get-run** when watching is unavailable.
|
|
329
|
+
```bash
|
|
330
|
+
gh run watch {runId} --exit-status
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Labels
|
|
334
|
+
|
|
335
|
+
#### list-labels
|
|
336
|
+
→ all label names defined in the repo.
|
|
337
|
+
```bash
|
|
338
|
+
gh label list --limit 200 --json name --jq '.[].name'
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### create-label
|
|
342
|
+
Name, color, description. Never delete, rename, or recolor existing labels.
|
|
343
|
+
```bash
|
|
344
|
+
gh label create <name> --color <hex> --description "<description>"
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
#### ensure-label-taxonomy
|
|
348
|
+
Create every label from the config's taxonomy that does not exist yet (used by `om-setup-agent-pipeline`; skip ones that already exist per **list-labels**):
|
|
349
|
+
```bash
|
|
350
|
+
gh label create review --color 0366d6 --description "Ready for code review"
|
|
351
|
+
gh label create changes-requested --color b60205 --description "Reviewer requested changes"
|
|
352
|
+
gh label create qa --color fbca04 --description "Manual QA in progress"
|
|
353
|
+
gh label create qa-failed --color b60205 --description "Manual QA failed"
|
|
354
|
+
gh label create merge-queue --color 0e8a16 --description "Approved, ready to merge"
|
|
355
|
+
gh label create blocked --color b60205 --description "Blocked by a dependency"
|
|
356
|
+
gh label create do-not-merge --color b60205 --description "Hard merge block"
|
|
357
|
+
gh label create bug --color d73a4a --description "Bug fix"
|
|
358
|
+
gh label create feature --color a2eeef --description "New capability"
|
|
359
|
+
gh label create refactor --color cfd3d7 --description "No behavior change"
|
|
360
|
+
gh label create security --color b60205 --description "Security-relevant change"
|
|
361
|
+
gh label create dependencies --color 0366d6 --description "Dependency update"
|
|
362
|
+
gh label create documentation --color 0075ca --description "Docs only"
|
|
363
|
+
gh label create needs-qa --color fbca04 --description "Requires manual QA before merge"
|
|
364
|
+
gh label create skip-qa --color 0e8a16 --description "Low risk, QA not required"
|
|
365
|
+
gh label create qa-approved --color 0e8a16 --description "Manual QA passed"
|
|
366
|
+
gh label create qa-self-verified --color c5def5 --description "Self-QA exception used"
|
|
367
|
+
gh label create in-progress --color c5def5 --description "An automated skill is working on this"
|
|
368
|
+
gh label create do-not-close --color c5def5 --description "Humans only: never auto-close this issue"
|
|
369
|
+
gh label create priority-low --color e4e669 --description "Cosmetic or follow-up work"
|
|
370
|
+
gh label create priority-medium --color fbca04 --description "Ordinary bug or feature"
|
|
371
|
+
gh label create priority-high --color d93f0b --description "Release-blocking"
|
|
372
|
+
gh label create priority-extreme --color b60205 --description "Outage or security incident"
|
|
373
|
+
gh label create risk-low --color 0e8a16 --description "Isolated, low blast radius"
|
|
374
|
+
gh label create risk-medium --color fbca04 --description "Ordinary change with tests"
|
|
375
|
+
gh label create risk-high --color b60205 --description "Wide blast radius, review deeply"
|
|
376
|
+
```
|