@sentry/junior-github 0.104.1 → 0.105.0
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/SETUP.md +2 -2
- package/dist/index.js +45 -4
- package/package.json +2 -2
- package/skills/attach-github-assets/SOURCES.md +1 -1
- package/skills/attach-github-assets/SPEC.md +2 -2
- package/skills/github-code/SKILL.md +49 -142
- package/skills/github-code/SPEC.md +42 -0
- package/skills/github-code/references/api-surface.md +7 -4
- package/skills/github-code/references/troubleshooting-workarounds.md +21 -18
package/SETUP.md
CHANGED
|
@@ -98,8 +98,8 @@ Use `additionalUserScopes` only when a human-identity integration flow requires
|
|
|
98
98
|
## 3) Runtime behavior
|
|
99
99
|
|
|
100
100
|
- When either GitHub skill is active, authenticated `gh` and `git` commands cause the runtime to inject GitHub credentials automatically for the current turn.
|
|
101
|
-
- The plugin classifies GitHub traffic from the forwarded HTTP request. Reads use `installation-read`, while `GET /user` uses `user-read`. Allowlisted App-owned mutations
|
|
102
|
-
- `user-read` and
|
|
101
|
+
- The plugin classifies GitHub traffic from the forwarded HTTP request. Reads use `installation-read`, while `GET /user` uses `user-read`. Allowlisted App-owned mutations, Git smart-HTTP pushes, and user-attachment uploads to `uploads.github.com/user-attachments/assets` use repository-scoped `installation-write`. Unknown REST writes and GraphQL mutations are denied.
|
|
102
|
+
- `user-read` and explicitly human `user-write` operations require the actor, or an explicitly delegated user subject, to authorize the GitHub App through the private OAuth flow. Junior-owned issue, pull request, branch, and asset-upload operations do not fall back to user OAuth.
|
|
103
103
|
- Headless resource-event turns use the `resource-event` system actor and may receive the same repository-scoped installation grants. This lets Junior respond to subscribed pull request events by committing and pushing fixes without inheriting a subscriber's OAuth credential.
|
|
104
104
|
- Git commits use Junior as author and committer. Resolvable human run actors are credited once with `Co-Authored-By` trailers.
|
|
105
105
|
- Issued credentials are reused only within the current turn, credential leases are cached by plugin grant and repository lease scope, and upstream 403 permission denials clear the cached lease before the next retry.
|
package/dist/index.js
CHANGED
|
@@ -857,7 +857,7 @@ var USER_WRITE_REQUIREMENTS = [
|
|
|
857
857
|
"requesting GitHub user permission to perform this operation"
|
|
858
858
|
];
|
|
859
859
|
var GITHUB_CREDENTIAL_DOMAINS = ["api.github.com", "github.com"];
|
|
860
|
-
var
|
|
860
|
+
var GITHUB_ASSET_UPLOAD_CREDENTIAL_DOMAINS = [
|
|
861
861
|
...GITHUB_CREDENTIAL_DOMAINS,
|
|
862
862
|
"uploads.github.com"
|
|
863
863
|
];
|
|
@@ -1318,7 +1318,7 @@ function createCredentialLease(input) {
|
|
|
1318
1318
|
...input.account ? { account: input.account } : {},
|
|
1319
1319
|
...input.authorization ? { authorization: input.authorization } : {},
|
|
1320
1320
|
expiresAt: new Date(input.expiresAtMs).toISOString(),
|
|
1321
|
-
headerTransforms: (input.authorization ?
|
|
1321
|
+
headerTransforms: (input.domains ?? (input.authorization ? GITHUB_ASSET_UPLOAD_CREDENTIAL_DOMAINS : GITHUB_CREDENTIAL_DOMAINS)).map((domain) => ({
|
|
1322
1322
|
domain,
|
|
1323
1323
|
headers: {
|
|
1324
1324
|
Authorization: authorizationFor(domain, input.token)
|
|
@@ -1405,6 +1405,28 @@ function githubRepositoryFromLeaseScope(leaseScope) {
|
|
|
1405
1405
|
}
|
|
1406
1406
|
return { owner: match[1], name: match[2] };
|
|
1407
1407
|
}
|
|
1408
|
+
function githubRepositoryIdFromUploadUrl(upstreamUrl) {
|
|
1409
|
+
const repositoryId = Number(upstreamUrl.searchParams.get("repository_id"));
|
|
1410
|
+
if (!Number.isSafeInteger(repositoryId) || repositoryId <= 0) {
|
|
1411
|
+
throw new EgressPolicyDenied(
|
|
1412
|
+
"GitHub asset upload request is missing a valid repository_id."
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1415
|
+
return repositoryId;
|
|
1416
|
+
}
|
|
1417
|
+
function githubRepositoryIdLeaseScope(repositoryId) {
|
|
1418
|
+
return `repository-id:${repositoryId}`;
|
|
1419
|
+
}
|
|
1420
|
+
function githubRepositoryIdFromLeaseScope(leaseScope) {
|
|
1421
|
+
const match = /^repository-id:(\d+)$/.exec(leaseScope ?? "");
|
|
1422
|
+
const repositoryId = Number(match?.[1]);
|
|
1423
|
+
if (!Number.isSafeInteger(repositoryId) || repositoryId <= 0) {
|
|
1424
|
+
throw new GitHubPluginSetupError(
|
|
1425
|
+
"GitHub asset upload grant is missing a repository id lease scope."
|
|
1426
|
+
);
|
|
1427
|
+
}
|
|
1428
|
+
return repositoryId;
|
|
1429
|
+
}
|
|
1408
1430
|
async function resolveUserAccount(tokens) {
|
|
1409
1431
|
const account = await githubRequest("https://api.github.com", "/user", {
|
|
1410
1432
|
token: tokens.accessToken
|
|
@@ -1582,7 +1604,7 @@ async function issueInstallationCredential(options) {
|
|
|
1582
1604
|
throw new GitHubPluginSetupError(`Invalid ${options.installationIdEnv}`);
|
|
1583
1605
|
}
|
|
1584
1606
|
const appJwt = createAppJwt(appId, options.privateKeyEnv);
|
|
1585
|
-
const body = "repositories" in options ? { repositories: options.repositories } : {
|
|
1607
|
+
const body = "repositories" in options ? { repositories: options.repositories } : "repositoryIds" in options ? { repository_ids: options.repositoryIds } : {
|
|
1586
1608
|
permissions: "permissions" in options ? options.permissions : await options.loadPermissions({ appJwt, installationId })
|
|
1587
1609
|
};
|
|
1588
1610
|
const accessTokenResponse = await githubRequest(
|
|
@@ -1600,6 +1622,7 @@ async function issueInstallationCredential(options) {
|
|
|
1600
1622
|
Date.now() + MAX_LEASE_MS
|
|
1601
1623
|
);
|
|
1602
1624
|
return createCredentialLease({
|
|
1625
|
+
...options.domains ? { domains: options.domains } : {},
|
|
1603
1626
|
token: parsedToken.token,
|
|
1604
1627
|
expiresAtMs
|
|
1605
1628
|
});
|
|
@@ -1918,7 +1941,13 @@ async function githubGrantForEgress(ctx) {
|
|
|
1918
1941
|
upstreamUrl
|
|
1919
1942
|
});
|
|
1920
1943
|
if (isGitHubAssetUploadRequest(method, upstreamUrl)) {
|
|
1921
|
-
|
|
1944
|
+
const repositoryId = githubRepositoryIdFromUploadUrl(upstreamUrl);
|
|
1945
|
+
return grantForAccess(
|
|
1946
|
+
"write",
|
|
1947
|
+
"github.asset-upload",
|
|
1948
|
+
"installation-write",
|
|
1949
|
+
githubRepositoryIdLeaseScope(repositoryId)
|
|
1950
|
+
);
|
|
1922
1951
|
}
|
|
1923
1952
|
const smartHttpAccess = githubSmartHttpAccess(upstreamUrl);
|
|
1924
1953
|
if (smartHttpAccess) {
|
|
@@ -2109,6 +2138,18 @@ function githubPlugin(options = {}) {
|
|
|
2109
2138
|
});
|
|
2110
2139
|
}
|
|
2111
2140
|
if (ctx.grant.name === "installation-write") {
|
|
2141
|
+
if (ctx.grant.reason === "github.asset-upload") {
|
|
2142
|
+
const repositoryId = githubRepositoryIdFromLeaseScope(
|
|
2143
|
+
ctx.grant.leaseScope
|
|
2144
|
+
);
|
|
2145
|
+
return await issueInstallationCredential({
|
|
2146
|
+
appIdEnv,
|
|
2147
|
+
domains: GITHUB_ASSET_UPLOAD_CREDENTIAL_DOMAINS,
|
|
2148
|
+
privateKeyEnv,
|
|
2149
|
+
installationIdEnv,
|
|
2150
|
+
repositoryIds: [repositoryId]
|
|
2151
|
+
});
|
|
2152
|
+
}
|
|
2112
2153
|
const repository = githubRepositoryFromLeaseScope(
|
|
2113
2154
|
ctx.grant.leaseScope
|
|
2114
2155
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.105.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@sinclair/typebox": "^0.34.49",
|
|
27
27
|
"zod": "^4.4.3",
|
|
28
|
-
"@sentry/junior-plugin-api": "0.
|
|
28
|
+
"@sentry/junior-plugin-api": "0.105.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^25.9.1",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
- **Adopted:** preserve the upstream one-file-per-upload behavior, supported formats, markdown output, and upload endpoint.
|
|
15
15
|
- **Adopted:** preserve the upstream MIT license in the skill directory as explicitly required.
|
|
16
|
-
- **Replaced:** direct `gh auth token` access with Junior's host-managed
|
|
16
|
+
- **Replaced:** direct `gh auth token` access with Junior's host-managed, repository-scoped installation credential injection so credentials never enter script output or files.
|
|
17
17
|
- **Replaced:** numeric repository-id override with explicit `owner/repo`; the script resolves the id through authenticated `gh api`.
|
|
18
18
|
- **Narrowed:** automatic activation requires a concrete local path and GitHub destination.
|
|
19
19
|
- **Deferred:** live upload verification because it would create an external GitHub asset; deterministic mocked validation is sufficient for implementation checks.
|
|
@@ -23,7 +23,7 @@ Out of scope:
|
|
|
23
23
|
- Run `scripts/upload.sh` once per local file.
|
|
24
24
|
- Return image markdown or a bare video URL.
|
|
25
25
|
- Surface per-file failures exactly enough for the user to act.
|
|
26
|
-
- Use the GitHub plugin's
|
|
26
|
+
- Use the GitHub plugin's repository-scoped installation credential injection; do not retrieve tokens in the script.
|
|
27
27
|
|
|
28
28
|
## Reference Architecture
|
|
29
29
|
|
|
@@ -40,7 +40,7 @@ Out of scope:
|
|
|
40
40
|
## Known Limitations
|
|
41
41
|
|
|
42
42
|
- GitHub's user-attachment endpoint is not part of the documented public REST API.
|
|
43
|
-
- A real upload requires GitHub to accept the
|
|
43
|
+
- A real upload requires GitHub to accept the repository-scoped installation credential for the target repository.
|
|
44
44
|
|
|
45
45
|
## Maintenance Notes
|
|
46
46
|
|
|
@@ -1,180 +1,87 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-code
|
|
3
|
-
description: Work with GitHub repositories, source code, branches, commits,
|
|
3
|
+
description: Work with GitHub repositories, source code, branches, commits, pull requests, reviews, diffs, CI, and repository credentials. Use for implementation, source investigation, clone/fetch/branch workflows, PR creation or updates, review feedback, GitHub Actions checks, and repository permission failures. Prefer this skill for repository tasks even when they concern a Sentry product.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# GitHub Code Operations
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- Supported App-owned GitHub operations require no user-managed credential. Junior automatically mints and injects a repository-scoped GitHub App `installation-write` credential.
|
|
11
|
-
- For a pull request from an existing branch, push the branch first, then call `github_createPullRequest`; both operations receive the automatic installation credential.
|
|
12
|
-
- Do not ask the user to authorize GitHub, provide a token, or grant Contents/Pull requests permissions before trying a supported operation.
|
|
13
|
-
- Request remediation only after a supported operation returns evidence of an upstream provider denial. A Junior tool-routing denial means retry with the required tool, not request permissions.
|
|
14
|
-
|
|
15
|
-
Use `gh` and `git` for repository checkout, source investigation, code changes, commits, and pull request inspection or mutation. Use Junior's `github_createPullRequest` tool instead of `gh pr create` for new pull requests.
|
|
8
|
+
Use `git` and `gh` for repository work. Use `github_createPullRequest`, not `gh pr create`, for new PRs.
|
|
16
9
|
|
|
17
10
|
## References
|
|
18
11
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
| Command syntax, permissions, config
|
|
22
|
-
| Failed commands
|
|
12
|
+
| Open when you need | Read |
|
|
13
|
+
| -------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
14
|
+
| Command syntax, permissions, config | [references/api-surface.md](references/api-surface.md) |
|
|
15
|
+
| Failed commands or permission recovery | [references/troubleshooting-workarounds.md](references/troubleshooting-workarounds.md) |
|
|
23
16
|
|
|
24
|
-
##
|
|
17
|
+
## Non-negotiable rules
|
|
25
18
|
|
|
26
|
-
- Resolve the
|
|
27
|
-
- Keep `--repo owner/repo` explicit on
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- Do not
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Stop on: missing repo access, ambiguous target, destructive op without confirmation, or unresolved permission failure.
|
|
19
|
+
- Resolve the repo from the explicit request, then `github.repo`. Run `jr-rpc config get github.repo` standalone.
|
|
20
|
+
- Keep `--repo owner/repo` explicit on `gh`; use `git -C PATH` for local repos.
|
|
21
|
+
- Read applicable `AGENTS.md` files before editing. Narrower repo/task instructions win.
|
|
22
|
+
- Preserve unrelated work. Never force-push, delete refs, or perform destructive merges.
|
|
23
|
+
- Base conclusions on repository evidence. Do not claim a check ran unless it did.
|
|
24
|
+
- Supported App-owned writes use an automatically injected repository-scoped credential. Try the operation before requesting remediation; ask for no user token.
|
|
25
|
+
- Stop for ambiguous targets, missing access, destructive operations, or unresolved upstream permission failures.
|
|
34
26
|
|
|
35
27
|
## Workflow
|
|
36
28
|
|
|
37
|
-
### 1. Resolve
|
|
38
|
-
|
|
39
|
-
Identify `owner/repo`, local checkout path, default branch, and current branch.
|
|
40
|
-
|
|
41
|
-
For edit operations, also check:
|
|
42
|
-
|
|
43
|
-
- current branch and uncommitted changes
|
|
44
|
-
- package manager, build tool, monorepo structure
|
|
45
|
-
- relevant test/lint/typecheck commands
|
|
46
|
-
- repo-local instructions that override this skill
|
|
47
|
-
|
|
48
|
-
Choose a validation path before editing:
|
|
49
|
-
|
|
50
|
-
- changed-file or package-scoped checks before broad suites
|
|
51
|
-
- targeted tests before full runs
|
|
52
|
-
- repo-native scripts, fixtures, playgrounds, or smoke checks before one-off scaffolding
|
|
53
|
-
|
|
54
|
-
For risky, user-visible, or long-running changes, capture a baseline before editing. If the baseline already fails, record it as pre-existing.
|
|
55
|
-
|
|
56
|
-
Prefer existing local checkouts over cloning. Default to shallow clones.
|
|
57
|
-
|
|
58
|
-
### 2. Investigate before editing
|
|
59
|
-
|
|
60
|
-
Before changing code, establish:
|
|
61
|
-
|
|
62
|
-
- where the behavior lives
|
|
63
|
-
- what the current vs. requested behavior is
|
|
64
|
-
- root cause or gap the change addresses
|
|
65
|
-
- what smallest check can prove the result
|
|
66
|
-
|
|
67
|
-
Rules:
|
|
68
|
-
|
|
69
|
-
- Prefer narrow evidence: file reads, grep, tests, existing issues/PRs, command output.
|
|
70
|
-
- Read referenced issues, PRs, specs, policies, designs, or incidents when the task points to them.
|
|
71
|
-
- For product copy, docs, design, or UI work, inspect the real product/project context before inventing wording or layout.
|
|
72
|
-
- Before editing a bug, know the failure shape: what breaks, where, and under what condition.
|
|
73
|
-
- After a failed fix attempt or strong correction, stop patching symptoms — re-read the evidence and restate the root cause before editing again.
|
|
74
|
-
- If the task is investigation-only, answer from evidence without editing.
|
|
75
|
-
|
|
76
|
-
**Advisor planning checkpoint:** For a non-trivial implementation — especially architecture or API changes, security-sensitive behavior, concurrency, migrations, broad cross-file edits, or work following failed attempts — call the advisor after gathering enough evidence and before editing. Provide the requirements, relevant code and output, constraints, proposed plan, alternatives considered, risks, and intended validation path. Resolve or explicitly account for material concerns before implementing.
|
|
77
|
-
|
|
78
|
-
### 3. Edit safely
|
|
79
|
-
|
|
80
|
-
- Smallest coherent change that satisfies the request.
|
|
81
|
-
- Follow repo-local style, patterns, and API boundaries.
|
|
82
|
-
- Keep interfaces, exports, config, and public surfaces no broader than the requirement needs.
|
|
83
|
-
- When the change touches related call sites or representations, remove duplication or split logic introduced by the change before finalizing.
|
|
84
|
-
- No drive-by refactors or speculative cleanup.
|
|
85
|
-
- Do not optimize only for passing tests; solve the requested behavior.
|
|
86
|
-
- After meaningful edits, run the smallest relevant repo-real check.
|
|
87
|
-
- On check failure, inspect root cause before patching again.
|
|
88
|
-
|
|
89
|
-
For multi-step or risky work, keep a compact checklist of intent, touched files, verification state, next step, and blockers.
|
|
90
|
-
|
|
91
|
-
### 4. Verify before packaging
|
|
92
|
-
|
|
93
|
-
Before committing and creating a PR for code, config, or docs-as-code changes:
|
|
94
|
-
|
|
95
|
-
- Run the chosen validation path. Separate pre-existing failures from regressions.
|
|
96
|
-
- For docs or instruction-only changes, do a content consistency review instead of claiming automated validation.
|
|
97
|
-
- If no credible check exists, say so explicitly.
|
|
98
|
-
|
|
99
|
-
**Advisor review checkpoint:** For a non-trivial implementation, call the advisor after inspecting the final diff and running the initial validation path, but before committing, opening or updating a PR, or reporting completion. Provide the diff, relevant surrounding code, requirements, validation results, known limitations, and any remaining risks. Ask specifically for correctness issues, regressions, missed cases, and testing gaps. Investigate material findings, revise as needed, and rerun affected checks before packaging.
|
|
100
|
-
|
|
101
|
-
### 5. Commit
|
|
102
|
-
|
|
103
|
-
Default format when the repo does not specify otherwise:
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
<type>(<scope>): <Subject>
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Types: `feat`, `fix`, `ref`, `docs`, `test`, `build`, `ci`, `chore`. Imperative present tense, no trailing period, no agent/tool branding. Keep lines under 100 characters.
|
|
110
|
-
|
|
111
|
-
Body only when it helps reviewers understand _why_.
|
|
112
|
-
|
|
113
|
-
Footer order: `Fixes`/`Refs` lines.
|
|
114
|
-
|
|
115
|
-
### 6. Create or update PR
|
|
116
|
-
|
|
117
|
-
Before creating:
|
|
118
|
-
|
|
119
|
-
1. Changes committed on a non-default branch.
|
|
120
|
-
2. Push the branch explicitly: `git push -u origin BRANCH`.
|
|
121
|
-
3. Resolve the actual default branch: `gh repo view owner/repo --json defaultBranchRef --jq .defaultBranchRef.name`.
|
|
122
|
-
4. Create with explicit targeting, using that default branch as `base`: `github_createPullRequest({ repo: "owner/repo", head: "BRANCH", base: "<DEFAULT_BRANCH>", title: "...", body: "...", draft: true })`.
|
|
29
|
+
### 1. Resolve and inspect
|
|
123
30
|
|
|
124
|
-
|
|
31
|
+
Identify the repo, checkout, default/current branches, worktree state, repo instructions, package manager, and relevant checks. Prefer an existing checkout; otherwise clone shallowly.
|
|
125
32
|
|
|
126
|
-
-
|
|
127
|
-
- Reuse an existing PR for the branch; only open a new one when explicitly asked or the work is materially distinct.
|
|
128
|
-
- After new commits, re-evaluate title and body against the current diff.
|
|
33
|
+
A shallow clone is for fast inspection, not history rewriting. Before rebasing, merge-base analysis, blame/history work, or comparing against a base absent locally, fetch the needed refs and deepen incrementally. Use `--unshallow` only when bounded deepening is insufficient. Never use a force push to compensate for incomplete history.
|
|
129
34
|
|
|
130
|
-
|
|
35
|
+
For edits, choose the smallest credible validation path before changing files. Capture a baseline when a failure may be pre-existing.
|
|
131
36
|
|
|
132
|
-
|
|
37
|
+
### 2. Investigate
|
|
133
38
|
|
|
134
|
-
|
|
135
|
-
- What changed and why; what was verified; what remains unverified or risky.
|
|
136
|
-
- Issue references when relevant.
|
|
137
|
-
- No checkbox boilerplate, no PII or customer data in public repos.
|
|
39
|
+
Establish where the behavior lives, current versus requested behavior, root cause or gap, and the smallest proof of correctness. Read linked issues, PRs, specs, and failing output when provided. If the request is investigation-only, report evidence without editing.
|
|
138
40
|
|
|
139
|
-
|
|
41
|
+
For non-trivial architecture, API, security, concurrency, migration, or broad cross-file work, use the available advisor after gathering evidence and before editing. Resolve material concerns in the plan.
|
|
140
42
|
|
|
141
|
-
|
|
43
|
+
### 3. Edit
|
|
142
44
|
|
|
143
|
-
|
|
45
|
+
Make the smallest coherent change. Follow local patterns and avoid speculative cleanup. After a failed attempt, re-check the root cause before patching again.
|
|
144
46
|
|
|
145
|
-
|
|
47
|
+
Before running repo checks, ensure project dependencies are available:
|
|
146
48
|
|
|
147
|
-
|
|
49
|
+
1. Detect the package manager and lockfile from repo evidence.
|
|
50
|
+
2. If dependencies are missing or the check reports missing packages, run the repo-native frozen/immutable install (`pnpm install --frozen-lockfile`, `npm ci`, `yarn install --immutable`, `bun install --frozen-lockfile`, or the documented equivalent).
|
|
51
|
+
3. Do not regenerate or modify a lockfile merely to make verification run. If the locked install fails, report the exact failure unless dependency changes are part of the task.
|
|
148
52
|
|
|
149
|
-
|
|
150
|
-
- Write a **self-contained intent** that captures repo, PR number, branch, and a single goal: resolve any review concerns and keep the build green. When an event fires, read the signal, address it, push, and report.
|
|
151
|
-
- **Only post an update when there is something meaningful to say.** Report when feedback has been addressed, a build failure has been fixed, the PR is fully green and ready to merge, or the PR has been merged. Stay silent on intermediate CI passes, queued checks, and informational events with no action taken.
|
|
53
|
+
Do not install or repair the GitHub plugin runtime itself; that is manifest-owned setup.
|
|
152
54
|
|
|
153
|
-
|
|
55
|
+
### 4. Verify and review
|
|
154
56
|
|
|
155
|
-
|
|
57
|
+
Run targeted changed-file/package checks before broad suites. Separate regressions from baseline failures. For instruction-only changes, run available structural checks and perform a content-consistency review.
|
|
156
58
|
|
|
157
|
-
|
|
59
|
+
For non-trivial work, review the final diff and initial results with the available advisor before packaging. Address material correctness, regression, and testing concerns, then rerun affected checks.
|
|
158
60
|
|
|
159
|
-
|
|
61
|
+
### 5. Package every completed edit
|
|
160
62
|
|
|
161
|
-
|
|
63
|
+
Unless the user explicitly says not to create a PR, every completed repository edit must end in a pushed branch and PR. Default to draft; honor an explicit user or repo instruction to open it ready for review. Do not stop at local changes or a commit.
|
|
162
64
|
|
|
163
|
-
|
|
65
|
+
1. Reuse the current non-default branch or create a focused branch.
|
|
66
|
+
2. Commit using repo conventions; otherwise use `<type>(<scope>): <Subject>` in imperative present tense, with no agent branding.
|
|
67
|
+
3. Push explicitly with `git push -u origin BRANCH`.
|
|
68
|
+
4. Resolve the actual default branch.
|
|
69
|
+
5. Reuse and update an existing PR for the branch; otherwise call `github_createPullRequest` with explicit repo, head, base, title, body, and `draft: true` unless the user or repo explicitly requires ready-for-review.
|
|
164
70
|
|
|
165
|
-
|
|
71
|
+
The PR body should explain what changed and why, checks run, and remaining risks or unverified areas. Never include customer data, PII, secrets, or sensitive thread context, especially in public repositories. Re-evaluate its title/body after material follow-up commits. Resolve requested assignee/reviewer handles from evidence; skip unconfirmed identities.
|
|
166
72
|
|
|
167
|
-
|
|
73
|
+
If PR creation is blocked, report the exact failed command/tool call and leave the committed branch intact.
|
|
168
74
|
|
|
169
|
-
|
|
75
|
+
### 6. Follow and report
|
|
170
76
|
|
|
171
|
-
|
|
77
|
+
When PR creation returns a subscribable resource hint, subscribe to suggested review/CI events. Report only actionable feedback addressed, build failures fixed, fully green/ready state, or merge.
|
|
172
78
|
|
|
173
|
-
|
|
79
|
+
Return: repo, branch, PR URL/number, checks and results, pre-existing failures, and anything not run with the reason.
|
|
174
80
|
|
|
175
|
-
##
|
|
81
|
+
## Operation notes
|
|
176
82
|
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
83
|
+
- **Clone/history:** clone shallowly by default; deepen before any operation that relies on omitted ancestry.
|
|
84
|
+
- **PR inspection:** read conversation comments, inline review comments, reviews, diff, and checks.
|
|
85
|
+
- **PR mutation:** push before create; use only supported endpoints in the API reference.
|
|
86
|
+
- **Workflow dispatch:** `gh workflow run` is supported only for workflows declaring `workflow_dispatch`.
|
|
87
|
+
- **Permissions:** a tool-routing denial requires the named tool; only an upstream denial justifies permission remediation.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# github-code skill contract
|
|
2
|
+
|
|
3
|
+
## Intent
|
|
4
|
+
|
|
5
|
+
Guide evidence-first GitHub repository work from inspection through a reviewable result without duplicating command and troubleshooting detail in runtime context.
|
|
6
|
+
|
|
7
|
+
## Behavioral contract
|
|
8
|
+
|
|
9
|
+
- Resolve and inspect the repository before acting.
|
|
10
|
+
- Preserve unrelated work and reject destructive Git operations.
|
|
11
|
+
- Treat shallow clones as inspection checkouts; fetch/deepen before history-dependent operations and never force-push around missing ancestry.
|
|
12
|
+
- Install repository dependencies with the detected package manager's locked/frozen mode before verification when dependencies are absent.
|
|
13
|
+
- For every completed repository edit, create or update a pushed PR unless the user explicitly opts out; default new PRs to draft while honoring explicit ready-for-review instructions.
|
|
14
|
+
- Report exact validation and permission failures without claiming partial work is complete.
|
|
15
|
+
|
|
16
|
+
## Runtime architecture
|
|
17
|
+
|
|
18
|
+
- `SKILL.md`: compact workflow and decision rules.
|
|
19
|
+
- `references/api-surface.md`: command and permission lookup.
|
|
20
|
+
- `references/troubleshooting-workarounds.md`: failure recovery.
|
|
21
|
+
|
|
22
|
+
Do not move provider runtime installation, OAuth, or environment setup into this skill; the GitHub plugin manifest owns those concerns.
|
|
23
|
+
|
|
24
|
+
## Trigger expectations
|
|
25
|
+
|
|
26
|
+
Should trigger for implementation, source inspection, clone/fetch/branch work, commits, PRs, reviews, CI, and repository credential failures.
|
|
27
|
+
|
|
28
|
+
Should not trigger for GitHub issue-only operations, non-GitHub ticketing, product telemetry, or general product documentation with no repository task.
|
|
29
|
+
|
|
30
|
+
## Validation
|
|
31
|
+
|
|
32
|
+
After material edits:
|
|
33
|
+
|
|
34
|
+
1. Run the repository skill validator.
|
|
35
|
+
2. Run formatting or package checks applicable to changed Markdown.
|
|
36
|
+
3. Confirm all referenced files exist.
|
|
37
|
+
4. Confirm code-edit completion defaults to a draft PR.
|
|
38
|
+
5. Confirm dependency installation and shallow-history recovery do not permit lockfile mutation or force-push shortcuts.
|
|
39
|
+
|
|
40
|
+
## Maintenance
|
|
41
|
+
|
|
42
|
+
Keep workflow policy in `SKILL.md`; move syntax matrices and failure details to the routed references. Remove duplicated rules rather than restating them across sections.
|
|
@@ -25,12 +25,14 @@ Treat explicit repo flags as command-targeting safety rails, not as a credential
|
|
|
25
25
|
| Operation | Command |
|
|
26
26
|
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
27
27
|
| Clone repository (default shallow) | `gh repo clone owner/repo [DIRECTORY] -- --depth=1` |
|
|
28
|
-
|
|
|
29
|
-
|
|
|
28
|
+
| Fetch bounded base history | `git -C DIRECTORY fetch --depth=N origin BASE:refs/remotes/origin/BASE` |
|
|
29
|
+
| Deepen base history | `git -C DIRECTORY fetch --deepen=N origin BASE:refs/remotes/origin/BASE` |
|
|
30
|
+
| Convert shallow clone to full | `git -C DIRECTORY fetch --unshallow origin` |
|
|
31
|
+
| Check shallow state | `git -C DIRECTORY rev-parse --is-shallow-repository` |
|
|
30
32
|
| Check branch | `git -C DIRECTORY branch --show-current` |
|
|
31
33
|
| Check worktree state | `git -C DIRECTORY status --short --branch` |
|
|
32
|
-
| View commit log against base | `git -C DIRECTORY log BASE..HEAD --oneline`
|
|
33
|
-
| Diff against base | `git -C DIRECTORY diff BASE...HEAD`
|
|
34
|
+
| View commit log against base | `git -C DIRECTORY log origin/BASE..HEAD --oneline` |
|
|
35
|
+
| Diff against base | `git -C DIRECTORY diff origin/BASE...HEAD` |
|
|
34
36
|
| Resolve default branch | `gh repo view owner/repo --json defaultBranchRef --jq .defaultBranchRef.name` |
|
|
35
37
|
| Create branch | `git -C DIRECTORY checkout -b BRANCH` |
|
|
36
38
|
| Stage and commit | `git -C DIRECTORY add -A && git -C DIRECTORY commit -m "message"` |
|
|
@@ -66,6 +68,7 @@ jr-rpc config set github.repo owner/repo
|
|
|
66
68
|
- Pass extra `git clone` flags after `--` (e.g. `gh repo clone owner/repo -- --depth=1`).
|
|
67
69
|
- A local `git commit` does not call GitHub. Pushing that commit uses Junior's repository-scoped installation credential and requires `github.contents.write` on the target repo.
|
|
68
70
|
- If the commit changes workflow files under `.github/workflows`, the App installation needs Workflows write in addition to Contents write.
|
|
71
|
+
- Before rebasing, merge-base analysis, blame/history inspection, or a base comparison, check whether the repository is shallow. Fetch a bounded depth of the base into `refs/remotes/origin/BASE`, deepen incrementally until the needed ancestry is present, and compare against `origin/BASE`; use `--unshallow` only when bounded deepening is insufficient. Never force-push to work around missing ancestry.
|
|
69
72
|
- Before `github_createPullRequest`, push the head branch explicitly and resolve the target repo's default branch for `base`. That push requires GitHub write access to the remote.
|
|
70
73
|
- Merge, fork creation, workflow reruns or cancellations, REST contents/Git database writes, and repository administration are outside the current write allowlist.
|
|
71
74
|
- If the explicit `git push` fails with 401/403 or another access/permission error, verify the repo context and retry once. If it still fails, load troubleshooting guidance and report the exact command failure.
|
|
@@ -2,24 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
Use this table to recover quickly while keeping operations deterministic.
|
|
4
4
|
|
|
5
|
-
| Symptom
|
|
6
|
-
|
|
|
7
|
-
| `unknown command "..."` from `gh`
|
|
8
|
-
| `unknown flag: --depth` from `gh repo clone`
|
|
9
|
-
| `Missing required option --repo`
|
|
10
|
-
| Command affects or authenticates against the wrong repo
|
|
11
|
-
| `GraphQL: Could not resolve to a Repository`
|
|
12
|
-
| 401 Unauthorized
|
|
13
|
-
| `junior-auth-required provider=github grant=user-write`
|
|
14
|
-
| `git push` fails with 401/403 or auth/permission output
|
|
15
|
-
| Bash result includes `permission_denied` with `source: "upstream"`
|
|
16
|
-
| 403 without `permission_denied` where `source: "upstream"`
|
|
17
|
-
| `gh auth status` shows `Token scopes: none`
|
|
18
|
-
| `github_createPullRequest` returns upstream 401/403
|
|
19
|
-
| `github_createPullRequest` returns 422 for `head`
|
|
20
|
-
| `github_createPullRequest` fails with 422 validation on `base`
|
|
21
|
-
| `git blame`, long log history, or old commits are missing after clone
|
|
22
|
-
| `
|
|
5
|
+
| Symptom | Likely cause | Fix |
|
|
6
|
+
| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
7
|
+
| `unknown command "..."` from `gh` | CLI version too old or wrong binary in the plugin runtime. | Verify `gh --version`; if it is unavailable or too old, report that the GitHub plugin runtime dependency is not available. |
|
|
8
|
+
| `unknown flag: --depth` from `gh repo clone` | `git clone` flags were passed before `--`. | Pass clone flags after `--`, for example `gh repo clone owner/repo -- --depth=1`. |
|
|
9
|
+
| `Missing required option --repo` | Repo not passed and no default was resolved. | Resolve with `jr-rpc config get github.repo`; pass `--repo owner/repo` explicitly when missing. |
|
|
10
|
+
| Command affects or authenticates against the wrong repo | Stale `github.repo` default or authenticated command missing explicit repo. | Pass `--repo owner/repo` for the target repository, or update `github.repo` before retrying. |
|
|
11
|
+
| `GraphQL: Could not resolve to a Repository` | Repo slug is wrong or inaccessible. | Validate `owner/repo` and confirm app installation on target repository. |
|
|
12
|
+
| 401 Unauthorized | Issued GitHub credentials were rejected upstream. | Verify the target repo, then use the grant/auth signal to distinguish stale user OAuth from app installation or host env setup. |
|
|
13
|
+
| `junior-auth-required provider=github grant=user-write` | User-to-server OAuth is missing or stale for a human-identity operation. | Follow the private OAuth prompt; do not ask the user to paste or manage tokens manually. |
|
|
14
|
+
| `git push` fails with 401/403 or auth/permission output | Write permission is missing, app installation is too narrow, or remote is wrong. | Verify the remote and repo context, retry once, then confirm app permissions and installation scope if it still fails. |
|
|
15
|
+
| Bash result includes `permission_denied` with `source: "upstream"` | GitHub returned 403 after Junior injected the named grant. | Do not call this a Junior runtime block. Use the message, connected account, upstream target, grant requirements, accepted-permissions, and SSO fields to explain the GitHub denial. |
|
|
16
|
+
| 403 without `permission_denied` where `source: "upstream"` | Junior may have rejected an unsupported route before contacting GitHub. | Read the response body. Follow any required-tool instruction; do not ask for GitHub permissions unless the failure is confirmed upstream. |
|
|
17
|
+
| `gh auth status` shows `Token scopes: none` | Expected for GitHub App user-to-server tokens. | Do not treat this as read-only proof. Use the failed command, `permission_denied.acceptedPermissions`, and GitHub App permissions instead. |
|
|
18
|
+
| `github_createPullRequest` returns upstream 401/403 | The App installation or target repository does not permit the operation. | Use the structured upstream denial to verify installation scope and accepted permissions; do not request user OAuth for this bot-owned operation. |
|
|
19
|
+
| `github_createPullRequest` returns 422 for `head` | The head branch was not pushed or the explicit head ref is wrong. | Push the branch, then retry with explicit `repo`, `head`, and `base` values. |
|
|
20
|
+
| `github_createPullRequest` fails with 422 validation on `base` | The `base` branch does not exist in the target repo. | Resolve the default branch with `gh repo view owner/repo --json defaultBranchRef --jq .defaultBranchRef.name`, then retry with that value as `base`. |
|
|
21
|
+
| `git blame`, long log history, or old commits are missing after clone | Repo was cloned shallow by design. | Fetch the required ref and deepen it incrementally; use `--unshallow` only when bounded deepening is insufficient. |
|
|
22
|
+
| Rebase, merge-base, or `origin/BASE...HEAD` comparison fails or gives odd ancestry | Required ancestry or the remote-tracking base ref is absent from the shallow clone. | Fetch a bounded depth into `BASE:refs/remotes/origin/BASE`, deepen that base ref until the merge base exists, and compare or rebase against `origin/BASE`. Never force-push around incomplete history. |
|
|
23
|
+
| Tests fail because dependencies or executables are missing | Repository dependencies were not installed. | Detect the lockfile and run the repo-native frozen/immutable install. Do not rewrite the lockfile unless dependency changes are part of the task. |
|
|
24
|
+
| Frozen/immutable dependency install fails | Lockfile drift, unavailable registry, incompatible runtime, or environment issue. | Report the exact install failure. Do not fall back to a lockfile-updating install unless the requested work intentionally changes dependencies. |
|
|
25
|
+
| `sandbox setup failed (dnf install gh failed ...)` | `gh` package not available from the plugin runtime dependency bootstrap. | Report the plugin runtime bootstrap failure; do not try to repair package installation from the skill workflow. |
|
|
23
26
|
|
|
24
27
|
## Retry guidance
|
|
25
28
|
|