co-maintainer 0.4.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/LICENSE +21 -0
- package/README.md +105 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +9 -0
- package/dist/mod.d.ts +4 -0
- package/dist/mod.js +2 -0
- package/dist/package.json +54 -0
- package/dist/src/ai/batch.d.ts +16 -0
- package/dist/src/ai/batch.js +117 -0
- package/dist/src/ai/fake.d.ts +7 -0
- package/dist/src/ai/fake.js +40 -0
- package/dist/src/ai/hetzner.d.ts +16 -0
- package/dist/src/ai/hetzner.js +69 -0
- package/dist/src/ai/mermaid.d.ts +27 -0
- package/dist/src/ai/mermaid.js +457 -0
- package/dist/src/ai/mermaid_loop.d.ts +12 -0
- package/dist/src/ai/mermaid_loop.js +100 -0
- package/dist/src/ai/openrouter.d.ts +9 -0
- package/dist/src/ai/openrouter.js +29 -0
- package/dist/src/ai/provider.d.ts +4 -0
- package/dist/src/ai/provider.js +63 -0
- package/dist/src/cli/args.d.ts +5 -0
- package/dist/src/cli/args.js +252 -0
- package/dist/src/cli/commands/probe.d.ts +2 -0
- package/dist/src/cli/commands/probe.js +122 -0
- package/dist/src/cli/commands/review.d.ts +3 -0
- package/dist/src/cli/commands/review.js +84 -0
- package/dist/src/cli/commands/serve.d.ts +18 -0
- package/dist/src/cli/commands/serve.js +183 -0
- package/dist/src/cli/commands/set.d.ts +7 -0
- package/dist/src/cli/commands/set.js +171 -0
- package/dist/src/cli/main.d.ts +1 -0
- package/dist/src/cli/main.js +27 -0
- package/dist/src/cli/prompt.d.ts +4 -0
- package/dist/src/cli/prompt.js +26 -0
- package/dist/src/cli/review_args.d.ts +28 -0
- package/dist/src/cli/review_args.js +84 -0
- package/dist/src/cli/review_output.d.ts +2 -0
- package/dist/src/cli/review_output.js +10 -0
- package/dist/src/cli/review_result.d.ts +81 -0
- package/dist/src/cli/review_result.js +281 -0
- package/dist/src/config.d.ts +108 -0
- package/dist/src/config.js +138 -0
- package/dist/src/git/default_branch.d.ts +5 -0
- package/dist/src/git/default_branch.js +22 -0
- package/dist/src/github/app.d.ts +43 -0
- package/dist/src/github/app.js +120 -0
- package/dist/src/github/client.d.ts +17 -0
- package/dist/src/github/client.js +66 -0
- package/dist/src/github/collect.d.ts +7 -0
- package/dist/src/github/collect.js +368 -0
- package/dist/src/github/gh.d.ts +8 -0
- package/dist/src/github/gh.js +63 -0
- package/dist/src/github/jwt.d.ts +12 -0
- package/dist/src/github/jwt.js +84 -0
- package/dist/src/github/oauth.d.ts +9 -0
- package/dist/src/github/oauth.js +51 -0
- package/dist/src/github/pat.d.ts +10 -0
- package/dist/src/github/pat.js +60 -0
- package/dist/src/knowledge/facts.d.ts +3 -0
- package/dist/src/knowledge/facts.js +325 -0
- package/dist/src/knowledge/guide.d.ts +6 -0
- package/dist/src/knowledge/guide.js +82 -0
- package/dist/src/knowledge/probe.d.ts +12 -0
- package/dist/src/knowledge/probe.js +144 -0
- package/dist/src/knowledge/sections.d.ts +2 -0
- package/dist/src/knowledge/sections.js +13 -0
- package/dist/src/knowledge/skill.d.ts +10 -0
- package/dist/src/knowledge/skill.js +106 -0
- package/dist/src/knowledge/synthesis.d.ts +7 -0
- package/dist/src/knowledge/synthesis.js +315 -0
- package/dist/src/knowledge/types.d.ts +49 -0
- package/dist/src/knowledge/types.js +1 -0
- package/dist/src/knowledge/validate.d.ts +6 -0
- package/dist/src/knowledge/validate.js +134 -0
- package/dist/src/local/carry_over_store.d.ts +18 -0
- package/dist/src/local/carry_over_store.js +40 -0
- package/dist/src/local/codegraph_exclude.d.ts +3 -0
- package/dist/src/local/codegraph_exclude.js +26 -0
- package/dist/src/local/codegraph_prepare.d.ts +17 -0
- package/dist/src/local/codegraph_prepare.js +51 -0
- package/dist/src/local/git_ops.d.ts +12 -0
- package/dist/src/local/git_ops.js +98 -0
- package/dist/src/local/git_parse.d.ts +27 -0
- package/dist/src/local/git_parse.js +131 -0
- package/dist/src/local/git_revision.d.ts +15 -0
- package/dist/src/local/git_revision.js +141 -0
- package/dist/src/local/git_untracked.d.ts +21 -0
- package/dist/src/local/git_untracked.js +79 -0
- package/dist/src/local/review_local.d.ts +4 -0
- package/dist/src/local/review_local.js +273 -0
- package/dist/src/local/review_lock.d.ts +7 -0
- package/dist/src/local/review_lock.js +45 -0
- package/dist/src/pr/checkout.d.ts +25 -0
- package/dist/src/pr/checkout.js +136 -0
- package/dist/src/pr/codegraph_tool_args.d.ts +8 -0
- package/dist/src/pr/codegraph_tool_args.js +34 -0
- package/dist/src/pr/codegraph_tools.d.ts +15 -0
- package/dist/src/pr/codegraph_tools.js +408 -0
- package/dist/src/pr/diff_summary.d.ts +6 -0
- package/dist/src/pr/diff_summary.js +52 -0
- package/dist/src/pr/findings.d.ts +14 -0
- package/dist/src/pr/findings.js +94 -0
- package/dist/src/pr/github_revision.d.ts +4 -0
- package/dist/src/pr/github_revision.js +39 -0
- package/dist/src/pr/hunks.d.ts +18 -0
- package/dist/src/pr/hunks.js +73 -0
- package/dist/src/pr/reviewer.d.ts +40 -0
- package/dist/src/pr/reviewer.js +582 -0
- package/dist/src/pr/rounds.d.ts +17 -0
- package/dist/src/pr/rounds.js +43 -0
- package/dist/src/pr/scope.d.ts +35 -0
- package/dist/src/pr/scope.js +84 -0
- package/dist/src/pr/snapshot.d.ts +11 -0
- package/dist/src/pr/snapshot.js +1 -0
- package/dist/src/pr/suggestion.d.ts +17 -0
- package/dist/src/pr/suggestion.js +70 -0
- package/dist/src/remote/client.d.ts +4 -0
- package/dist/src/remote/client.js +199 -0
- package/dist/src/remote/client_tools.d.ts +13 -0
- package/dist/src/remote/client_tools.js +30 -0
- package/dist/src/remote/fixtures.d.ts +1 -0
- package/dist/src/remote/fixtures.js +30 -0
- package/dist/src/remote/revision_from_submit.d.ts +2 -0
- package/dist/src/remote/revision_from_submit.js +26 -0
- package/dist/src/remote/schema.d.ts +14 -0
- package/dist/src/remote/schema.js +30 -0
- package/dist/src/remote/server/body.d.ts +18 -0
- package/dist/src/remote/server/body.js +73 -0
- package/dist/src/remote/server/routes.d.ts +1 -0
- package/dist/src/remote/server/routes.js +150 -0
- package/dist/src/remote/server/sessions.d.ts +16 -0
- package/dist/src/remote/server/sessions.js +48 -0
- package/dist/src/remote/server/sync.d.ts +3 -0
- package/dist/src/remote/server/sync.js +90 -0
- package/dist/src/remote/tool_bridge.d.ts +15 -0
- package/dist/src/remote/tool_bridge.js +84 -0
- package/dist/src/remote/validate.d.ts +8 -0
- package/dist/src/remote/validate.js +248 -0
- package/dist/src/review/carry_over.d.ts +63 -0
- package/dist/src/review/carry_over.js +372 -0
- package/dist/src/review/engine.d.ts +13 -0
- package/dist/src/review/engine.js +4 -0
- package/dist/src/review/guides.d.ts +12 -0
- package/dist/src/review/guides.js +44 -0
- package/dist/src/review/revision.d.ts +26 -0
- package/dist/src/review/revision.js +57 -0
- package/dist/src/server/api/activity.d.ts +1 -0
- package/dist/src/server/api/activity.js +12 -0
- package/dist/src/server/api/analytics.d.ts +1 -0
- package/dist/src/server/api/analytics.js +9 -0
- package/dist/src/server/api/installations.d.ts +4 -0
- package/dist/src/server/api/installations.js +24 -0
- package/dist/src/server/api/jobs.d.ts +1 -0
- package/dist/src/server/api/jobs.js +86 -0
- package/dist/src/server/api/json_body.d.ts +1 -0
- package/dist/src/server/api/json_body.js +14 -0
- package/dist/src/server/api/remote_tokens.d.ts +1 -0
- package/dist/src/server/api/remote_tokens.js +71 -0
- package/dist/src/server/api/repos.d.ts +4 -0
- package/dist/src/server/api/repos.js +136 -0
- package/dist/src/server/api/settings.d.ts +1 -0
- package/dist/src/server/api/settings.js +210 -0
- package/dist/src/server/app.d.ts +27 -0
- package/dist/src/server/app.js +147 -0
- package/dist/src/server/assets.d.ts +3 -0
- package/dist/src/server/assets.js +21 -0
- package/dist/src/server/auth.d.ts +44 -0
- package/dist/src/server/auth.js +188 -0
- package/dist/src/server/errors.d.ts +8 -0
- package/dist/src/server/errors.js +10 -0
- package/dist/src/server/http.d.ts +8 -0
- package/dist/src/server/http.js +117 -0
- package/dist/src/server/logo.d.ts +1 -0
- package/dist/src/server/logo.js +2 -0
- package/dist/src/server/pages/activity.d.ts +4 -0
- package/dist/src/server/pages/activity.js +200 -0
- package/dist/src/server/pages/add_repo.d.ts +9 -0
- package/dist/src/server/pages/add_repo.js +56 -0
- package/dist/src/server/pages/analytics.d.ts +2 -0
- package/dist/src/server/pages/analytics.js +193 -0
- package/dist/src/server/pages/client.d.ts +2 -0
- package/dist/src/server/pages/client.js +2 -0
- package/dist/src/server/pages/home.d.ts +16 -0
- package/dist/src/server/pages/home.js +87 -0
- package/dist/src/server/pages/knowledge.d.ts +2 -0
- package/dist/src/server/pages/knowledge.js +64 -0
- package/dist/src/server/pages/layout.d.ts +32 -0
- package/dist/src/server/pages/layout.js +230 -0
- package/dist/src/server/pages/pr.d.ts +2 -0
- package/dist/src/server/pages/pr.js +109 -0
- package/dist/src/server/pages/repo.d.ts +2 -0
- package/dist/src/server/pages/repo.js +92 -0
- package/dist/src/server/pages/repo_prs.d.ts +2 -0
- package/dist/src/server/pages/repo_prs.js +75 -0
- package/dist/src/server/pages/repo_remote.d.ts +2 -0
- package/dist/src/server/pages/repo_remote.js +38 -0
- package/dist/src/server/pages/repo_settings.d.ts +3 -0
- package/dist/src/server/pages/repo_settings.js +127 -0
- package/dist/src/server/pages/router.d.ts +17 -0
- package/dist/src/server/pages/router.js +312 -0
- package/dist/src/server/pages/settings.d.ts +2 -0
- package/dist/src/server/pages/settings.js +337 -0
- package/dist/src/server/pages/setup.d.ts +5 -0
- package/dist/src/server/pages/setup.js +38 -0
- package/dist/src/server/pages/styles.d.ts +2 -0
- package/dist/src/server/pages/styles.js +2 -0
- package/dist/src/server/webhook/index.d.ts +1 -0
- package/dist/src/server/webhook/index.js +64 -0
- package/dist/src/server/webhook/signature.d.ts +7 -0
- package/dist/src/server/webhook/signature.js +41 -0
- package/dist/src/services/credentials.d.ts +19 -0
- package/dist/src/services/credentials.js +146 -0
- package/dist/src/services/dashboard.d.ts +165 -0
- package/dist/src/services/dashboard.js +200 -0
- package/dist/src/services/drift.d.ts +13 -0
- package/dist/src/services/drift.js +76 -0
- package/dist/src/services/jobs.d.ts +34 -0
- package/dist/src/services/jobs.js +222 -0
- package/dist/src/services/remote_review.d.ts +10 -0
- package/dist/src/services/remote_review.js +274 -0
- package/dist/src/services/remote_review_abort.d.ts +3 -0
- package/dist/src/services/remote_review_abort.js +11 -0
- package/dist/src/services/remote_token_jobs.d.ts +1 -0
- package/dist/src/services/remote_token_jobs.js +20 -0
- package/dist/src/services/remote_tokens.d.ts +13 -0
- package/dist/src/services/remote_tokens.js +57 -0
- package/dist/src/services/replies.d.ts +7 -0
- package/dist/src/services/replies.js +248 -0
- package/dist/src/services/review.d.ts +35 -0
- package/dist/src/services/review.js +671 -0
- package/dist/src/services/setup.d.ts +29 -0
- package/dist/src/services/setup.js +364 -0
- package/dist/src/services/webhook.d.ts +22 -0
- package/dist/src/services/webhook.js +401 -0
- package/dist/src/store/app_db.d.ts +10 -0
- package/dist/src/store/app_db.js +85 -0
- package/dist/src/store/cache_db.d.ts +4 -0
- package/dist/src/store/cache_db.js +63 -0
- package/dist/src/store/deliveries.d.ts +12 -0
- package/dist/src/store/deliveries.js +23 -0
- package/dist/src/store/drift.d.ts +4 -0
- package/dist/src/store/drift.js +22 -0
- package/dist/src/store/findings.d.ts +31 -0
- package/dist/src/store/findings.js +64 -0
- package/dist/src/store/installations.d.ts +9 -0
- package/dist/src/store/installations.js +35 -0
- package/dist/src/store/job_logs.d.ts +5 -0
- package/dist/src/store/job_logs.js +17 -0
- package/dist/src/store/jobs.d.ts +27 -0
- package/dist/src/store/jobs.js +86 -0
- package/dist/src/store/migrations.d.ts +5 -0
- package/dist/src/store/migrations.js +258 -0
- package/dist/src/store/remote_review_inputs.d.ts +11 -0
- package/dist/src/store/remote_review_inputs.js +25 -0
- package/dist/src/store/remote_tokens.d.ts +10 -0
- package/dist/src/store/remote_tokens.js +45 -0
- package/dist/src/store/replies.d.ts +24 -0
- package/dist/src/store/replies.js +79 -0
- package/dist/src/store/repos.d.ts +11 -0
- package/dist/src/store/repos.js +59 -0
- package/dist/src/store/reviews.d.ts +86 -0
- package/dist/src/store/reviews.js +220 -0
- package/dist/src/store/rows.d.ts +179 -0
- package/dist/src/store/rows.js +4 -0
- package/dist/src/store/sessions.d.ts +8 -0
- package/dist/src/store/sessions.js +34 -0
- package/dist/src/store/skill_state.d.ts +3 -0
- package/dist/src/store/skill_state.js +24 -0
- package/dist/src/store/sqlite.d.ts +39 -0
- package/dist/src/store/sqlite.js +77 -0
- package/dist/src/store/subjects.d.ts +15 -0
- package/dist/src/store/subjects.js +78 -0
- package/dist/src/tools/codegraph.d.ts +58 -0
- package/dist/src/tools/codegraph.js +165 -0
- package/dist/src/tools/codegraph_exec.d.ts +13 -0
- package/dist/src/tools/codegraph_exec.js +66 -0
- package/dist/src/types.d.ts +89 -0
- package/dist/src/types.js +1 -0
- package/dist/src/util/atomic.d.ts +4 -0
- package/dist/src/util/atomic.js +78 -0
- package/dist/src/util/keyed_lock.d.ts +3 -0
- package/dist/src/util/keyed_lock.js +33 -0
- package/dist/src/util/log.d.ts +11 -0
- package/dist/src/util/log.js +42 -0
- package/dist/src/util/redact.d.ts +5 -0
- package/dist/src/util/redact.js +30 -0
- package/dist/src/util/runtime.d.ts +90 -0
- package/dist/src/util/runtime.js +206 -0
- package/dist/src/util/time.d.ts +9 -0
- package/dist/src/util/time.js +36 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +5 -0
- package/package.json +54 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** `co-maintainer set --token=... --ai=... --low-model=... --high-model=...
|
|
2
|
+
* --auth=... --github-app-id=... --github-app-private-key=... (or
|
|
3
|
+
* --github-app-private-key-file=path) --github-webhook-secret=...` —
|
|
4
|
+
* persists global defaults, including secrets, to config.json so every
|
|
5
|
+
* other command can skip both the flag and the interactive prompt. See
|
|
6
|
+
* docs/md/configuration.md for the tradeoff. */
|
|
7
|
+
export declare function runSet(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { writeUserConfig } from "../../config.js";
|
|
2
|
+
import { readTextFile } from "../../util/runtime.js";
|
|
3
|
+
function die(message) {
|
|
4
|
+
throw new Error(message);
|
|
5
|
+
}
|
|
6
|
+
function text(args, name) {
|
|
7
|
+
return args
|
|
8
|
+
.find((arg) => arg.startsWith(`--${name}=`))
|
|
9
|
+
?.slice(name.length + 3);
|
|
10
|
+
}
|
|
11
|
+
const secretFields = new Set([
|
|
12
|
+
"token",
|
|
13
|
+
"githubPat",
|
|
14
|
+
"githubAppPrivateKey",
|
|
15
|
+
"githubWebhookSecret",
|
|
16
|
+
"githubOAuthClientSecret",
|
|
17
|
+
"remoteToken",
|
|
18
|
+
]);
|
|
19
|
+
/** `co-maintainer set --token=... --ai=... --low-model=... --high-model=...
|
|
20
|
+
* --auth=... --github-app-id=... --github-app-private-key=... (or
|
|
21
|
+
* --github-app-private-key-file=path) --github-webhook-secret=...` —
|
|
22
|
+
* persists global defaults, including secrets, to config.json so every
|
|
23
|
+
* other command can skip both the flag and the interactive prompt. See
|
|
24
|
+
* docs/md/configuration.md for the tradeoff. */
|
|
25
|
+
export async function runSet(args) {
|
|
26
|
+
if (args.includes("--help") || args.includes("-h") || args.length === 0) {
|
|
27
|
+
console.log("Usage: co-maintainer set --token=... --ai=none|openrouter|hetzner --low-model=... --high-model=... --auth=gh|pat --github-pat=...");
|
|
28
|
+
console.log(" --github-app-id=... --github-app-private-key=... | --github-app-private-key-file=path");
|
|
29
|
+
console.log(" --github-webhook-secret=...");
|
|
30
|
+
console.log(" --github-oauth-client-id=... --github-oauth-client-secret=... --github-oauth-allowed-user=...");
|
|
31
|
+
console.log(" --disable-auth=password --enable-auth=github");
|
|
32
|
+
console.log("Writes to the user config file; unset an entry with --unset=name (e.g. --unset=token).");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const known = [
|
|
36
|
+
"token",
|
|
37
|
+
"ai",
|
|
38
|
+
"low-model",
|
|
39
|
+
"high-model",
|
|
40
|
+
"auth",
|
|
41
|
+
"github-pat",
|
|
42
|
+
"github-app-id",
|
|
43
|
+
"github-app-private-key",
|
|
44
|
+
"github-app-private-key-file",
|
|
45
|
+
"github-webhook-secret",
|
|
46
|
+
"github-oauth-client-id",
|
|
47
|
+
"github-oauth-client-secret",
|
|
48
|
+
"github-oauth-allowed-user",
|
|
49
|
+
"disable-auth",
|
|
50
|
+
"enable-auth",
|
|
51
|
+
"remote-host",
|
|
52
|
+
"remote-token",
|
|
53
|
+
"unset",
|
|
54
|
+
];
|
|
55
|
+
for (const arg of args) {
|
|
56
|
+
if (!arg.startsWith("--") ||
|
|
57
|
+
!known.some((name) => arg.startsWith(`--${name}=`))) {
|
|
58
|
+
die(`Unknown option: ${arg}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const ai = text(args, "ai");
|
|
62
|
+
if (ai && !["none", "openrouter", "hetzner"].includes(ai)) {
|
|
63
|
+
die("--ai must be one of: none, openrouter, hetzner");
|
|
64
|
+
}
|
|
65
|
+
const auth = text(args, "auth");
|
|
66
|
+
if (auth && !["gh", "pat"].includes(auth)) {
|
|
67
|
+
die("--auth must be one of: gh, pat");
|
|
68
|
+
}
|
|
69
|
+
if (text(args, "github-app-private-key") &&
|
|
70
|
+
text(args, "github-app-private-key-file")) {
|
|
71
|
+
die("Pass only one of --github-app-private-key or --github-app-private-key-file");
|
|
72
|
+
}
|
|
73
|
+
const fieldByFlag = {
|
|
74
|
+
token: "token",
|
|
75
|
+
ai: "ai",
|
|
76
|
+
"low-model": "lowModel",
|
|
77
|
+
"high-model": "highModel",
|
|
78
|
+
auth: "auth",
|
|
79
|
+
"github-pat": "githubPat",
|
|
80
|
+
"github-app-id": "githubAppId",
|
|
81
|
+
"github-app-private-key": "githubAppPrivateKey",
|
|
82
|
+
"github-webhook-secret": "githubWebhookSecret",
|
|
83
|
+
"github-oauth-client-id": "githubOAuthClientId",
|
|
84
|
+
"github-oauth-client-secret": "githubOAuthClientSecret",
|
|
85
|
+
"github-oauth-allowed-user": "githubOAuthAllowedUser",
|
|
86
|
+
"disable-auth": "passwordAuthDisabled",
|
|
87
|
+
"enable-auth": "githubAuthEnabled",
|
|
88
|
+
"remote-host": "remoteHost",
|
|
89
|
+
"remote-token": "remoteToken",
|
|
90
|
+
};
|
|
91
|
+
const unset = new Set(args
|
|
92
|
+
.filter((arg) => arg.startsWith("--unset="))
|
|
93
|
+
.map((arg) => arg.slice("--unset=".length)));
|
|
94
|
+
const patch = {};
|
|
95
|
+
for (const [flag, field] of Object.entries(fieldByFlag)) {
|
|
96
|
+
if (unset.has(field) || unset.has(flag))
|
|
97
|
+
patch[field] = undefined;
|
|
98
|
+
}
|
|
99
|
+
if (ai)
|
|
100
|
+
patch.ai = ai;
|
|
101
|
+
if (auth)
|
|
102
|
+
patch.auth = auth;
|
|
103
|
+
const lowModel = text(args, "low-model");
|
|
104
|
+
if (lowModel)
|
|
105
|
+
patch.lowModel = lowModel;
|
|
106
|
+
const highModel = text(args, "high-model");
|
|
107
|
+
if (highModel)
|
|
108
|
+
patch.highModel = highModel;
|
|
109
|
+
const token = text(args, "token");
|
|
110
|
+
if (token)
|
|
111
|
+
patch.token = token;
|
|
112
|
+
const githubPat = text(args, "github-pat");
|
|
113
|
+
if (githubPat)
|
|
114
|
+
patch.githubPat = githubPat;
|
|
115
|
+
const githubAppId = text(args, "github-app-id");
|
|
116
|
+
if (githubAppId)
|
|
117
|
+
patch.githubAppId = githubAppId;
|
|
118
|
+
const githubWebhookSecret = text(args, "github-webhook-secret");
|
|
119
|
+
if (githubWebhookSecret)
|
|
120
|
+
patch.githubWebhookSecret = githubWebhookSecret;
|
|
121
|
+
const githubAppPrivateKey = text(args, "github-app-private-key");
|
|
122
|
+
if (githubAppPrivateKey)
|
|
123
|
+
patch.githubAppPrivateKey = githubAppPrivateKey;
|
|
124
|
+
const privateKeyFile = text(args, "github-app-private-key-file");
|
|
125
|
+
if (privateKeyFile) {
|
|
126
|
+
try {
|
|
127
|
+
patch.githubAppPrivateKey = await readTextFile(privateKeyFile);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
die(`Could not read ${privateKeyFile}: ${String(error)}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const oauthClientId = text(args, "github-oauth-client-id");
|
|
134
|
+
if (oauthClientId)
|
|
135
|
+
patch.githubOAuthClientId = oauthClientId;
|
|
136
|
+
const oauthClientSecret = text(args, "github-oauth-client-secret");
|
|
137
|
+
if (oauthClientSecret)
|
|
138
|
+
patch.githubOAuthClientSecret = oauthClientSecret;
|
|
139
|
+
const oauthAllowedUser = text(args, "github-oauth-allowed-user");
|
|
140
|
+
if (oauthAllowedUser)
|
|
141
|
+
patch.githubOAuthAllowedUser = oauthAllowedUser;
|
|
142
|
+
const disableAuth = text(args, "disable-auth");
|
|
143
|
+
if (disableAuth) {
|
|
144
|
+
if (disableAuth !== "password")
|
|
145
|
+
die("--disable-auth only supports: password");
|
|
146
|
+
patch.passwordAuthDisabled = true;
|
|
147
|
+
}
|
|
148
|
+
const enableAuth = text(args, "enable-auth");
|
|
149
|
+
if (enableAuth) {
|
|
150
|
+
if (enableAuth !== "github")
|
|
151
|
+
die("--enable-auth only supports: github");
|
|
152
|
+
patch.githubAuthEnabled = true;
|
|
153
|
+
}
|
|
154
|
+
const remoteHost = text(args, "remote-host");
|
|
155
|
+
if (remoteHost)
|
|
156
|
+
patch.remoteHost = remoteHost;
|
|
157
|
+
const remoteToken = text(args, "remote-token");
|
|
158
|
+
if (remoteToken)
|
|
159
|
+
patch.remoteToken = remoteToken;
|
|
160
|
+
if (Object.keys(patch).length === 0) {
|
|
161
|
+
die("Nothing to set; pass --token=, --ai=, --low-model=, --high-model=, --auth=, --github-pat=, " +
|
|
162
|
+
"--github-app-id=, --github-app-private-key(-file)=, --github-webhook-secret=, " +
|
|
163
|
+
"--github-oauth-client-id=, --github-oauth-client-secret=, --github-oauth-allowed-user=, " +
|
|
164
|
+
"--disable-auth=password, --enable-auth=github, or --unset=name");
|
|
165
|
+
}
|
|
166
|
+
await writeUserConfig(patch);
|
|
167
|
+
const summary = Object.entries(patch).map(([key, value]) => value === undefined
|
|
168
|
+
? `${key} (unset)`
|
|
169
|
+
: `${key}=${secretFields.has(key) ? "•".repeat(8) : value}`);
|
|
170
|
+
console.log(`[set] updated: ${summary.join(", ")}`);
|
|
171
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function run(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** CLI dispatch only. Each branch parses nothing itself beyond `args[0]` and
|
|
2
|
+
* calls straight into a command or a service — see PLAN.md Section 3. */
|
|
3
|
+
import { parseArgs } from "./args.js";
|
|
4
|
+
import { runServe } from "./commands/serve.js";
|
|
5
|
+
import { runSet } from "./commands/set.js";
|
|
6
|
+
import { runProbe } from "./commands/probe.js";
|
|
7
|
+
import { runReviewFromCli } from "./commands/review.js";
|
|
8
|
+
import { runInitOrRemake } from "../services/setup.js";
|
|
9
|
+
export async function run(args) {
|
|
10
|
+
if (args[0] === "set") {
|
|
11
|
+
await runSet(args.slice(1));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (args[0] === "serve") {
|
|
15
|
+
await runServe(args.slice(1));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (args[0] === "review") {
|
|
19
|
+
await runReviewFromCli(args.slice(1));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const options = await parseArgs(args);
|
|
23
|
+
if (options.command === "probe")
|
|
24
|
+
await runProbe(options);
|
|
25
|
+
else
|
|
26
|
+
await runInitOrRemake(options);
|
|
27
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Free-text question; empty input yields the fallback (or ""). */
|
|
2
|
+
export declare function askLine(label: string, fallback?: string): Promise<string>;
|
|
3
|
+
/** Yes/no question; anything but `y`/`yes` is a no. */
|
|
4
|
+
export declare function askConfirm(question: string): Promise<boolean>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Interactive prompts over `node:readline/promises`.
|
|
2
|
+
*
|
|
3
|
+
* Every prompt opens and closes its own interface: co-maintainer rarely asks
|
|
4
|
+
* more than a couple of questions, and an interface left open keeps stdin
|
|
5
|
+
* referenced, which would hang a non-interactive pipeline. */
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
7
|
+
async function ask(question) {
|
|
8
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
9
|
+
try {
|
|
10
|
+
return (await rl.question(question)).trim();
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
rl.close();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Free-text question; empty input yields the fallback (or ""). */
|
|
17
|
+
export async function askLine(label, fallback) {
|
|
18
|
+
const suffix = fallback ? ` [${fallback}]` : "";
|
|
19
|
+
const answer = await ask(`${label}${suffix}:`);
|
|
20
|
+
return answer || fallback || "";
|
|
21
|
+
}
|
|
22
|
+
/** Yes/no question; anything but `y`/`yes` is a no. */
|
|
23
|
+
export async function askConfirm(question) {
|
|
24
|
+
const answer = (await ask(`${question} [y/N]`)).toLowerCase();
|
|
25
|
+
return answer === "y" || answer === "yes";
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Options } from "../types.ts";
|
|
2
|
+
export type ReviewMode = "local" | "remote" | "pr";
|
|
3
|
+
type ReviewFlags = {
|
|
4
|
+
json: boolean;
|
|
5
|
+
remote: boolean;
|
|
6
|
+
disableCodegraph: boolean;
|
|
7
|
+
allowToolInstall: boolean;
|
|
8
|
+
fresh: boolean;
|
|
9
|
+
toBranch?: string;
|
|
10
|
+
branch?: string;
|
|
11
|
+
repoOverride?: string;
|
|
12
|
+
remakeBeforeReview: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type ReviewCliArgs = ({
|
|
15
|
+
mode: "pr";
|
|
16
|
+
options: Options;
|
|
17
|
+
} & ReviewFlags) | ({
|
|
18
|
+
mode: "local";
|
|
19
|
+
rawArgs: string[];
|
|
20
|
+
} & ReviewFlags) | ({
|
|
21
|
+
mode: "remote";
|
|
22
|
+
rawArgs: string[];
|
|
23
|
+
} & ReviewFlags);
|
|
24
|
+
/** Strip local-only flags before `parseArgs` for PR-style options. */
|
|
25
|
+
export declare function filterReviewConfigArgs(raw: string[]): string[];
|
|
26
|
+
/** Parses `co-maintainer review` after the `review` token (plan §8.1). */
|
|
27
|
+
export declare function parseReviewArgs(args: string[]): Promise<ReviewCliArgs>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { parseArgs } from "./args.js";
|
|
2
|
+
function die(message) {
|
|
3
|
+
throw new Error(message);
|
|
4
|
+
}
|
|
5
|
+
function reviewFlags(rest) {
|
|
6
|
+
const text = (name) => rest.find((item) => item.startsWith(`--${name}=`))?.slice(name.length + 3);
|
|
7
|
+
for (const arg of rest) {
|
|
8
|
+
if (arg === "--codegraph") {
|
|
9
|
+
die("Unknown option: --codegraph");
|
|
10
|
+
}
|
|
11
|
+
if (arg === "--remote" &&
|
|
12
|
+
rest.some((r) => r === "--remake-before-review")) {
|
|
13
|
+
die("--remake-before-review cannot be used with --remote");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
json: rest.includes("--json"),
|
|
18
|
+
remote: rest.includes("--remote"),
|
|
19
|
+
disableCodegraph: rest.includes("--disable-codegraph"),
|
|
20
|
+
allowToolInstall: rest.includes("--allow-tool-install"),
|
|
21
|
+
fresh: rest.includes("--fresh"),
|
|
22
|
+
toBranch: text("to-branch"),
|
|
23
|
+
branch: text("branch"),
|
|
24
|
+
repoOverride: text("repo"),
|
|
25
|
+
remakeBeforeReview: rest.includes("--remake-before-review"),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const LOCAL_ONLY_FLAGS = new Set([
|
|
29
|
+
"--json",
|
|
30
|
+
"--remote",
|
|
31
|
+
"--disable-codegraph",
|
|
32
|
+
"--allow-tool-install",
|
|
33
|
+
"--fresh",
|
|
34
|
+
"--remake-before-review",
|
|
35
|
+
]);
|
|
36
|
+
/** Strip local-only flags before `parseArgs` for PR-style options. */
|
|
37
|
+
export function filterReviewConfigArgs(raw) {
|
|
38
|
+
return raw.filter((arg) => {
|
|
39
|
+
if (LOCAL_ONLY_FLAGS.has(arg))
|
|
40
|
+
return false;
|
|
41
|
+
if (arg.startsWith("--to-branch=") ||
|
|
42
|
+
arg.startsWith("--branch=") ||
|
|
43
|
+
arg.startsWith("--repo=")) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Parses `co-maintainer review` after the `review` token (plan §8.1). */
|
|
50
|
+
export async function parseReviewArgs(args) {
|
|
51
|
+
const positional = args.filter((a) => !a.startsWith("--"));
|
|
52
|
+
const flags = reviewFlags(args);
|
|
53
|
+
const isPr = positional.length >= 2 &&
|
|
54
|
+
/^[^/]+\/[^/]+$/.test(positional[0]) &&
|
|
55
|
+
/^\d+$/.test(positional[1]);
|
|
56
|
+
if (isPr) {
|
|
57
|
+
const options = await parseArgs([
|
|
58
|
+
"review",
|
|
59
|
+
positional[0],
|
|
60
|
+
positional[1],
|
|
61
|
+
...filterReviewConfigArgs(args),
|
|
62
|
+
]);
|
|
63
|
+
if (flags.remote)
|
|
64
|
+
die("--remote is only for local review without a PR number");
|
|
65
|
+
if (flags.remakeBeforeReview) {
|
|
66
|
+
die("--remake-before-review is not supported for PR review");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
mode: "pr",
|
|
70
|
+
options: {
|
|
71
|
+
...options,
|
|
72
|
+
useCodegraph: flags.disableCodegraph ? false : true,
|
|
73
|
+
},
|
|
74
|
+
...flags,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (positional.length === 0) {
|
|
78
|
+
if (flags.remote)
|
|
79
|
+
return { mode: "remote", rawArgs: args, ...flags };
|
|
80
|
+
return { mode: "local", rawArgs: args, ...flags };
|
|
81
|
+
}
|
|
82
|
+
die("Usage: co-maintainer review [options]\n" +
|
|
83
|
+
" co-maintainer review owner/repo PR_NUMBER [options]");
|
|
84
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { parseFindings } from "../pr/findings.js";
|
|
2
|
+
import { humanCopy } from "../services/review.js";
|
|
3
|
+
export function reviewExitCode(markdown) {
|
|
4
|
+
const findings = parseFindings(markdown);
|
|
5
|
+
const blocking = findings.some((f) => f.blocking === true || /\[P0\b/i.test(f.heading));
|
|
6
|
+
return blocking ? 1 : 0;
|
|
7
|
+
}
|
|
8
|
+
export function printLocalReview(header, markdown) {
|
|
9
|
+
console.log(`\n${header}\n\n${humanCopy(markdown)}\n`);
|
|
10
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ParsedFinding } from "../pr/findings.ts";
|
|
2
|
+
import { type ResolvedFinding } from "../review/carry_over.ts";
|
|
3
|
+
import type { Revision } from "../review/revision.ts";
|
|
4
|
+
export type ReviewWarning = {
|
|
5
|
+
code: string;
|
|
6
|
+
message: string;
|
|
7
|
+
};
|
|
8
|
+
export type JsonReviewFinding = {
|
|
9
|
+
id: string;
|
|
10
|
+
state: "new" | "open" | "closed";
|
|
11
|
+
closeReason: "fixed" | "file_reverted" | null;
|
|
12
|
+
severity: string;
|
|
13
|
+
blocking: boolean;
|
|
14
|
+
path: string | null;
|
|
15
|
+
lineFrom: number | null;
|
|
16
|
+
lineTo: number | null;
|
|
17
|
+
title: string;
|
|
18
|
+
body: string;
|
|
19
|
+
suggestion: {
|
|
20
|
+
lineFrom: number;
|
|
21
|
+
lineTo: number;
|
|
22
|
+
text: string;
|
|
23
|
+
} | null;
|
|
24
|
+
};
|
|
25
|
+
export declare function isBlockingFinding(title: string, severity: string): boolean;
|
|
26
|
+
export declare function resolvedFromFirstReview(parsed: ParsedFinding[], filesByPath: Map<string, {
|
|
27
|
+
patch: string;
|
|
28
|
+
}>): ResolvedFinding[];
|
|
29
|
+
export declare function sortResolvedFindings(findings: ResolvedFinding[]): ResolvedFinding[];
|
|
30
|
+
export declare function toJsonFinding(row: ResolvedFinding): JsonReviewFinding;
|
|
31
|
+
export declare function revisionStats(revision: Revision): {
|
|
32
|
+
files: number;
|
|
33
|
+
additions: number;
|
|
34
|
+
deletions: number;
|
|
35
|
+
truncated: boolean;
|
|
36
|
+
};
|
|
37
|
+
export declare function summaryCounts(findings: ResolvedFinding[]): {
|
|
38
|
+
new: number;
|
|
39
|
+
open: number;
|
|
40
|
+
closed: number;
|
|
41
|
+
blocking: number;
|
|
42
|
+
};
|
|
43
|
+
export declare function reviewExitCodeFromResolved(findings: ResolvedFinding[]): number;
|
|
44
|
+
/** Plan §9.1 human-readable local review output. */
|
|
45
|
+
export declare function formatHumanLocalReview(header: string, revision: Revision, guideBuiltAt: string | null, codegraphState: "used" | "disabled" | "unavailable", findings: ResolvedFinding[], warnings: ReviewWarning[]): string;
|
|
46
|
+
/** Human-readable findings block for remote sync JSON (same shape as `toJsonFinding`). */
|
|
47
|
+
export declare function formatHumanJsonFindings(findings: JsonReviewFinding[]): string;
|
|
48
|
+
export declare function reviewExitCodeFromJsonFindings(findings: JsonReviewFinding[]): number;
|
|
49
|
+
export type LocalReviewJsonInput = {
|
|
50
|
+
repo: string;
|
|
51
|
+
branch: string;
|
|
52
|
+
baseLabel: string;
|
|
53
|
+
revision: Revision;
|
|
54
|
+
guideBuiltAt: string | null;
|
|
55
|
+
codegraphState: "used" | "disabled" | "unavailable";
|
|
56
|
+
codegraphReason: string | null;
|
|
57
|
+
findings: ResolvedFinding[];
|
|
58
|
+
warnings: ReviewWarning[];
|
|
59
|
+
usage: {
|
|
60
|
+
tokensIn: number;
|
|
61
|
+
tokensOut: number;
|
|
62
|
+
costUsd: number | null;
|
|
63
|
+
};
|
|
64
|
+
durationMs: number;
|
|
65
|
+
};
|
|
66
|
+
export type PrReviewJsonInput = {
|
|
67
|
+
repo: string;
|
|
68
|
+
prNumber: number;
|
|
69
|
+
markdown: string;
|
|
70
|
+
guideBuiltAt: string | null;
|
|
71
|
+
codegraphState: "used" | "disabled" | "unavailable";
|
|
72
|
+
codegraphReason: string | null;
|
|
73
|
+
usage: {
|
|
74
|
+
tokensIn: number;
|
|
75
|
+
tokensOut: number;
|
|
76
|
+
costUsd: number | null;
|
|
77
|
+
};
|
|
78
|
+
durationMs: number;
|
|
79
|
+
};
|
|
80
|
+
export declare function buildPrReviewJson(input: PrReviewJsonInput): string;
|
|
81
|
+
export declare function buildLocalReviewJson(input: LocalReviewJsonInput): string;
|