@open-cr-agent/cli 0.5.0 → 0.6.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/dist/cloud/account-salt.d.ts +6 -0
- package/dist/cloud/account-salt.js +33 -0
- package/dist/{review → cloud}/account-settings.js +5 -4
- package/dist/cloud/browser.d.ts +17 -0
- package/dist/cloud/browser.js +37 -0
- package/dist/cloud/client.d.ts +93 -0
- package/dist/cloud/client.js +221 -0
- package/dist/cloud/credentials.d.ts +18 -0
- package/dist/cloud/credentials.js +52 -0
- package/dist/cloud/deps.d.ts +14 -0
- package/dist/cloud/deps.js +34 -0
- package/dist/cloud/file-lock.d.ts +14 -0
- package/dist/cloud/file-lock.js +77 -0
- package/dist/cloud/findings.d.ts +8 -0
- package/dist/{review/cloud-findings.js → cloud/findings.js} +10 -32
- package/dist/cloud/gateway-token.d.ts +18 -0
- package/dist/cloud/gateway-token.js +63 -0
- package/dist/cloud/memory.d.ts +8 -0
- package/dist/cloud/memory.js +68 -0
- package/dist/cloud/private-file.d.ts +8 -0
- package/dist/cloud/private-file.js +46 -0
- package/dist/{review/cloud-providers.d.ts → cloud/providers.d.ts} +12 -6
- package/dist/cloud/providers.js +132 -0
- package/dist/cloud/review.d.ts +28 -0
- package/dist/cloud/review.js +76 -0
- package/dist/cloud/settings.d.ts +22 -0
- package/dist/cloud/settings.js +64 -0
- package/dist/cloud/upload.d.ts +20 -0
- package/dist/{review/cloud-upload.js → cloud/upload.js} +74 -71
- package/dist/commands/login.d.ts +5 -0
- package/dist/commands/login.js +164 -0
- package/dist/commands/memory.d.ts +3 -0
- package/dist/{memory.js → commands/memory.js} +21 -20
- package/dist/commands/metrics.d.ts +45 -0
- package/dist/{metrics.js → commands/metrics.js} +32 -45
- package/dist/{plugins-command.d.ts → commands/plugins.d.ts} +3 -9
- package/dist/{plugins-command.js → commands/plugins.js} +29 -53
- package/dist/{review → commands/review}/args.d.ts +7 -10
- package/dist/{review → commands/review}/args.js +11 -16
- package/dist/commands/review/deliver.d.ts +7 -0
- package/dist/commands/review/deliver.js +56 -0
- package/dist/commands/review/deps.d.ts +18 -0
- package/dist/commands/review/deps.js +2 -0
- package/dist/commands/review/execute-run.d.ts +13 -0
- package/dist/commands/review/execute-run.js +97 -0
- package/dist/commands/review/exit-code.d.ts +4 -0
- package/dist/commands/review/exit-code.js +29 -0
- package/dist/commands/review/plan-prices.d.ts +3 -0
- package/dist/commands/review/plan-prices.js +18 -0
- package/dist/{review → commands/review}/plan-render.js +22 -2
- package/dist/commands/review/plan-run.d.ts +5 -0
- package/dist/commands/review/plan-run.js +38 -0
- package/dist/commands/review/plan-schema.d.ts +97 -0
- package/dist/commands/review/plan-schema.js +34 -0
- package/dist/{review → commands/review}/progress.d.ts +3 -5
- package/dist/{review → commands/review}/progress.js +3 -3
- package/dist/{review → commands/review}/provenance.d.ts +4 -2
- package/dist/{review → commands/review}/provenance.js +2 -3
- package/dist/{review → commands/review}/render.js +1 -1
- package/dist/commands/review/resolve-run.d.ts +29 -0
- package/dist/commands/review/resolve-run.js +125 -0
- package/dist/commands/review/review-options.d.ts +6 -0
- package/dist/commands/review/review-options.js +35 -0
- package/dist/{review → commands/review}/runtimes.js +1 -1
- package/dist/{review → commands/review}/sarif-input.d.ts +0 -1
- package/dist/{review → commands/review}/sarif-input.js +5 -5
- package/dist/commands/review/sarif.d.ts +96 -0
- package/dist/{review → commands/review}/sarif.js +29 -7
- package/dist/commands/review/settings-sources.d.ts +17 -0
- package/dist/commands/review/settings-sources.js +30 -0
- package/dist/commands/review/target.d.ts +38 -0
- package/dist/commands/review/target.js +126 -0
- package/dist/commands/review.d.ts +7 -0
- package/dist/commands/review.js +34 -0
- package/dist/config/cli-config.d.ts +41 -0
- package/dist/config/cli-config.js +199 -0
- package/dist/{review/remote-config.d.ts → config/remote.d.ts} +3 -3
- package/dist/{review/remote-config.js → config/remote.js} +5 -23
- package/dist/{review/config.d.ts → config/schema.d.ts} +8 -31
- package/dist/config/schema.js +138 -0
- package/dist/config/settings.d.ts +37 -0
- package/dist/config/settings.js +133 -0
- package/dist/config/user-dir.d.ts +3 -0
- package/dist/config/user-dir.js +10 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -1
- package/dist/internal.d.ts +6 -0
- package/dist/internal.js +7 -0
- package/dist/io/exit.d.ts +9 -0
- package/dist/io/exit.js +12 -0
- package/dist/io/output.d.ts +4 -0
- package/dist/io/output.js +2 -0
- package/dist/io/usage-error.d.ts +5 -0
- package/dist/io/usage-error.js +8 -0
- package/dist/main.js +2 -2
- package/dist/{review/account-plugins.d.ts → plugins/account.d.ts} +2 -2
- package/dist/{review/account-plugins.js → plugins/account.js} +7 -7
- package/dist/{review/plugins.d.ts → plugins/load.d.ts} +2 -2
- package/dist/{review/plugins.js → plugins/load.js} +6 -5
- package/dist/plugins/npm.d.ts +8 -0
- package/dist/plugins/npm.js +24 -0
- package/dist/{plugin-store.d.ts → plugins/store.d.ts} +1 -1
- package/dist/{plugin-store.js → plugins/store.js} +5 -4
- package/dist/repository-id.d.ts +12 -0
- package/dist/repository-id.js +72 -0
- package/dist/run.d.ts +2 -2
- package/dist/run.js +15 -12
- package/dist/session/store.d.ts +9 -0
- package/dist/session/store.js +31 -0
- package/package.json +17 -7
- package/dist/account-salt.d.ts +0 -7
- package/dist/account-salt.js +0 -43
- package/dist/cloud.d.ts +0 -34
- package/dist/cloud.js +0 -272
- package/dist/memory.d.ts +0 -4
- package/dist/metrics.d.ts +0 -47
- package/dist/review/cloud-findings.d.ts +0 -31
- package/dist/review/cloud-memory.d.ts +0 -6
- package/dist/review/cloud-memory.js +0 -58
- package/dist/review/cloud-providers.js +0 -60
- package/dist/review/cloud-review.d.ts +0 -19
- package/dist/review/cloud-review.js +0 -51
- package/dist/review/cloud-settings.d.ts +0 -16
- package/dist/review/cloud-settings.js +0 -118
- package/dist/review/cloud-upload.d.ts +0 -60
- package/dist/review/command.d.ts +0 -33
- package/dist/review/command.js +0 -293
- package/dist/review/config.js +0 -304
- package/dist/review/sarif.d.ts +0 -4
- package/dist/review/settings-sources.d.ts +0 -11
- package/dist/review/settings-sources.js +0 -58
- package/dist/review/target.d.ts +0 -18
- package/dist/review/target.js +0 -210
- /package/dist/{review → cloud}/account-settings.d.ts +0 -0
- /package/dist/{review → commands/review}/plan-render.d.ts +0 -0
- /package/dist/{review → commands/review}/render.d.ts +0 -0
- /package/dist/{review → commands/review}/runtimes.d.ts +0 -0
- /package/dist/{review → io}/terminal.d.ts +0 -0
- /package/dist/{review → io}/terminal.js +0 -0
package/dist/metrics.d.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { type Severity, type Verification } from "@open-cr-agent/core";
|
|
2
|
-
import type { Output } from "./review/progress.js";
|
|
3
|
-
export declare const METRICS_VERSION = 1;
|
|
4
|
-
export declare const METRICS_USAGE = "Usage: ocra metrics [options]\n\nCounts over the finished reviews in .ocra/sessions: runs, cost, findings,\nwhat reviewers later fixed or dismissed, per reviewer. Reads each session's\nreport.json (report version 1); nothing calls a model.\n\nOptions:\n --sessions <dir> Sessions directory (default: .ocra/sessions of this repository)\n --since <date> Only runs started at or after this ISO 8601 date\n --format <text|json> Output format (default: text); the JSON carries \"version\": 1\n -h, --help Show help\n";
|
|
5
|
-
export interface ReviewerMetrics {
|
|
6
|
-
tasks: number;
|
|
7
|
-
failedTasks: number;
|
|
8
|
-
findings: number;
|
|
9
|
-
costUsd: number;
|
|
10
|
-
fixed: number;
|
|
11
|
-
dismissed: number;
|
|
12
|
-
acceptanceRate: number | null;
|
|
13
|
-
}
|
|
14
|
-
export interface Metrics {
|
|
15
|
-
version: typeof METRICS_VERSION;
|
|
16
|
-
sessionsDir: string;
|
|
17
|
-
since?: string;
|
|
18
|
-
runs: {
|
|
19
|
-
total: number;
|
|
20
|
-
byVerdict: Record<string, number>;
|
|
21
|
-
incomplete: number;
|
|
22
|
-
unreadable: number;
|
|
23
|
-
};
|
|
24
|
-
cost: {
|
|
25
|
-
usd: number;
|
|
26
|
-
inputTokens: number;
|
|
27
|
-
outputTokens: number;
|
|
28
|
-
usdPerRun: number | null;
|
|
29
|
-
};
|
|
30
|
-
findings: {
|
|
31
|
-
reported: number;
|
|
32
|
-
unique: number;
|
|
33
|
-
bySeverity: Record<Severity, number>;
|
|
34
|
-
byVerification: Record<Verification, number>;
|
|
35
|
-
};
|
|
36
|
-
outcomes: {
|
|
37
|
-
fixed: number;
|
|
38
|
-
dismissed: number;
|
|
39
|
-
acceptanceRate: number | null;
|
|
40
|
-
};
|
|
41
|
-
reviewers: Record<string, ReviewerMetrics>;
|
|
42
|
-
}
|
|
43
|
-
export declare function metricsCommand(argv: string[], out: Output, cwd: string): Promise<number>;
|
|
44
|
-
export declare function sessionStart(id: string): Date | undefined;
|
|
45
|
-
export declare function collectMetrics(sessionsDir: string, since?: Date): Promise<Metrics>;
|
|
46
|
-
export declare function renderMetrics(m: Metrics): string;
|
|
47
|
-
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { ReviewReport, Severity, Verification } from "@open-cr-agent/core";
|
|
2
|
-
export type SharedFinding = {
|
|
3
|
-
fingerprint: string;
|
|
4
|
-
reviewer: string;
|
|
5
|
-
severity: Severity;
|
|
6
|
-
category: string;
|
|
7
|
-
verification: Verification;
|
|
8
|
-
file: string;
|
|
9
|
-
lineStart: number | null;
|
|
10
|
-
lineEnd: number | null;
|
|
11
|
-
title: string;
|
|
12
|
-
body: string;
|
|
13
|
-
suggestion: string | null;
|
|
14
|
-
code: string;
|
|
15
|
-
redacted?: true;
|
|
16
|
-
truncated?: true;
|
|
17
|
-
};
|
|
18
|
-
export declare const MAX_FINDINGS = 200;
|
|
19
|
-
export declare const MAX_FIELD = 4096;
|
|
20
|
-
export declare const MAX_TOTAL_BYTES = 262144;
|
|
21
|
-
export declare const REDACTED = "[redacted]";
|
|
22
|
-
export declare function redact(text: string): {
|
|
23
|
-
text: string;
|
|
24
|
-
redacted: boolean;
|
|
25
|
-
};
|
|
26
|
-
/** The report's findings as uploaded, redacted and bounded; `left` counts those not sent. */
|
|
27
|
-
export declare function sharedFindings(report: Pick<ReviewReport, "findings">): {
|
|
28
|
-
findings: SharedFinding[];
|
|
29
|
-
left: number;
|
|
30
|
-
};
|
|
31
|
-
//# sourceMappingURL=cloud-findings.d.ts.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { MemoryEntry } from "@open-cr-agent/core";
|
|
2
|
-
import type { CloudDeps, Credentials } from "../cloud.js";
|
|
3
|
-
/** The account's entries for the repository; [] and a warning when they cannot be read. */
|
|
4
|
-
export declare function fetchAccountMemory(deps: Pick<CloudDeps, "fetch">, session: Pick<Credentials, "server" | "access_token">, repoHash: string, warn: (message: string) => void): Promise<MemoryEntry[]>;
|
|
5
|
-
export declare function parseAccountMemory(body: unknown, warn: (message: string) => void): MemoryEntry[];
|
|
6
|
-
//# sourceMappingURL=cloud-memory.d.ts.map
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { memoryEntrySchema } from "@open-cr-agent/core/internal";
|
|
2
|
-
import { VERSION } from "../version.js";
|
|
3
|
-
// The findings the account remembers for one repository (ADR-0028, 4), set
|
|
4
|
-
// from the web. A review applies them with .ocra/memory.json's.
|
|
5
|
-
// The server keeps at most 500 per repository; more is not an answer to trust.
|
|
6
|
-
const MAX_ENTRIES = 500;
|
|
7
|
-
/** The account's entries for the repository; [] and a warning when they cannot be read. */
|
|
8
|
-
export async function fetchAccountMemory(deps, session, repoHash, warn) {
|
|
9
|
-
let body;
|
|
10
|
-
try {
|
|
11
|
-
const res = await deps.fetch(`${session.server}/api/memory?repo=${encodeURIComponent(repoHash)}`, {
|
|
12
|
-
headers: {
|
|
13
|
-
authorization: `Bearer ${session.access_token}`,
|
|
14
|
-
"user-agent": `ocra/${VERSION}`,
|
|
15
|
-
},
|
|
16
|
-
signal: AbortSignal.timeout(15_000),
|
|
17
|
-
});
|
|
18
|
-
// A server without account memory has none to apply.
|
|
19
|
-
if (res.status === 404)
|
|
20
|
-
return [];
|
|
21
|
-
if (!res.ok)
|
|
22
|
-
throw new Error(`HTTP ${res.status}`);
|
|
23
|
-
body = await res.json();
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
warn(`could not read your ocra Cloud memory (${error instanceof Error ? error.message : "error"}); the review applies the repository's alone`);
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
return parseAccountMemory(body, warn);
|
|
30
|
-
}
|
|
31
|
-
export function parseAccountMemory(body, warn) {
|
|
32
|
-
const list = body?.entries;
|
|
33
|
-
if (!Array.isArray(list)) {
|
|
34
|
-
warn("ignoring your ocra Cloud memory: the server's answer has no entries");
|
|
35
|
-
return [];
|
|
36
|
-
}
|
|
37
|
-
const entries = [];
|
|
38
|
-
let refused = 0;
|
|
39
|
-
for (const raw of list.slice(0, MAX_ENTRIES)) {
|
|
40
|
-
const r = (typeof raw === "object" && raw !== null ? raw : {});
|
|
41
|
-
const parsed = memoryEntrySchema.safeParse({
|
|
42
|
-
fingerprint: r.fingerprint,
|
|
43
|
-
file: r.file,
|
|
44
|
-
title: r.title,
|
|
45
|
-
reason: r.reason,
|
|
46
|
-
...(typeof r.createdAt === "string" ? { added: r.createdAt.slice(0, 10) } : {}),
|
|
47
|
-
});
|
|
48
|
-
if (parsed.success)
|
|
49
|
-
entries.push(parsed.data);
|
|
50
|
-
else
|
|
51
|
-
refused += 1;
|
|
52
|
-
}
|
|
53
|
-
if (refused > 0) {
|
|
54
|
-
warn(`ignoring ${refused} ocra Cloud memory entr${refused > 1 ? "ies" : "y"} this version of ocra cannot read`);
|
|
55
|
-
}
|
|
56
|
-
return entries;
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=cloud-memory.js.map
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { OcraError } from "@open-cr-agent/core";
|
|
2
|
-
import { cloudSession } from "../cloud.js";
|
|
3
|
-
// Models named ocra-<provider>/<model> go through the ocra Cloud gateway with
|
|
4
|
-
// the key stored there for <provider> (ADR-0024). Each such provider becomes
|
|
5
|
-
// an OpenAI-compatible endpoint declared for this run, authorized by the
|
|
6
|
-
// signed-in session's access token. Without such a model nothing here reads
|
|
7
|
-
// the session or touches the network.
|
|
8
|
-
export const CLOUD_PREFIX = "ocra-";
|
|
9
|
-
/** Where the access token travels to the runtime; never a user's variable (OCRA_ is refused in config). */
|
|
10
|
-
export const CLOUD_TOKEN_ENV = "OCRA_CLOUD_ACCESS_TOKEN";
|
|
11
|
-
// A review may run for half an hour; start it with a token that outlives it.
|
|
12
|
-
const MIN_TOKEN_MS = 35 * 60_000;
|
|
13
|
-
// chains: every chain of the run, the tiers' and the agents' own.
|
|
14
|
-
export async function withCloudProviders(chains, providers, env, deps, warn) {
|
|
15
|
-
const wanted = new Map();
|
|
16
|
-
for (const model of chains.flatMap((chain) => chain ?? [])) {
|
|
17
|
-
const slash = model.indexOf("/");
|
|
18
|
-
const id = model.slice(0, slash);
|
|
19
|
-
if (slash < 0 || !id.startsWith(CLOUD_PREFIX) || providers[id])
|
|
20
|
-
continue;
|
|
21
|
-
const set = wanted.get(id) ?? new Set();
|
|
22
|
-
set.add(model.slice(slash + 1));
|
|
23
|
-
wanted.set(id, set);
|
|
24
|
-
}
|
|
25
|
-
if (wanted.size === 0)
|
|
26
|
-
return { providers: { ...providers }, env };
|
|
27
|
-
const names = [...wanted.keys()].join(", ");
|
|
28
|
-
if (env.OCRA_CLOUD === "off") {
|
|
29
|
-
throw new OcraError("CONFIG_INVALID", `Models name ocra Cloud (${names}) but OCRA_CLOUD=off`);
|
|
30
|
-
}
|
|
31
|
-
const session = deps && (await cloudSession(deps, MIN_TOKEN_MS));
|
|
32
|
-
if (!session) {
|
|
33
|
-
throw new OcraError("CONFIG_CREDENTIALS_MISSING", `Models name ocra Cloud (${names}): sign in with ocra login`);
|
|
34
|
-
}
|
|
35
|
-
const res = await deps.fetch(`${session.server}/api/providers`, {
|
|
36
|
-
signal: AbortSignal.timeout(30_000),
|
|
37
|
-
});
|
|
38
|
-
if (!res.ok) {
|
|
39
|
-
throw new OcraError("RUNTIME_START_FAILED", `ocra Cloud answered ${res.status} for its providers`);
|
|
40
|
-
}
|
|
41
|
-
const listed = (await res.json()).providers ?? [];
|
|
42
|
-
const declared = { ...providers };
|
|
43
|
-
for (const [id, modelIds] of wanted) {
|
|
44
|
-
const name = id.slice(CLOUD_PREFIX.length);
|
|
45
|
-
const chat = listed
|
|
46
|
-
.find((p) => p.name === name)
|
|
47
|
-
?.paths.find((path) => path.endsWith("/chat/completions"));
|
|
48
|
-
if (!chat) {
|
|
49
|
-
throw new OcraError("CONFIG_INVALID", `ocra Cloud has no OpenAI-compatible chat endpoint for "${name}" (named by ${id})`);
|
|
50
|
-
}
|
|
51
|
-
declared[id] = {
|
|
52
|
-
baseUrl: `${session.server}/api/gateway/${name}${chat.slice(0, -"/chat/completions".length)}`,
|
|
53
|
-
apiKeyEnv: CLOUD_TOKEN_ENV,
|
|
54
|
-
models: Object.fromEntries([...modelIds].map((m) => [m, { input: 0, output: 0 }])),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
warn(`${names}: models through ocra Cloud are not priced, so reported cost and --max-cost-usd do not count them`);
|
|
58
|
-
return { providers: declared, env: { ...env, [CLOUD_TOKEN_ENV]: session.access_token } };
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=cloud-providers.js.map
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { MemoryEntry, ReviewReport } from "@open-cr-agent/core";
|
|
2
|
-
import { type CloudDeps } from "../cloud.js";
|
|
3
|
-
import { type ReviewSource } from "./cloud-upload.js";
|
|
4
|
-
import type { Output } from "./progress.js";
|
|
5
|
-
export type CloudReview = {
|
|
6
|
-
repoHash: string;
|
|
7
|
-
shareFindings: boolean;
|
|
8
|
-
memory: MemoryEntry[];
|
|
9
|
-
};
|
|
10
|
-
/** Undefined when the saved session is gone; a failure to reach ocra Cloud is one warning. */
|
|
11
|
-
export declare function prepareCloudReview(root: string, deps: CloudDeps, warn: (message: string) => void): Promise<CloudReview | undefined>;
|
|
12
|
-
/** Sends the counts, and the findings when the account shares them. */
|
|
13
|
-
export declare function sendToCloud(report: ReviewReport, cloud: CloudReview, deps: CloudDeps, run: {
|
|
14
|
-
source: ReviewSource;
|
|
15
|
-
durationMs: number;
|
|
16
|
-
err: Output;
|
|
17
|
-
warn: (message: string) => void;
|
|
18
|
-
}): Promise<void>;
|
|
19
|
-
//# sourceMappingURL=cloud-review.d.ts.map
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { fetchAccountSalt, saveAccountSalt } from "../account-salt.js";
|
|
2
|
-
import { cloudSession } from "../cloud.js";
|
|
3
|
-
import { sharedFindings } from "./cloud-findings.js";
|
|
4
|
-
import { fetchAccountMemory } from "./cloud-memory.js";
|
|
5
|
-
import { repoHash, uploadOf, uploadReview } from "./cloud-upload.js";
|
|
6
|
-
/** Undefined when the saved session is gone; a failure to reach ocra Cloud is one warning. */
|
|
7
|
-
export async function prepareCloudReview(root, deps, warn) {
|
|
8
|
-
let session;
|
|
9
|
-
let salt;
|
|
10
|
-
try {
|
|
11
|
-
session = await cloudSession(deps);
|
|
12
|
-
if (!session)
|
|
13
|
-
return undefined;
|
|
14
|
-
salt = await fetchAccountSalt(deps, session.server, session.access_token);
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
// This machine's salt still groups the counts. Findings and the
|
|
18
|
-
// account's memory are keyed by the account's hash when it shares
|
|
19
|
-
// findings, so without its answer neither can be matched: none is sent
|
|
20
|
-
// and none applied.
|
|
21
|
-
warn(`could not read your ocra Cloud account (${error instanceof Error ? error.message : "error"}); this review sends no findings and applies no account memory`);
|
|
22
|
-
return {
|
|
23
|
-
repoHash: await repoHash(root, deps.credentialsPath),
|
|
24
|
-
shareFindings: false,
|
|
25
|
-
memory: [],
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
await saveAccountSalt(deps.credentialsPath, salt);
|
|
29
|
-
const hash = await repoHash(root, deps.credentialsPath, salt ?? undefined);
|
|
30
|
-
return {
|
|
31
|
-
repoHash: hash,
|
|
32
|
-
shareFindings: salt !== null,
|
|
33
|
-
memory: await fetchAccountMemory(deps, session, hash, warn),
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/** Sends the counts, and the findings when the account shares them. */
|
|
37
|
-
export async function sendToCloud(report, cloud, deps, run) {
|
|
38
|
-
const upload = uploadOf(report, run.source, cloud.repoHash, run.durationMs);
|
|
39
|
-
const shared = cloud.shareFindings ? sharedFindings(report) : undefined;
|
|
40
|
-
const sent = await uploadReview(upload, deps, run.warn, shared?.findings);
|
|
41
|
-
if (!sent)
|
|
42
|
-
return;
|
|
43
|
-
if (sent.findings > 0) {
|
|
44
|
-
const left = shared?.left ? ` (${shared.left} left out by the size limit)` : "";
|
|
45
|
-
run.err.write(`[ocra] Sent this review's counts and ${sent.findings} finding(s) to ocra Cloud${left} (--no-upload to skip)\n`);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
run.err.write("[ocra] Sent this review's counts to ocra Cloud (--no-upload to skip)\n");
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=cloud-review.js.map
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type CloudDeps } from "../cloud.js";
|
|
2
|
-
import { type AccountPlugins } from "./account-plugins.js";
|
|
3
|
-
import { type AccountSettings } from "./account-settings.js";
|
|
4
|
-
import type { CliConfig } from "./config.js";
|
|
5
|
-
export declare const ACCOUNT_SCALARS: readonly ["concurrency", "taskTimeoutMinutes", "runTimeoutMinutes", "maxCostUsd", "maxTasks", "verify", "judge", "sampling"];
|
|
6
|
-
/** The account's settings; undefined when signed out or unreachable (a warning says which). */
|
|
7
|
-
export declare function fetchAccountSettings(deps: CloudDeps, warn: (message: string) => void): Promise<{
|
|
8
|
-
settings?: AccountSettings;
|
|
9
|
-
plugins: AccountPlugins;
|
|
10
|
-
} | undefined>;
|
|
11
|
-
/** The configuration with the account's settings under it, and what they filled in. */
|
|
12
|
-
export declare function layerAccountSettings(config: CliConfig, account: AccountSettings): {
|
|
13
|
-
config: CliConfig;
|
|
14
|
-
filled: string[];
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=cloud-settings.d.ts.map
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { cloudSession } from "../cloud.js";
|
|
2
|
-
import { VERSION } from "../version.js";
|
|
3
|
-
import { parseAccountPlugins } from "./account-plugins.js";
|
|
4
|
-
import { parseAccountSettings } from "./account-settings.js";
|
|
5
|
-
// ocra Cloud's account settings fill what the repository's configuration
|
|
6
|
-
// leaves out (ADR-0025, ADR-0027): a tier's models and effort, a reviewer's
|
|
7
|
-
// or role's whole entry, the runtime and each limit. What the configuration
|
|
8
|
-
// sets always wins; include, exclude and rules combine, the repository's
|
|
9
|
-
// first.
|
|
10
|
-
const TIERS = ["top", "standard", "light"];
|
|
11
|
-
// Each set by the configuration or else by the account, whole.
|
|
12
|
-
export const ACCOUNT_SCALARS = [
|
|
13
|
-
"concurrency",
|
|
14
|
-
"taskTimeoutMinutes",
|
|
15
|
-
"runTimeoutMinutes",
|
|
16
|
-
"maxCostUsd",
|
|
17
|
-
"maxTasks",
|
|
18
|
-
"verify",
|
|
19
|
-
"judge",
|
|
20
|
-
"sampling",
|
|
21
|
-
];
|
|
22
|
-
/** The account's settings; undefined when signed out or unreachable (a warning says which). */
|
|
23
|
-
export async function fetchAccountSettings(deps, warn) {
|
|
24
|
-
let body;
|
|
25
|
-
try {
|
|
26
|
-
const session = await cloudSession(deps);
|
|
27
|
-
if (!session)
|
|
28
|
-
return undefined;
|
|
29
|
-
const res = await deps.fetch(`${session.server}/api/preferences`, {
|
|
30
|
-
headers: { authorization: `Bearer ${session.access_token}`, "user-agent": `ocra/${VERSION}` },
|
|
31
|
-
signal: AbortSignal.timeout(15_000),
|
|
32
|
-
});
|
|
33
|
-
if (!res.ok) {
|
|
34
|
-
warn(`could not read your ocra Cloud settings (HTTP ${res.status}); the review uses the repository's`);
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
body = await res.json();
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
warn(`could not read your ocra Cloud settings (${error.message}); the review uses the repository's`);
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
if (typeof body !== "object" || body === null) {
|
|
44
|
-
warn("ignoring your ocra Cloud settings: the server's answer is not an object");
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
const { settings, warnings } = parseAccountSettings(body);
|
|
48
|
-
for (const warning of warnings)
|
|
49
|
-
warn(warning);
|
|
50
|
-
return { ...(settings ? { settings } : {}), plugins: parseAccountPlugins(body, warn) };
|
|
51
|
-
}
|
|
52
|
-
/** The configuration with the account's settings under it, and what they filled in. */
|
|
53
|
-
export function layerAccountSettings(config, account) {
|
|
54
|
-
const filled = [];
|
|
55
|
-
const models = { ...config.models };
|
|
56
|
-
const effort = { ...config.effort };
|
|
57
|
-
for (const tier of TIERS) {
|
|
58
|
-
const chain = account.models?.[tier];
|
|
59
|
-
if (!config.models[tier]?.length && chain) {
|
|
60
|
-
models[tier] = chain;
|
|
61
|
-
filled.push(`models.${tier}`);
|
|
62
|
-
}
|
|
63
|
-
const level = account.effort?.[tier];
|
|
64
|
-
if (config.effort[tier] === undefined && level !== undefined) {
|
|
65
|
-
effort[tier] = level;
|
|
66
|
-
filled.push(`effort.${tier}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
const reviewers = { ...config.reviewers };
|
|
70
|
-
for (const [id, entry] of Object.entries(account.reviewers ?? {})) {
|
|
71
|
-
if (reviewers[id] === undefined) {
|
|
72
|
-
reviewers[id] = entry;
|
|
73
|
-
filled.push(`reviewers.${id}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const roles = { ...config.roles };
|
|
77
|
-
for (const [role, entry] of Object.entries(account.roles ?? {})) {
|
|
78
|
-
if (roles[role] === undefined && entry) {
|
|
79
|
-
roles[role] = entry;
|
|
80
|
-
filled.push(`roles.${role}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
const out = {
|
|
84
|
-
...config,
|
|
85
|
-
models,
|
|
86
|
-
effort,
|
|
87
|
-
reviewers,
|
|
88
|
-
roles,
|
|
89
|
-
accountSettings: { version: account.version },
|
|
90
|
-
};
|
|
91
|
-
if (!config.runtimeSet && account.runtime) {
|
|
92
|
-
out.runtime = account.runtime;
|
|
93
|
-
out.runtimeSet = true;
|
|
94
|
-
filled.push("runtime");
|
|
95
|
-
}
|
|
96
|
-
for (const key of ACCOUNT_SCALARS) {
|
|
97
|
-
if (config[key] === undefined && account[key] !== undefined) {
|
|
98
|
-
Object.assign(out, { [key]: account[key] });
|
|
99
|
-
filled.push(key);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
for (const key of ["include", "exclude"]) {
|
|
103
|
-
const added = (account[key] ?? []).filter((glob) => !config[key].includes(glob));
|
|
104
|
-
if (added.length > 0) {
|
|
105
|
-
out[key] = [...config[key], ...added];
|
|
106
|
-
filled.push(key);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (account.rules?.length) {
|
|
110
|
-
out.rules = [
|
|
111
|
-
...config.rules,
|
|
112
|
-
...account.rules.map((rule) => ({ ...rule, source: "account" })),
|
|
113
|
-
];
|
|
114
|
-
filled.push("rules");
|
|
115
|
-
}
|
|
116
|
-
return { config: out, filled };
|
|
117
|
-
}
|
|
118
|
-
//# sourceMappingURL=cloud-settings.js.map
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { type ReviewReport, type Severity, type Verification } from "@open-cr-agent/core";
|
|
2
|
-
import { type CloudDeps } from "../cloud.js";
|
|
3
|
-
import type { SharedFinding } from "./cloud-findings.js";
|
|
4
|
-
export type ReviewSource = "local" | "github" | "gitlab";
|
|
5
|
-
export type ReviewerCounts = {
|
|
6
|
-
tasks: number;
|
|
7
|
-
failedTasks: number;
|
|
8
|
-
findings: Record<Severity, number>;
|
|
9
|
-
costUsd: number;
|
|
10
|
-
fixed: number;
|
|
11
|
-
dismissed: number;
|
|
12
|
-
};
|
|
13
|
-
export type ReviewUpload = {
|
|
14
|
-
runId: string;
|
|
15
|
-
repoHash: string;
|
|
16
|
-
source: ReviewSource;
|
|
17
|
-
tier: string;
|
|
18
|
-
verdict: string;
|
|
19
|
-
complete: boolean;
|
|
20
|
-
findings: {
|
|
21
|
-
critical: number;
|
|
22
|
-
warning: number;
|
|
23
|
-
suggestion: number;
|
|
24
|
-
};
|
|
25
|
-
files: {
|
|
26
|
-
reviewed: number;
|
|
27
|
-
notReviewed: number;
|
|
28
|
-
};
|
|
29
|
-
tasks: {
|
|
30
|
-
completed: number;
|
|
31
|
-
failed: number;
|
|
32
|
-
};
|
|
33
|
-
usage: {
|
|
34
|
-
inputTokens: number;
|
|
35
|
-
outputTokens: number;
|
|
36
|
-
costUsd: number;
|
|
37
|
-
};
|
|
38
|
-
durationMs: number;
|
|
39
|
-
ocraVersion: string;
|
|
40
|
-
reviewers?: Record<string, ReviewerCounts>;
|
|
41
|
-
verification?: Record<Verification, number>;
|
|
42
|
-
outcomes?: {
|
|
43
|
-
fixed: number;
|
|
44
|
-
dismissed: number;
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
export declare function uploadOf(report: ReviewReport, source: ReviewSource, repoHash: string, durationMs: number): ReviewUpload;
|
|
48
|
-
/** The repository's hash, salted with the account's salt when given, else this machine's. */
|
|
49
|
-
export declare function repoHash(root: string, credentialsPath: string, accountSalt?: string): Promise<string>;
|
|
50
|
-
/** Whether this run talks to ocra Cloud at all: signed in, not turned off. */
|
|
51
|
-
export declare function cloudEnabled(deps: CloudDeps): Promise<boolean>;
|
|
52
|
-
/**
|
|
53
|
-
* Sends the counts, and the findings when given; answers how many findings
|
|
54
|
-
* the server kept, or undefined when it took nothing. A failure is a
|
|
55
|
-
* warning, never a failed review.
|
|
56
|
-
*/
|
|
57
|
-
export declare function uploadReview(upload: ReviewUpload, deps: CloudDeps, warn: (message: string) => void, findings?: readonly SharedFinding[]): Promise<{
|
|
58
|
-
findings: number;
|
|
59
|
-
} | undefined>;
|
|
60
|
-
//# sourceMappingURL=cloud-upload.d.ts.map
|
package/dist/review/command.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { type OcraPlugin } from "@open-cr-agent/core";
|
|
2
|
-
import type { CloudDeps } from "../cloud.js";
|
|
3
|
-
import type { NpmRunner } from "../plugins-command.js";
|
|
4
|
-
import type { ReviewArgs } from "./args.js";
|
|
5
|
-
import { type Output } from "./progress.js";
|
|
6
|
-
import type { RuntimeLoaders } from "./runtimes.js";
|
|
7
|
-
export declare const SESSIONS_DIR = ".ocra/sessions";
|
|
8
|
-
export declare const EXIT: {
|
|
9
|
-
readonly ok: 0;
|
|
10
|
-
readonly blocking: 1;
|
|
11
|
-
readonly error: 2;
|
|
12
|
-
readonly incomplete: 3;
|
|
13
|
-
readonly interrupted: 130;
|
|
14
|
-
};
|
|
15
|
-
export declare const BUILTIN_PLUGINS: readonly OcraPlugin[];
|
|
16
|
-
export interface ReviewDeps {
|
|
17
|
-
cwd: string;
|
|
18
|
-
env: Readonly<Record<string, string | undefined>>;
|
|
19
|
-
builtinPlugins: readonly OcraPlugin[];
|
|
20
|
-
runtimes: RuntimeLoaders;
|
|
21
|
-
writeFile(path: string, content: string): Promise<void>;
|
|
22
|
-
now(): number;
|
|
23
|
-
heartbeatMs: number;
|
|
24
|
-
fetch?: typeof fetch;
|
|
25
|
-
cloud?: CloudDeps;
|
|
26
|
-
npm?: NpmRunner;
|
|
27
|
-
onInterrupt?(handler: () => void): () => void;
|
|
28
|
-
}
|
|
29
|
-
export declare function reviewCommand(args: ReviewArgs, io: {
|
|
30
|
-
out: Output;
|
|
31
|
-
err: Output;
|
|
32
|
-
}, deps: ReviewDeps): Promise<number>;
|
|
33
|
-
//# sourceMappingURL=command.d.ts.map
|