@open-cr-agent/cli 0.3.0 → 0.5.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.
Files changed (45) hide show
  1. package/README.md +3 -3
  2. package/dist/account-salt.d.ts +7 -0
  3. package/dist/account-salt.js +43 -0
  4. package/dist/cloud.d.ts +34 -0
  5. package/dist/cloud.js +272 -0
  6. package/dist/plugin-store.d.ts +20 -0
  7. package/dist/plugin-store.js +84 -0
  8. package/dist/plugins-command.d.ts +15 -0
  9. package/dist/plugins-command.js +183 -0
  10. package/dist/review/account-plugins.d.ts +23 -0
  11. package/dist/review/account-plugins.js +54 -0
  12. package/dist/review/account-settings.d.ts +100 -0
  13. package/dist/review/account-settings.js +106 -0
  14. package/dist/review/args.d.ts +2 -1
  15. package/dist/review/args.js +5 -0
  16. package/dist/review/cloud-findings.d.ts +31 -0
  17. package/dist/review/cloud-findings.js +80 -0
  18. package/dist/review/cloud-memory.d.ts +6 -0
  19. package/dist/review/cloud-memory.js +58 -0
  20. package/dist/review/cloud-providers.d.ts +12 -0
  21. package/dist/review/cloud-providers.js +60 -0
  22. package/dist/review/cloud-review.d.ts +19 -0
  23. package/dist/review/cloud-review.js +51 -0
  24. package/dist/review/cloud-settings.d.ts +16 -0
  25. package/dist/review/cloud-settings.js +118 -0
  26. package/dist/review/cloud-upload.d.ts +60 -0
  27. package/dist/review/cloud-upload.js +180 -0
  28. package/dist/review/command.d.ts +4 -0
  29. package/dist/review/command.js +91 -14
  30. package/dist/review/config.d.ts +65 -6
  31. package/dist/review/config.js +71 -7
  32. package/dist/review/plan-render.js +1 -1
  33. package/dist/review/plugins.d.ts +10 -0
  34. package/dist/review/plugins.js +46 -1
  35. package/dist/review/provenance.js +15 -2
  36. package/dist/review/remote-config.d.ts +6 -0
  37. package/dist/review/remote-config.js +3 -1
  38. package/dist/review/render.js +7 -2
  39. package/dist/review/sarif.js +1 -1
  40. package/dist/review/settings-sources.d.ts +11 -0
  41. package/dist/review/settings-sources.js +58 -0
  42. package/dist/review/target.d.ts +1 -0
  43. package/dist/review/target.js +4 -1
  44. package/dist/run.js +36 -0
  45. package/package.json +8 -8
