@mnaimfaizy/agent-kit 0.0.0-stage → 1.0.0-beta.1
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/README.md +21 -2
- package/bin/agent-kit.mjs +13 -0
- package/package.json +29 -4
- package/src/callers.mjs +204 -0
- package/src/checks/claude-app.mjs +55 -0
- package/src/checks/kit-owned-trees.mjs +78 -0
- package/src/checks/labels.mjs +100 -0
- package/src/checks/pins.mjs +76 -0
- package/src/checks/result.mjs +74 -0
- package/src/checks/rulesets.mjs +346 -0
- package/src/checks/secrets-and-variables.mjs +252 -0
- package/src/cli.mjs +229 -0
- package/src/doctor.mjs +405 -0
- package/src/exec.mjs +64 -0
- package/src/github.mjs +88 -0
- package/src/init.mjs +627 -0
- package/src/kit-owned-paths.mjs +48 -0
- package/src/kit-tag.mjs +257 -0
- package/src/local-tree.mjs +240 -0
- package/src/local-writes.mjs +307 -0
- package/src/prompt.mjs +42 -0
- package/src/safe-paths.mjs +68 -0
- package/src/tags.mjs +55 -0
- package/src/templates.mjs +133 -0
- package/src/upgrade.mjs +288 -0
- package/src/workflow-call.mjs +44 -0
- package/src/yaml-subset.mjs +118 -0
package/src/github.mjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Read-only GitHub API calls through the adopter's own `gh` login. The CLI
|
|
2
|
+
// never changes GitHub settings: it only reads, and prints `gh` commands for
|
|
3
|
+
// the adopter to run.
|
|
4
|
+
|
|
5
|
+
import { REPO_PATTERN as REPO } from "./checks/result.mjs";
|
|
6
|
+
import { firstLine } from "./exec.mjs";
|
|
7
|
+
|
|
8
|
+
const HOST = /^[A-Za-z0-9.-]+(?::\d+)?$/;
|
|
9
|
+
|
|
10
|
+
export class GhError extends Error {
|
|
11
|
+
constructor(message, { status } = {}) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.httpStatus = status ?? null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function fail(r, what) {
|
|
18
|
+
const text = `${r.stderr}\n${r.stdout}`;
|
|
19
|
+
const m = /HTTP (\d{3})/.exec(text);
|
|
20
|
+
return new GhError(`${what}: ${firstLine(r.stderr) || firstLine(r.stdout) || "gh failed"}`, {
|
|
21
|
+
status: m ? Number(m[1]) : null,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function checkRepoName(repo) {
|
|
26
|
+
if (!REPO.test(repo)) throw new GhError(`not a GitHub repository name: ${JSON.stringify(repo)}`);
|
|
27
|
+
return repo;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {import("./exec.mjs").Runner} runner
|
|
32
|
+
* @param {{ cwd?: string, hostname?: string | null }} [opts] hostname: a GitHub
|
|
33
|
+
* Enterprise Server host; gh api then targets it with --hostname.
|
|
34
|
+
*/
|
|
35
|
+
export function createGitHub(runner, { cwd, hostname = null } = {}) {
|
|
36
|
+
if (hostname !== null && !HOST.test(hostname)) {
|
|
37
|
+
throw new GhError(`not a host name: ${JSON.stringify(hostname)}`);
|
|
38
|
+
}
|
|
39
|
+
const gh = (args) => runner("gh", args, { cwd });
|
|
40
|
+
const host = hostname && hostname !== "github.com" ? ["--hostname", hostname] : [];
|
|
41
|
+
|
|
42
|
+
/** GET an endpoint and parse its JSON. */
|
|
43
|
+
function getJson(endpoint) {
|
|
44
|
+
const r = gh(["api", ...host, "--method", "GET", endpoint]);
|
|
45
|
+
if (r.status !== 0) throw fail(r, `gh api ${endpoint}`);
|
|
46
|
+
return JSON.parse(r.stdout);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** GET every page of an endpoint and return one line per `jq` result. */
|
|
50
|
+
function getLines(endpoint, jq) {
|
|
51
|
+
const r = gh(["api", ...host, "--method", "GET", "--paginate", endpoint, "--jq", jq]);
|
|
52
|
+
if (r.status !== 0) throw fail(r, `gh api ${endpoint}`);
|
|
53
|
+
return r.stdout.split(/\r?\n/).filter(Boolean);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The repository doctor checks, and whether this login is an admin on it. */
|
|
57
|
+
function repoInfo(repo) {
|
|
58
|
+
const args = [
|
|
59
|
+
"repo",
|
|
60
|
+
"view",
|
|
61
|
+
"--json",
|
|
62
|
+
"nameWithOwner,isInOrganization,viewerPermission,defaultBranchRef,url",
|
|
63
|
+
];
|
|
64
|
+
if (repo) args.splice(2, 0, checkRepoName(repo));
|
|
65
|
+
const r = gh(args);
|
|
66
|
+
if (r.status !== 0) throw fail(r, "gh repo view");
|
|
67
|
+
const data = JSON.parse(r.stdout);
|
|
68
|
+
// The host the repository lives on: github.com, or a GitHub Enterprise Server.
|
|
69
|
+
let hostName = "github.com";
|
|
70
|
+
try {
|
|
71
|
+
if (data.url) hostName = new URL(data.url).host.toLowerCase();
|
|
72
|
+
} catch {
|
|
73
|
+
hostName = "github.com";
|
|
74
|
+
}
|
|
75
|
+
if (!HOST.test(hostName))
|
|
76
|
+
throw new GhError(`unexpected repository URL ${JSON.stringify(data.url)}`);
|
|
77
|
+
return {
|
|
78
|
+
host: hostName,
|
|
79
|
+
repo: checkRepoName(data.nameWithOwner),
|
|
80
|
+
owner: data.nameWithOwner.split("/")[0],
|
|
81
|
+
ownerType: data.isInOrganization ? "Organization" : "User",
|
|
82
|
+
admin: data.viewerPermission === "ADMIN",
|
|
83
|
+
defaultBranch: data.defaultBranchRef?.name ?? "main",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { getJson, getLines, repoInfo };
|
|
88
|
+
}
|