evrex-mcp 0.9.1 → 0.10.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 +24 -0
- package/dist/account.js +24 -2
- package/dist/capture.js +35 -5
- package/dist/continuity.js +24 -2
- package/dist/hook.js +24 -2
- package/dist/import.js +42 -12
- package/dist/index.js +1534 -1164
- package/dist/pretool.js +24 -2
- package/dist/tickets.js +36 -6
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -64,6 +64,30 @@ re-rendered from the transcript and marked authoritative over the summary).
|
|
|
64
64
|
| `EVREX_API_BASE_URL` | no | Point at a self-hosted evrex backend. Defaults to the hosted one. |
|
|
65
65
|
| `ANTHROPIC_MODEL` | no | Defaults to `claude-opus-5`. |
|
|
66
66
|
|
|
67
|
+
## Hosted mode
|
|
68
|
+
|
|
69
|
+
The same tools over HTTPS, for agents that run in someone else's cloud and can only attach a remote MCP server.
|
|
70
|
+
That includes Claude Tag in Slack, Cursor cloud agents, the Copilot coding agent, Devin and CI.
|
|
71
|
+
Evrex runs it at `https://api.evrex.ai/mcp`. Mint a read-only token at https://app.evrex.ai/agents and give the agent:
|
|
72
|
+
|
|
73
|
+
- `Authorization: Bearer evx_…` (required)
|
|
74
|
+
- `X-Evrex-Repo: owner/name` (optional), or the full git remote URL for a repo not on github.com. This is the repo to
|
|
75
|
+
search when a tool call names none. Without it, a call searches every repo your team has indexed. A value that names
|
|
76
|
+
no repo is refused with a 400.
|
|
77
|
+
|
|
78
|
+
Where a config reads the token from the environment, keep it in `EVREX_MCP_TOKEN`, never `EVREX_TOKEN`: on a machine
|
|
79
|
+
that captures sessions, `EVREX_TOKEN` takes precedence over the enrolled capture credential, so a read-only agent
|
|
80
|
+
token there makes every capture upload fail.
|
|
81
|
+
|
|
82
|
+
To run your own copy:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
PORT=3100 EVREX_API_BASE_URL=https://api.evrex.ai npx -y evrex-mcp serve
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
It is stateless (POST `/mcp` only) and keeps no data. Each request's token makes that request's calls to the backend.
|
|
89
|
+
`EVREX_MCP_ALLOWED_ORIGINS` (comma-separated) replaces the default list of browser origins it admits.
|
|
90
|
+
|
|
67
91
|
## No API credits needed to query
|
|
68
92
|
|
|
69
93
|
The tools return the recorded context — constraints, rejected approaches, prior
|
package/dist/account.js
CHANGED
|
@@ -3,21 +3,42 @@
|
|
|
3
3
|
// src/account.ts
|
|
4
4
|
import { statSync, openSync, readSync, closeSync } from "node:fs";
|
|
5
5
|
|
|
6
|
+
// src/request-context.ts
|
|
7
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
|
+
var storage = new AsyncLocalStorage();
|
|
9
|
+
function currentRequest() {
|
|
10
|
+
return storage.getStore();
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
// src/client.ts
|
|
7
14
|
var DEFAULT_API_BASE_URL = "https://api.evrex.ai";
|
|
8
15
|
var API_BASE_URL = (process.env.EVREX_API_BASE_URL ?? process.env.EVREX_API_URL ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
9
16
|
var EVREX_TOKEN = process.env.EVREX_TOKEN ?? process.env.EVREX_API_TOKEN ?? null;
|
|
17
|
+
function token() {
|
|
18
|
+
return currentRequest()?.token ?? EVREX_TOKEN;
|
|
19
|
+
}
|
|
10
20
|
function headers() {
|
|
11
21
|
const base = { "Content-Type": "application/json" };
|
|
12
|
-
|
|
22
|
+
const credential = token();
|
|
23
|
+
if (credential) base.Authorization = `Bearer ${credential}`;
|
|
13
24
|
return base;
|
|
14
25
|
}
|
|
15
26
|
function describeFailure(method, path, status, statusText) {
|
|
16
27
|
if (status === 401 || status === 403) {
|
|
28
|
+
if (currentRequest()) {
|
|
29
|
+
return `${method} ${path} -> ${status}: the Evrex token this connection carries was rejected, or lacks the scope this needs. Mint a read token at https://app.evrex.ai/agents.`;
|
|
30
|
+
}
|
|
17
31
|
return EVREX_TOKEN ? `${method} ${path} -> ${status}: the EVREX_TOKEN this server was started with was rejected. It may be revoked or expired.` : `${method} ${path} -> ${status}: this evrex backend requires a credential, but no EVREX_TOKEN is set for this MCP server.`;
|
|
18
32
|
}
|
|
19
33
|
return `${method} ${path} -> ${status} ${statusText}`;
|
|
20
34
|
}
|
|
35
|
+
var EvrexApiError = class extends Error {
|
|
36
|
+
constructor(message, status) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.status = status;
|
|
39
|
+
this.name = "EvrexApiError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
21
42
|
async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
22
43
|
const res = await fetch(`${API_BASE_URL}${path}`, {
|
|
23
44
|
method,
|
|
@@ -25,7 +46,7 @@ async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
|
25
46
|
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
26
47
|
});
|
|
27
48
|
if (res.status === 404 && absentIsAnswer) return null;
|
|
28
|
-
if (!res.ok) throw new
|
|
49
|
+
if (!res.ok) throw new EvrexApiError(describeFailure(method, path, res.status, res.statusText), res.status);
|
|
29
50
|
return await res.json();
|
|
30
51
|
}
|
|
31
52
|
var get = (path) => request("GET", path);
|
|
@@ -34,6 +55,7 @@ var post = (path, body) => request("POST", path, { body });
|
|
|
34
55
|
var evrexApi = {
|
|
35
56
|
baseUrl: API_BASE_URL,
|
|
36
57
|
repos: () => get("/repos"),
|
|
58
|
+
me: () => get("/auth/me"),
|
|
37
59
|
commits: (repoPath) => get(`/commits?repoPath=${encodeURIComponent(repoPath)}`),
|
|
38
60
|
// Abbreviated shas resolve server-side, so a value pasted from `git log`
|
|
39
61
|
// works here (apps/backend/src/reads/reads.service.ts#resolveSha).
|
package/dist/capture.js
CHANGED
|
@@ -3368,18 +3368,39 @@ var init_src = __esm({
|
|
|
3368
3368
|
}
|
|
3369
3369
|
});
|
|
3370
3370
|
|
|
3371
|
+
// src/request-context.ts
|
|
3372
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3373
|
+
function currentRequest() {
|
|
3374
|
+
return storage.getStore();
|
|
3375
|
+
}
|
|
3376
|
+
var storage;
|
|
3377
|
+
var init_request_context = __esm({
|
|
3378
|
+
"src/request-context.ts"() {
|
|
3379
|
+
"use strict";
|
|
3380
|
+
storage = new AsyncLocalStorage();
|
|
3381
|
+
}
|
|
3382
|
+
});
|
|
3383
|
+
|
|
3371
3384
|
// src/client.ts
|
|
3372
3385
|
var client_exports = {};
|
|
3373
3386
|
__export(client_exports, {
|
|
3387
|
+
EvrexApiError: () => EvrexApiError,
|
|
3374
3388
|
evrexApi: () => evrexApi
|
|
3375
3389
|
});
|
|
3390
|
+
function token() {
|
|
3391
|
+
return currentRequest()?.token ?? EVREX_TOKEN;
|
|
3392
|
+
}
|
|
3376
3393
|
function headers() {
|
|
3377
3394
|
const base = { "Content-Type": "application/json" };
|
|
3378
|
-
|
|
3395
|
+
const credential = token();
|
|
3396
|
+
if (credential) base.Authorization = `Bearer ${credential}`;
|
|
3379
3397
|
return base;
|
|
3380
3398
|
}
|
|
3381
3399
|
function describeFailure(method, path, status, statusText) {
|
|
3382
3400
|
if (status === 401 || status === 403) {
|
|
3401
|
+
if (currentRequest()) {
|
|
3402
|
+
return `${method} ${path} -> ${status}: the Evrex token this connection carries was rejected, or lacks the scope this needs. Mint a read token at https://app.evrex.ai/agents.`;
|
|
3403
|
+
}
|
|
3383
3404
|
return EVREX_TOKEN ? `${method} ${path} -> ${status}: the EVREX_TOKEN this server was started with was rejected. It may be revoked or expired.` : `${method} ${path} -> ${status}: this evrex backend requires a credential, but no EVREX_TOKEN is set for this MCP server.`;
|
|
3384
3405
|
}
|
|
3385
3406
|
return `${method} ${path} -> ${status} ${statusText}`;
|
|
@@ -3391,22 +3412,31 @@ async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
|
3391
3412
|
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
3392
3413
|
});
|
|
3393
3414
|
if (res.status === 404 && absentIsAnswer) return null;
|
|
3394
|
-
if (!res.ok) throw new
|
|
3415
|
+
if (!res.ok) throw new EvrexApiError(describeFailure(method, path, res.status, res.statusText), res.status);
|
|
3395
3416
|
return await res.json();
|
|
3396
3417
|
}
|
|
3397
|
-
var DEFAULT_API_BASE_URL, API_BASE_URL, EVREX_TOKEN, get, getOrNull, post, evrexApi;
|
|
3418
|
+
var DEFAULT_API_BASE_URL, API_BASE_URL, EVREX_TOKEN, EvrexApiError, get, getOrNull, post, evrexApi;
|
|
3398
3419
|
var init_client = __esm({
|
|
3399
3420
|
"src/client.ts"() {
|
|
3400
3421
|
"use strict";
|
|
3422
|
+
init_request_context();
|
|
3401
3423
|
DEFAULT_API_BASE_URL = "https://api.evrex.ai";
|
|
3402
3424
|
API_BASE_URL = (process.env.EVREX_API_BASE_URL ?? process.env.EVREX_API_URL ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
3403
3425
|
EVREX_TOKEN = process.env.EVREX_TOKEN ?? process.env.EVREX_API_TOKEN ?? null;
|
|
3426
|
+
EvrexApiError = class extends Error {
|
|
3427
|
+
constructor(message, status) {
|
|
3428
|
+
super(message);
|
|
3429
|
+
this.status = status;
|
|
3430
|
+
this.name = "EvrexApiError";
|
|
3431
|
+
}
|
|
3432
|
+
};
|
|
3404
3433
|
get = (path) => request("GET", path);
|
|
3405
3434
|
getOrNull = (path) => request("GET", path, { absentIsAnswer: true });
|
|
3406
3435
|
post = (path, body) => request("POST", path, { body });
|
|
3407
3436
|
evrexApi = {
|
|
3408
3437
|
baseUrl: API_BASE_URL,
|
|
3409
3438
|
repos: () => get("/repos"),
|
|
3439
|
+
me: () => get("/auth/me"),
|
|
3410
3440
|
commits: (repoPath) => get(`/commits?repoPath=${encodeURIComponent(repoPath)}`),
|
|
3411
3441
|
// Abbreviated shas resolve server-side, so a value pasted from `git log`
|
|
3412
3442
|
// works here (apps/backend/src/reads/reads.service.ts#resolveSha).
|
|
@@ -3862,8 +3892,8 @@ async function main() {
|
|
|
3862
3892
|
return;
|
|
3863
3893
|
}
|
|
3864
3894
|
const { evrexApi: evrexApi2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
3865
|
-
let
|
|
3866
|
-
const credential = () =>
|
|
3895
|
+
let token2;
|
|
3896
|
+
const credential = () => token2 ??= captureToken(process.env, async () => {
|
|
3867
3897
|
const { CredentialStore: CredentialStore2 } = await Promise.resolve().then(() => (init_credential_store(), credential_store_exports));
|
|
3868
3898
|
return new CredentialStore2().retrieve();
|
|
3869
3899
|
});
|
package/dist/continuity.js
CHANGED
|
@@ -5,21 +5,42 @@ import { execFileSync as execFileSync2 } from "node:child_process";
|
|
|
5
5
|
import { closeSync, openSync, readSync, statSync } from "node:fs";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
|
|
8
|
+
// src/request-context.ts
|
|
9
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
10
|
+
var storage = new AsyncLocalStorage();
|
|
11
|
+
function currentRequest() {
|
|
12
|
+
return storage.getStore();
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
// src/client.ts
|
|
9
16
|
var DEFAULT_API_BASE_URL = "https://api.evrex.ai";
|
|
10
17
|
var API_BASE_URL = (process.env.EVREX_API_BASE_URL ?? process.env.EVREX_API_URL ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
11
18
|
var EVREX_TOKEN = process.env.EVREX_TOKEN ?? process.env.EVREX_API_TOKEN ?? null;
|
|
19
|
+
function token() {
|
|
20
|
+
return currentRequest()?.token ?? EVREX_TOKEN;
|
|
21
|
+
}
|
|
12
22
|
function headers() {
|
|
13
23
|
const base = { "Content-Type": "application/json" };
|
|
14
|
-
|
|
24
|
+
const credential = token();
|
|
25
|
+
if (credential) base.Authorization = `Bearer ${credential}`;
|
|
15
26
|
return base;
|
|
16
27
|
}
|
|
17
28
|
function describeFailure(method, path, status, statusText) {
|
|
18
29
|
if (status === 401 || status === 403) {
|
|
30
|
+
if (currentRequest()) {
|
|
31
|
+
return `${method} ${path} -> ${status}: the Evrex token this connection carries was rejected, or lacks the scope this needs. Mint a read token at https://app.evrex.ai/agents.`;
|
|
32
|
+
}
|
|
19
33
|
return EVREX_TOKEN ? `${method} ${path} -> ${status}: the EVREX_TOKEN this server was started with was rejected. It may be revoked or expired.` : `${method} ${path} -> ${status}: this evrex backend requires a credential, but no EVREX_TOKEN is set for this MCP server.`;
|
|
20
34
|
}
|
|
21
35
|
return `${method} ${path} -> ${status} ${statusText}`;
|
|
22
36
|
}
|
|
37
|
+
var EvrexApiError = class extends Error {
|
|
38
|
+
constructor(message, status) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.status = status;
|
|
41
|
+
this.name = "EvrexApiError";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
23
44
|
async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
24
45
|
const res = await fetch(`${API_BASE_URL}${path}`, {
|
|
25
46
|
method,
|
|
@@ -27,7 +48,7 @@ async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
|
27
48
|
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
28
49
|
});
|
|
29
50
|
if (res.status === 404 && absentIsAnswer) return null;
|
|
30
|
-
if (!res.ok) throw new
|
|
51
|
+
if (!res.ok) throw new EvrexApiError(describeFailure(method, path, res.status, res.statusText), res.status);
|
|
31
52
|
return await res.json();
|
|
32
53
|
}
|
|
33
54
|
var get = (path) => request("GET", path);
|
|
@@ -36,6 +57,7 @@ var post = (path, body) => request("POST", path, { body });
|
|
|
36
57
|
var evrexApi = {
|
|
37
58
|
baseUrl: API_BASE_URL,
|
|
38
59
|
repos: () => get("/repos"),
|
|
60
|
+
me: () => get("/auth/me"),
|
|
39
61
|
commits: (repoPath) => get(`/commits?repoPath=${encodeURIComponent(repoPath)}`),
|
|
40
62
|
// Abbreviated shas resolve server-side, so a value pasted from `git log`
|
|
41
63
|
// works here (apps/backend/src/reads/reads.service.ts#resolveSha).
|
package/dist/hook.js
CHANGED
|
@@ -3,21 +3,42 @@
|
|
|
3
3
|
// src/hook.ts
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
|
|
6
|
+
// src/request-context.ts
|
|
7
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
|
+
var storage = new AsyncLocalStorage();
|
|
9
|
+
function currentRequest() {
|
|
10
|
+
return storage.getStore();
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
// src/client.ts
|
|
7
14
|
var DEFAULT_API_BASE_URL = "https://api.evrex.ai";
|
|
8
15
|
var API_BASE_URL = (process.env.EVREX_API_BASE_URL ?? process.env.EVREX_API_URL ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
9
16
|
var EVREX_TOKEN = process.env.EVREX_TOKEN ?? process.env.EVREX_API_TOKEN ?? null;
|
|
17
|
+
function token() {
|
|
18
|
+
return currentRequest()?.token ?? EVREX_TOKEN;
|
|
19
|
+
}
|
|
10
20
|
function headers() {
|
|
11
21
|
const base = { "Content-Type": "application/json" };
|
|
12
|
-
|
|
22
|
+
const credential = token();
|
|
23
|
+
if (credential) base.Authorization = `Bearer ${credential}`;
|
|
13
24
|
return base;
|
|
14
25
|
}
|
|
15
26
|
function describeFailure(method, path, status, statusText) {
|
|
16
27
|
if (status === 401 || status === 403) {
|
|
28
|
+
if (currentRequest()) {
|
|
29
|
+
return `${method} ${path} -> ${status}: the Evrex token this connection carries was rejected, or lacks the scope this needs. Mint a read token at https://app.evrex.ai/agents.`;
|
|
30
|
+
}
|
|
17
31
|
return EVREX_TOKEN ? `${method} ${path} -> ${status}: the EVREX_TOKEN this server was started with was rejected. It may be revoked or expired.` : `${method} ${path} -> ${status}: this evrex backend requires a credential, but no EVREX_TOKEN is set for this MCP server.`;
|
|
18
32
|
}
|
|
19
33
|
return `${method} ${path} -> ${status} ${statusText}`;
|
|
20
34
|
}
|
|
35
|
+
var EvrexApiError = class extends Error {
|
|
36
|
+
constructor(message, status) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.status = status;
|
|
39
|
+
this.name = "EvrexApiError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
21
42
|
async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
22
43
|
const res = await fetch(`${API_BASE_URL}${path}`, {
|
|
23
44
|
method,
|
|
@@ -25,7 +46,7 @@ async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
|
25
46
|
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
26
47
|
});
|
|
27
48
|
if (res.status === 404 && absentIsAnswer) return null;
|
|
28
|
-
if (!res.ok) throw new
|
|
49
|
+
if (!res.ok) throw new EvrexApiError(describeFailure(method, path, res.status, res.statusText), res.status);
|
|
29
50
|
return await res.json();
|
|
30
51
|
}
|
|
31
52
|
var get = (path) => request("GET", path);
|
|
@@ -34,6 +55,7 @@ var post = (path, body) => request("POST", path, { body });
|
|
|
34
55
|
var evrexApi = {
|
|
35
56
|
baseUrl: API_BASE_URL,
|
|
36
57
|
repos: () => get("/repos"),
|
|
58
|
+
me: () => get("/auth/me"),
|
|
37
59
|
commits: (repoPath) => get(`/commits?repoPath=${encodeURIComponent(repoPath)}`),
|
|
38
60
|
// Abbreviated shas resolve server-side, so a value pasted from `git log`
|
|
39
61
|
// works here (apps/backend/src/reads/reads.service.ts#resolveSha).
|
package/dist/import.js
CHANGED
|
@@ -3368,18 +3368,39 @@ var init_src = __esm({
|
|
|
3368
3368
|
}
|
|
3369
3369
|
});
|
|
3370
3370
|
|
|
3371
|
+
// src/request-context.ts
|
|
3372
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3373
|
+
function currentRequest() {
|
|
3374
|
+
return storage.getStore();
|
|
3375
|
+
}
|
|
3376
|
+
var storage;
|
|
3377
|
+
var init_request_context = __esm({
|
|
3378
|
+
"src/request-context.ts"() {
|
|
3379
|
+
"use strict";
|
|
3380
|
+
storage = new AsyncLocalStorage();
|
|
3381
|
+
}
|
|
3382
|
+
});
|
|
3383
|
+
|
|
3371
3384
|
// src/client.ts
|
|
3372
3385
|
var client_exports = {};
|
|
3373
3386
|
__export(client_exports, {
|
|
3387
|
+
EvrexApiError: () => EvrexApiError,
|
|
3374
3388
|
evrexApi: () => evrexApi
|
|
3375
3389
|
});
|
|
3390
|
+
function token() {
|
|
3391
|
+
return currentRequest()?.token ?? EVREX_TOKEN;
|
|
3392
|
+
}
|
|
3376
3393
|
function headers() {
|
|
3377
3394
|
const base = { "Content-Type": "application/json" };
|
|
3378
|
-
|
|
3395
|
+
const credential = token();
|
|
3396
|
+
if (credential) base.Authorization = `Bearer ${credential}`;
|
|
3379
3397
|
return base;
|
|
3380
3398
|
}
|
|
3381
3399
|
function describeFailure(method, path, status, statusText) {
|
|
3382
3400
|
if (status === 401 || status === 403) {
|
|
3401
|
+
if (currentRequest()) {
|
|
3402
|
+
return `${method} ${path} -> ${status}: the Evrex token this connection carries was rejected, or lacks the scope this needs. Mint a read token at https://app.evrex.ai/agents.`;
|
|
3403
|
+
}
|
|
3383
3404
|
return EVREX_TOKEN ? `${method} ${path} -> ${status}: the EVREX_TOKEN this server was started with was rejected. It may be revoked or expired.` : `${method} ${path} -> ${status}: this evrex backend requires a credential, but no EVREX_TOKEN is set for this MCP server.`;
|
|
3384
3405
|
}
|
|
3385
3406
|
return `${method} ${path} -> ${status} ${statusText}`;
|
|
@@ -3391,22 +3412,31 @@ async function request(method, path, { body, absentIsAnswer } = {}) {
|
|
|
3391
3412
|
...body === void 0 ? {} : { body: JSON.stringify(body) }
|
|
3392
3413
|
});
|
|
3393
3414
|
if (res.status === 404 && absentIsAnswer) return null;
|
|
3394
|
-
if (!res.ok) throw new
|
|
3415
|
+
if (!res.ok) throw new EvrexApiError(describeFailure(method, path, res.status, res.statusText), res.status);
|
|
3395
3416
|
return await res.json();
|
|
3396
3417
|
}
|
|
3397
|
-
var DEFAULT_API_BASE_URL, API_BASE_URL, EVREX_TOKEN, get, getOrNull, post, evrexApi;
|
|
3418
|
+
var DEFAULT_API_BASE_URL, API_BASE_URL, EVREX_TOKEN, EvrexApiError, get, getOrNull, post, evrexApi;
|
|
3398
3419
|
var init_client = __esm({
|
|
3399
3420
|
"src/client.ts"() {
|
|
3400
3421
|
"use strict";
|
|
3422
|
+
init_request_context();
|
|
3401
3423
|
DEFAULT_API_BASE_URL = "https://api.evrex.ai";
|
|
3402
3424
|
API_BASE_URL = (process.env.EVREX_API_BASE_URL ?? process.env.EVREX_API_URL ?? DEFAULT_API_BASE_URL).replace(/\/+$/, "");
|
|
3403
3425
|
EVREX_TOKEN = process.env.EVREX_TOKEN ?? process.env.EVREX_API_TOKEN ?? null;
|
|
3426
|
+
EvrexApiError = class extends Error {
|
|
3427
|
+
constructor(message, status) {
|
|
3428
|
+
super(message);
|
|
3429
|
+
this.status = status;
|
|
3430
|
+
this.name = "EvrexApiError";
|
|
3431
|
+
}
|
|
3432
|
+
};
|
|
3404
3433
|
get = (path) => request("GET", path);
|
|
3405
3434
|
getOrNull = (path) => request("GET", path, { absentIsAnswer: true });
|
|
3406
3435
|
post = (path, body) => request("POST", path, { body });
|
|
3407
3436
|
evrexApi = {
|
|
3408
3437
|
baseUrl: API_BASE_URL,
|
|
3409
3438
|
repos: () => get("/repos"),
|
|
3439
|
+
me: () => get("/auth/me"),
|
|
3410
3440
|
commits: (repoPath) => get(`/commits?repoPath=${encodeURIComponent(repoPath)}`),
|
|
3411
3441
|
// Abbreviated shas resolve server-side, so a value pasted from `git log`
|
|
3412
3442
|
// works here (apps/backend/src/reads/reads.service.ts#resolveSha).
|
|
@@ -3780,8 +3810,8 @@ async function durability(target, argv) {
|
|
|
3780
3810
|
};
|
|
3781
3811
|
const minAgeDays = flag("--min-age-days", 30);
|
|
3782
3812
|
const limit = flag("--limit", 300);
|
|
3783
|
-
const
|
|
3784
|
-
if (!
|
|
3813
|
+
const token2 = process.env.EVREX_TOKEN ?? await new (await Promise.resolve().then(() => (init_credential_store(), credential_store_exports))).CredentialStore().retrieve().catch(() => null);
|
|
3814
|
+
if (!token2) {
|
|
3785
3815
|
console.error("evrex: this machine is not enrolled.\n Run `npx -y evrex-mcp enrol` first, or set EVREX_TOKEN.");
|
|
3786
3816
|
process.exit(1);
|
|
3787
3817
|
}
|
|
@@ -3798,7 +3828,7 @@ async function durability(target, argv) {
|
|
|
3798
3828
|
}
|
|
3799
3829
|
const res = await fetch(`${evrexApi2.baseUrl}/ingest/commits/durability`, {
|
|
3800
3830
|
method: "POST",
|
|
3801
|
-
headers: { "content-type": "application/json", authorization: `Bearer ${
|
|
3831
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${token2}` },
|
|
3802
3832
|
body: JSON.stringify({ repoId, measurements })
|
|
3803
3833
|
});
|
|
3804
3834
|
if (!res.ok) {
|
|
@@ -3814,8 +3844,8 @@ async function parents(target) {
|
|
|
3814
3844
|
const { deriveRepoId: deriveRepoId2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
3815
3845
|
const { execFileSync: execFileSync5 } = await import("node:child_process");
|
|
3816
3846
|
const { evrexApi: evrexApi2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
3817
|
-
const
|
|
3818
|
-
if (!
|
|
3847
|
+
const token2 = process.env.EVREX_TOKEN ?? await new (await Promise.resolve().then(() => (init_credential_store(), credential_store_exports))).CredentialStore().retrieve().catch(() => null);
|
|
3848
|
+
if (!token2) {
|
|
3819
3849
|
console.error("evrex: this machine is not enrolled.\n Run `npx -y evrex-mcp enrol` first, or set EVREX_TOKEN.");
|
|
3820
3850
|
process.exit(1);
|
|
3821
3851
|
}
|
|
@@ -3830,7 +3860,7 @@ async function parents(target) {
|
|
|
3830
3860
|
for (let i = 0; i < rows.length; i += 500) {
|
|
3831
3861
|
const res = await fetch(`${evrexApi2.baseUrl}/ingest/commits/parents`, {
|
|
3832
3862
|
method: "POST",
|
|
3833
|
-
headers: { "content-type": "application/json", authorization: `Bearer ${
|
|
3863
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${token2}` },
|
|
3834
3864
|
body: JSON.stringify({ repoId, commits: rows.slice(i, i + 500) })
|
|
3835
3865
|
});
|
|
3836
3866
|
if (!res.ok) {
|
|
@@ -3855,8 +3885,8 @@ async function main() {
|
|
|
3855
3885
|
const target = resolve(process.argv[3] ?? process.cwd());
|
|
3856
3886
|
const { evrexApi: evrexApi2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
3857
3887
|
const { CredentialStore: CredentialStore2 } = await Promise.resolve().then(() => (init_credential_store(), credential_store_exports));
|
|
3858
|
-
const
|
|
3859
|
-
if (!
|
|
3888
|
+
const token2 = process.env.EVREX_TOKEN ?? await new CredentialStore2().retrieve().catch(() => null);
|
|
3889
|
+
if (!token2) {
|
|
3860
3890
|
console.error(
|
|
3861
3891
|
"evrex: this machine is not enrolled.\n Run `npx -y evrex-mcp enrol` first, or set EVREX_TOKEN."
|
|
3862
3892
|
);
|
|
@@ -3875,7 +3905,7 @@ async function main() {
|
|
|
3875
3905
|
method: "POST",
|
|
3876
3906
|
headers: {
|
|
3877
3907
|
"content-type": "application/json",
|
|
3878
|
-
authorization: `Bearer ${
|
|
3908
|
+
authorization: `Bearer ${token2}`
|
|
3879
3909
|
},
|
|
3880
3910
|
body: JSON.stringify(body)
|
|
3881
3911
|
});
|