jj-octo 0.2.3 → 0.3.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/README.md +8 -0
- package/dist/jj-octo.js +78 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,14 @@ bun update --global --latest jj-octo
|
|
|
56
56
|
|
|
57
57
|
It uses only GitHub's REST API, so that it works in a [Claude Code](https://claude.com/claude-code) cloud session. There, GitHub is reached through a proxy that allows REST calls for the session's repository and blocks GraphQL, which `gh pr` depends on.
|
|
58
58
|
|
|
59
|
+
Where git reaches github.com through a proxy that adds the credentials itself, as in a Claude Code cloud session that keeps the token outside the sandbox, have `jj-octo` use that proxy too:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
jj config set --repo jj-octo.github-auth git-proxy
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`jj-octo` then sends its requests through the `http.proxy` that git uses for `https://github.com`, trusts the certificate authorities in git's `http.sslCAInfo` for it, and sends a placeholder token that the proxy replaces. It reads git's settings on each run, so it follows a proxy that moves to another port. `token`, the default, sends your own token.
|
|
66
|
+
|
|
59
67
|
## Development
|
|
60
68
|
|
|
61
69
|
```
|
package/dist/jj-octo.js
CHANGED
|
@@ -18112,7 +18112,7 @@ var layer14 = /* @__PURE__ */ layerMergedContext(/* @__PURE__ */ succeed6(fetch)
|
|
|
18112
18112
|
// package.json
|
|
18113
18113
|
var package_default = {
|
|
18114
18114
|
name: "jj-octo",
|
|
18115
|
-
version: "0.
|
|
18115
|
+
version: "0.3.0",
|
|
18116
18116
|
description: "A jj subcommand for working with GitHub that supports stacking",
|
|
18117
18117
|
license: "MIT",
|
|
18118
18118
|
repository: {
|
|
@@ -18382,6 +18382,18 @@ var colocate = gen2(function* () {
|
|
|
18382
18382
|
const root = yield* resolve(yield* git.read(["rev-parse", "--show-toplevel"]));
|
|
18383
18383
|
const jjRoot = yield* jj.read(["root"]).pipe(flatMap4(resolve), orElseSucceed2(() => ""));
|
|
18384
18384
|
if (jjRoot !== root) {
|
|
18385
|
+
const [gitDirectory, commonDirectory] = (yield* git.read([
|
|
18386
|
+
"rev-parse",
|
|
18387
|
+
"--path-format=absolute",
|
|
18388
|
+
"--git-dir",
|
|
18389
|
+
"--git-common-dir"
|
|
18390
|
+
])).split(`
|
|
18391
|
+
`);
|
|
18392
|
+
if (gitDirectory !== commonDirectory) {
|
|
18393
|
+
yield* new GitFailed({
|
|
18394
|
+
message: "this is a git worktree, where jj would make a second repository; run `jj workspace add` in the main checkout instead"
|
|
18395
|
+
});
|
|
18396
|
+
}
|
|
18385
18397
|
yield* jj.run(["git", "init", "--colocate", root]);
|
|
18386
18398
|
}
|
|
18387
18399
|
});
|
|
@@ -18481,24 +18493,21 @@ var MergeRequest = Struct({
|
|
|
18481
18493
|
});
|
|
18482
18494
|
var StartedMerge = responseOf()(MergeRequest);
|
|
18483
18495
|
var MergeResult = responseOf()(MergeRequest);
|
|
18484
|
-
var
|
|
18485
|
-
const fromEnvironment = yield* option2(Redacted2("GH_TOKEN").pipe(orElse(() => Redacted2("GITHUB_TOKEN"))));
|
|
18486
|
-
if (isSome2(fromEnvironment)) {
|
|
18487
|
-
return fromEnvironment.value;
|
|
18488
|
-
}
|
|
18489
|
-
const spawner = yield* ChildProcessSpawner;
|
|
18490
|
-
const stored = (yield* spawner.string(make14("gh", ["auth", "token"]))).trim();
|
|
18491
|
-
return stored === "" ? yield* fail6("no token") : make19(stored);
|
|
18492
|
-
}).pipe(mapError2(() => new GitHubFailed({ message: "no GitHub token: set GH_TOKEN, or run `gh auth login`" })));
|
|
18493
|
-
var GitHubLive = (repository) => {
|
|
18496
|
+
var GitHubLive = (repository, connection) => {
|
|
18494
18497
|
const repo = (path) => `/repos/${repository.owner}/${repository.name}${path}`;
|
|
18495
18498
|
return effect(GitHub, gen2(function* () {
|
|
18496
|
-
const
|
|
18497
|
-
|
|
18499
|
+
const requestInit = match(connection.proxy, {
|
|
18500
|
+
onNone: () => ({}),
|
|
18501
|
+
onSome: ({ ca, url }) => match(ca, {
|
|
18502
|
+
onNone: () => ({ proxy: url }),
|
|
18503
|
+
onSome: (certificates) => ({ proxy: url, tls: { ca: certificates } })
|
|
18504
|
+
})
|
|
18505
|
+
});
|
|
18506
|
+
const client = (yield* HttpClient).pipe(mapRequest((request) => request.pipe(prependUrl("https://api.github.com"), acceptJson, bearerToken(connection.token), setHeaders({
|
|
18498
18507
|
"user-agent": "jj-octo",
|
|
18499
18508
|
"x-github-api-version": "2022-11-28"
|
|
18500
18509
|
}))));
|
|
18501
|
-
const send = (request) => client.execute(request).pipe(flatMap4((response) => response.status < 400 ? succeed6(response) : response.text.pipe(orElseSucceed2(() => ""), flatMap4((text) => fail6(new GitHubFailed({
|
|
18510
|
+
const send = (request) => client.execute(request).pipe(provideService2(RequestInit, requestInit), flatMap4((response) => response.status < 400 ? succeed6(response) : response.text.pipe(orElseSucceed2(() => ""), flatMap4((text) => fail6(new GitHubFailed({
|
|
18502
18511
|
message: `${request.method} ${request.url} returned ${response.status}: ${text}`
|
|
18503
18512
|
}))))), catchTag2("HttpClientError", (error) => fail6(new GitHubFailed({ message: error.message }))));
|
|
18504
18513
|
const json = (schema) => (request) => send(request).pipe(flatMap4(schemaBodyJson(schema)), catchTags2({
|
|
@@ -18555,6 +18564,60 @@ var GitHubLive = (repository) => {
|
|
|
18555
18564
|
}));
|
|
18556
18565
|
};
|
|
18557
18566
|
|
|
18567
|
+
// src/clients/github/connection.ts
|
|
18568
|
+
var authKey = "jj-octo.github-auth";
|
|
18569
|
+
var ownToken = gen2(function* () {
|
|
18570
|
+
const fromEnvironment = yield* option2(Redacted2("GH_TOKEN").pipe(orElse(() => Redacted2("GITHUB_TOKEN"))));
|
|
18571
|
+
if (isSome2(fromEnvironment)) {
|
|
18572
|
+
return fromEnvironment.value;
|
|
18573
|
+
}
|
|
18574
|
+
const spawner = yield* ChildProcessSpawner;
|
|
18575
|
+
const stored = (yield* spawner.string(make14("gh", ["auth", "token"]))).trim();
|
|
18576
|
+
return stored === "" ? yield* fail6("no token") : make19(stored);
|
|
18577
|
+
}).pipe(mapError2(() => new GitHubFailed({ message: "no GitHub token: set GH_TOKEN, or run `gh auth login`" })));
|
|
18578
|
+
var gitSetting = (name) => gen2(function* () {
|
|
18579
|
+
const git = yield* Git;
|
|
18580
|
+
const value = (yield* git.read(["config", "--get-urlmatch", name, "https://github.com"]).pipe(orElseSucceed2(() => ""))).trim();
|
|
18581
|
+
return value === "" ? none2() : some2(value);
|
|
18582
|
+
});
|
|
18583
|
+
var gitProxy = gen2(function* () {
|
|
18584
|
+
const fs = yield* FileSystem;
|
|
18585
|
+
const url = yield* gitSetting("http.proxy");
|
|
18586
|
+
if (isNone2(url)) {
|
|
18587
|
+
return yield* new GitHubFailed({
|
|
18588
|
+
message: `${authKey} is git-proxy, but git has no http.proxy for https://github.com`
|
|
18589
|
+
});
|
|
18590
|
+
}
|
|
18591
|
+
const caFile = yield* gitSetting("http.sslCAInfo");
|
|
18592
|
+
const ca = isNone2(caFile) ? none2() : some2(yield* fs.readFileString(caFile.value).pipe(mapError2((error) => new GitHubFailed({
|
|
18593
|
+
message: `can't read git's http.sslCAInfo ${caFile.value}: ${error.message}`
|
|
18594
|
+
}))));
|
|
18595
|
+
const connection = {
|
|
18596
|
+
proxy: some2({ ca, url: url.value }),
|
|
18597
|
+
token: make19("proxy-injected")
|
|
18598
|
+
};
|
|
18599
|
+
return connection;
|
|
18600
|
+
});
|
|
18601
|
+
var connection = gen2(function* () {
|
|
18602
|
+
const jj = yield* Jj;
|
|
18603
|
+
const auth = (yield* jj.read(["config", "get", authKey]).pipe(orElseSucceed2(() => ""))).trim();
|
|
18604
|
+
switch (auth) {
|
|
18605
|
+
case "":
|
|
18606
|
+
case "token": {
|
|
18607
|
+
const own = { proxy: none2(), token: yield* ownToken };
|
|
18608
|
+
return own;
|
|
18609
|
+
}
|
|
18610
|
+
case "git-proxy": {
|
|
18611
|
+
return yield* gitProxy;
|
|
18612
|
+
}
|
|
18613
|
+
default: {
|
|
18614
|
+
return yield* new GitHubFailed({
|
|
18615
|
+
message: `${authKey} is ${JSON.stringify(auth)}; set it to token or git-proxy`
|
|
18616
|
+
});
|
|
18617
|
+
}
|
|
18618
|
+
}
|
|
18619
|
+
});
|
|
18620
|
+
|
|
18558
18621
|
// src/clients/github/repository.ts
|
|
18559
18622
|
var repositoryFromUrl = (url) => {
|
|
18560
18623
|
const match = /github\.com[:/](?<owner>[^/]+)\/(?<name>[^/]+?)(?:\.git)?\/?$/u.exec(url.trim());
|
|
@@ -18573,7 +18636,7 @@ var GitHubFromOrigin = unwrap(gen2(function* () {
|
|
|
18573
18636
|
if (isNone2(repository)) {
|
|
18574
18637
|
return yield* new GitHubFailed({ message: "the `origin` remote isn't a GitHub repository" });
|
|
18575
18638
|
}
|
|
18576
|
-
return GitHubLive(repository.value);
|
|
18639
|
+
return GitHubLive(repository.value, yield* connection);
|
|
18577
18640
|
}));
|
|
18578
18641
|
|
|
18579
18642
|
// src/cli/gh/log.ts
|