@@ -0,0 +1,58 @@
1
+ import { ACCOUNT_SCALARS } from "./cloud-settings.js";
2
+ import { forTerminal } from "./terminal.js";
3
+ const TIERS = ["top", "standard", "light"];
4
+ /** file: the configuration before the account's settings; effective: after; filled: what they filled. */
5
+ export function effectiveSettings(file, effective, filled) {
6
+ const settings = [];
7
+ const add = (key, value, fromFile) => {
8
+ const fromAccount = filled.includes(key);
9
+ const source = fromFile && fromAccount
10
+ ? "file+account"
11
+ : fromAccount
12
+ ? "account"
13
+ : fromFile
14
+ ? "file"
15
+ : "default";
16
+ settings.push(source === "default" ? { key, source } : { key, value, source });
17
+ };
18
+ add("runtime", effective.runtime, file.runtimeSet);
19
+ for (const tier of TIERS) {
20
+ add(`models.${tier}`, effective.models[tier], file.models[tier] !== undefined);
21
+ }
22
+ for (const tier of TIERS) {
23
+ add(`effort.${tier}`, effective.effort[tier], file.effort[tier] !== undefined);
24
+ }
25
+ for (const [id, entry] of Object.entries(effective.reviewers)) {
26
+ add(`reviewers.${id}`, entry, file.reviewers[id] !== undefined);
27
+ }
28
+ for (const [role, entry] of Object.entries(effective.roles)) {
29
+ add(`roles.${role}`, entry, file.roles[role] !== undefined);
30
+ }
31
+ for (const key of ACCOUNT_SCALARS)
32
+ add(key, effective[key], file[key] !== undefined);
33
+ add("include", effective.include, file.include.length > 0);
34
+ add("exclude", effective.exclude, file.exclude.length > 0);
35
+ add("rules", effective.rules.map(({ path, source }) => ({ path, source })), file.rules.length > 0);
36
+ // A flag rather than a key: listed only when the account turned it on.
37
+ if (filled.includes("ultra"))
38
+ settings.push({ key: "ultra", value: true, source: "account" });
39
+ return settings;
40
+ }
41
+ export function renderSettings(settings, account) {
42
+ const lines = [
43
+ "",
44
+ account
45
+ ? `Settings (under your ocra Cloud settings, version ${account.version ?? "none"}):`
46
+ : "Settings:",
47
+ ];
48
+ const set = settings.filter((s) => s.source !== "default");
49
+ const width = Math.max(0, ...set.map((s) => s.key.length));
50
+ for (const s of set) {
51
+ lines.push(` ${s.key.padEnd(width)} ${JSON.stringify(s.value)} (${s.source})`);
52
+ }
53
+ const defaults = settings.filter((s) => s.source === "default").map((s) => s.key);
54
+ if (defaults.length > 0)
55
+ lines.push(` default: ${defaults.join(", ")}`);
56
+ return forTerminal(`${lines.join("\n")}\n`);
57
+ }
58
+ //# sourceMappingURL=settings-sources.js.map
@@ -4,6 +4,7 @@ import { type CliConfig } from "./config.js";
4
4
  export interface ReviewTarget {
5
5
  config: CliConfig;
6
6
  plugins: OcraPlugin[];
7
+ accountPlugins: boolean;
7
8
  createVcs(registry: PluginRegistry): VcsAdapter;
8
9
  readTrusted?: (path: string) => Promise<string | undefined>;
9
10
  publish: boolean;
@@ -16,6 +16,7 @@ export async function localTarget(args, cwd, root, env, warn, fetchImpl) {
16
16
  config,
17
17
  // Plugins named by the user's own file are resolved from where it is.
18
18
  plugins: await loadExternalPlugins(config.plugins, args.configFile ? dirname(args.configFile) : root),
19
+ accountPlugins: !args.ignoreRepoConfig,
19
20
  createVcs: (registry) => registry.createVcs("local", { cwd, target: args.target }),
20
21
  ...(args.ignoreRepoConfig ? { readTrusted: untrustedTreeReader(args, cwd) } : {}),
21
22
  publish: false,
@@ -62,6 +63,7 @@ export async function pullRequestTarget(pr, cwd, root, env, warn, fetchImpl, ign
62
63
  return {
63
64
  config,
64
65
  plugins: [],
66
+ accountPlugins: false,
65
67
  createVcs: (registry) => registry.createVcs("github", {
66
68
  owner,
67
69
  repo,
@@ -90,7 +92,7 @@ const GITLAB_API = "https://gitlab.com/api/v4";
90
92
  export async function mergeRequestTarget(mr, cwd, root, env, warn, fetchImpl, ignoreRepoConfig = false, configFile) {
91
93
  const token = env.GITLAB_TOKEN;
92
94
  if (!token) {
93
- throw new OcraError("CONFIG_CREDENTIALS_MISSING", "--mr needs a GitLab token in GITLAB_TOKEN: a project access token with the api scope and the Developer role (CI_JOB_TOKEN cannot post comments)");
95
+ throw new OcraError("CONFIG_CREDENTIALS_MISSING", "--mr needs a GitLab token in GITLAB_TOKEN with the api scope and the Developer role: a project access token, or on GitLab.com Free a personal access token of a dedicated account (CI_JOB_TOKEN cannot post comments)");
94
96
  }
95
97
  const origin = await originUrl(root);
96
98
  const project = mr.project ?? env.CI_PROJECT_ID ?? gitlabProject(origin);
@@ -125,6 +127,7 @@ export async function mergeRequestTarget(mr, cwd, root, env, warn, fetchImpl, ig
125
127
  return {
126
128
  config,
127
129
  plugins: [],
130
+ accountPlugins: false,
128
131
  createVcs: (registry) => registry.createVcs("gitlab", {
129
132
  project: /^\d+$/.test(project) ? Number(project) : project,
130
133
  iid: mr.iid,
package/dist/run.js CHANGED
@@ -2,8 +2,11 @@ import { writeFile } from "node:fs/promises";
2
2
  import { parseArgs } from "node:util";
3
3
  import { isOcraError } from "@open-cr-agent/core";
4
4
  import { errorMessage } from "@open-cr-agent/core/internal";
5
+ import { cloudCommand, defaultCloudDeps, LOGIN_USAGE } from "./cloud.js";
5
6
  import { memoryCommand } from "./memory.js";
6
7
  import { metricsCommand } from "./metrics.js";
8
+ import { pluginsDir } from "./plugin-store.js";
9
+ import { defaultNpm, PLUGINS_USAGE, pluginsCommand } from "./plugins-command.js";
7
10
  import { parseReviewArgs, REVIEW_USAGE, UsageError } from "./review/args.js";
8
11
  import { BUILTIN_PLUGINS, EXIT, reviewCommand } from "./review/command.js";
9
12
  import { BUILTIN_RUNTIMES } from "./review/runtimes.js";
@@ -15,6 +18,10 @@ Commands:
15
18
  review Review code changes (run "ocra review --help" for options)
16
19
  memory Remember findings the team accepts (run "ocra memory --help")
17
20
  metrics Counts over past reviews: runs, cost, findings, per reviewer (run "ocra metrics --help")
21
+ plugins Allow plugins your ocra Cloud settings name on this machine (run "ocra plugins --help")
22
+ login Sign in to ocra Cloud (in development; run "ocra login --help")
23
+ logout Sign out of ocra Cloud
24
+ whoami Show the ocra Cloud account
18
25
 
19
26
  Options:
20
27
  -h, --help Show help
@@ -27,6 +34,7 @@ export function defaultDeps() {
27
34
  builtinPlugins: BUILTIN_PLUGINS,
28
35
  runtimes: BUILTIN_RUNTIMES,
29
36
  writeFile: (path, content) => writeFile(path, content, "utf8"),
37
+ cloud: defaultCloudDeps(process.env),
30
38
  now: Date.now,
31
39
  heartbeatMs: 30_000,
32
40
  onInterrupt(handler) {
@@ -61,6 +69,34 @@ export async function run(argv, out, err, deps = defaultDeps()) {
61
69
  return EXIT.error;
62
70
  }
63
71
  }
72
+ if (command === "plugins") {
73
+ try {
74
+ return await pluginsCommand(rest, out, {
75
+ dir: pluginsDir(deps.env),
76
+ npm: deps.npm ?? defaultNpm(),
77
+ });
78
+ }
79
+ catch (error) {
80
+ if (error instanceof UsageError) {
81
+ err.write(`${error.message ? `${error.message}\n\n` : ""}${PLUGINS_USAGE}`);
82
+ }
83
+ else
84
+ err.write(failure(error));
85
+ return EXIT.error;
86
+ }
87
+ }
88
+ if (command === "login" || command === "logout" || command === "whoami") {
89
+ try {
90
+ return await cloudCommand(command, rest, out, err, defaultCloudDeps(deps.env));
91
+ }
92
+ catch (error) {
93
+ if (error instanceof UsageError)
94
+ err.write(`${error.message}\n\n${LOGIN_USAGE}`);
95
+ else
96
+ err.write(failure(error));
97
+ return EXIT.error;
98
+ }
99
+ }
64
100
  if (command !== undefined && !command.startsWith("-")) {
65
101
  err.write(`Unknown command: ${command}\n\n${USAGE}`);
66
102
  return EXIT.error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-cr-agent/cli",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "ocra: open-source multi-agent code review for local changes and GitHub pull requests",
5
5
  "keywords": [
6
6
  "code-review",
@@ -10,7 +10,7 @@
10
10
  "github-action"
11
11
  ],
12
12
  "license": "Apache-2.0",
13
- "homepage": "https://ocra.majincheng.com",
13
+ "homepage": "https://ocracloud.com",
14
14
  "repository": {
15
15
  "type": "git",
16
16
  "url": "git+https://github.com/jma49/Open-CR-Agent.git",
@@ -37,15 +37,15 @@
37
37
  "!dist/**/*.map"
38
38
  ],
39
39
  "dependencies": {
40
- "@open-cr-agent/core": "0.3.0",
41
- "@open-cr-agent/runtime-direct": "0.3.0",
42
- "@open-cr-agent/vcs-github": "0.3.0",
43
- "@open-cr-agent/vcs-gitlab": "0.3.0",
44
- "@open-cr-agent/vcs-local": "0.3.0",
40
+ "@open-cr-agent/core": "0.5.0",
41
+ "@open-cr-agent/runtime-direct": "0.5.0",
42
+ "@open-cr-agent/vcs-github": "0.5.0",
43
+ "@open-cr-agent/vcs-gitlab": "0.5.0",
44
+ "@open-cr-agent/vcs-local": "0.5.0",
45
45
  "zod": "^4.6.5"
46
46
  },
47
47
  "optionalDependencies": {
48
- "@open-cr-agent/runtime-opencode": "0.3.0"
48
+ "@open-cr-agent/runtime-opencode": "0.5.0"
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public"