fest-gateway 0.5.2 → 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/README.md +2 -0
- package/dist/cli/claude.js +10 -4
- package/dist/cli/claude.js.map +1 -1
- package/dist/cli/codex.js +8 -4
- package/dist/cli/codex.js.map +1 -1
- package/dist/cli/copilot.js +11 -5
- package/dist/cli/copilot.js.map +1 -1
- package/dist/cli/tags.js +258 -0
- package/dist/cli/tags.js.map +1 -0
- package/dist/server/api/live.js +1 -0
- package/dist/server/api/live.js.map +1 -1
- package/dist/server/api/routes.js +23 -2
- package/dist/server/api/routes.js.map +1 -1
- package/dist/server/auth/posture.js +39 -10
- package/dist/server/auth/posture.js.map +1 -1
- package/dist/server/bin/fest.js +29 -12
- package/dist/server/bin/fest.js.map +1 -1
- package/dist/server/pipeline/dispatch.js +1 -0
- package/dist/server/pipeline/dispatch.js.map +1 -1
- package/dist/server/pipeline/passthrough.js +1 -0
- package/dist/server/pipeline/passthrough.js.map +1 -1
- package/dist/server/pipeline/record.js +1 -0
- package/dist/server/pipeline/record.js.map +1 -1
- package/dist/server/store/migrations/007-tags.sql +94 -0
- package/dist/server/store/queries.js +112 -6
- package/dist/server/store/queries.js.map +1 -1
- package/dist/server/store/seed.js +17 -0
- package/dist/server/store/seed.js.map +1 -1
- package/dist/server/store/write.js +9 -2
- package/dist/server/store/write.js.map +1 -1
- package/dist/shared/tags.js +155 -0
- package/dist/shared/tags.js.map +1 -0
- package/dist/web/dist/assets/index-AJc39GYv.js +56 -0
- package/dist/web/dist/assets/index-AJc39GYv.js.map +1 -0
- package/dist/web/dist/assets/index-BgK6vcz0.css +2 -0
- package/dist/web/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/dist/assets/index-C7n3_lX2.css +0 -2
- package/dist/web/dist/assets/index-DJb4NfM5.js +0 -56
- package/dist/web/dist/assets/index-DJb4NfM5.js.map +0 -1
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ fest logout # forget the local token (does not revoke it server-side)
|
|
|
53
53
|
fest claude gw # force org credentials + the gateway's extra models
|
|
54
54
|
fest codex # OpenAI Codex CLI, on its own ChatGPT login or API key
|
|
55
55
|
fest copilot # GitHub Copilot CLI, on its own Copilot login
|
|
56
|
+
fest tags set team=platform # label usage from this directory down (-g: everywhere)
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
Codex and Copilot CLI are metered into the same dashboard, labelled by client.
|
|
@@ -396,6 +397,7 @@ inside it — read the relevant one before working there.
|
|
|
396
397
|
| [PRICING.md](docs/PRICING.md) | where rates come from, and spend vs. value |
|
|
397
398
|
| [CODEX.md](docs/CODEX.md) | Codex CLI through the `/openai` and `/chatgpt` mounts |
|
|
398
399
|
| [COPILOT.md](docs/COPILOT.md) | Copilot CLI on its own login through `/copilot`, what happens to the GitHub token, and BYOK |
|
|
400
|
+
| [TAGS.md](docs/TAGS.md) | tagging usage by team, project or anything else, and filtering the dashboard by it |
|
|
399
401
|
| [POSTURES.md](docs/POSTURES.md) | subscription vs. key posture |
|
|
400
402
|
| [CANARY.md](docs/CANARY.md) | the version-upgrade gate |
|
|
401
403
|
| [PHASE0.md](docs/PHASE0.md) · [PHASE0-RESULTS.md](docs/PHASE0-RESULTS.md) | the gating experiment, and what it found |
|
package/dist/cli/claude.js
CHANGED
|
@@ -26,6 +26,7 @@ import { join } from "node:path";
|
|
|
26
26
|
import { DEMOTION_VARS } from "../shared/demotion-vars.js";
|
|
27
27
|
import { BASE_MODELS } from "../shared/base-models.js";
|
|
28
28
|
import { readCliConfig } from "./config.js";
|
|
29
|
+
import { describeTags, sessionTags, tagSuffix } from "./tags.js";
|
|
29
30
|
/**
|
|
30
31
|
* Pure, so it's testable without spawning a real `claude` binary.
|
|
31
32
|
*
|
|
@@ -36,13 +37,16 @@ export function buildClaudeEnv(base, cfg, posture = "subscription") {
|
|
|
36
37
|
const env = { ...base };
|
|
37
38
|
for (const v of DEMOTION_VARS)
|
|
38
39
|
delete env[v];
|
|
40
|
+
// In the path, not ANTHROPIC_CUSTOM_HEADERS: a developer's own settings may
|
|
41
|
+
// already set that variable, and one carrier for every client is simpler.
|
|
42
|
+
const tags = tagSuffix(cfg.tags ?? {});
|
|
39
43
|
if (posture === "key") {
|
|
40
|
-
env["ANTHROPIC_BASE_URL"] = cfg.serverUrl
|
|
44
|
+
env["ANTHROPIC_BASE_URL"] = `${cfg.serverUrl}${tags}`;
|
|
41
45
|
// Set after the strip, never by exempting it from the strip list.
|
|
42
46
|
env["ANTHROPIC_AUTH_TOKEN"] = cfg.identityToken;
|
|
43
47
|
}
|
|
44
48
|
else {
|
|
45
|
-
env["ANTHROPIC_BASE_URL"] = `${cfg.serverUrl}/t/${cfg.identityToken}`;
|
|
49
|
+
env["ANTHROPIC_BASE_URL"] = `${cfg.serverUrl}/t/${cfg.identityToken}${tags}`;
|
|
46
50
|
}
|
|
47
51
|
return env;
|
|
48
52
|
}
|
|
@@ -266,11 +270,13 @@ export function postureWarnings(posture, env, triggers) {
|
|
|
266
270
|
}
|
|
267
271
|
return warnings;
|
|
268
272
|
}
|
|
269
|
-
export async function runClaude(argv, requested = "auto") {
|
|
273
|
+
export async function runClaude(argv, requested = "auto", tagFlags = []) {
|
|
270
274
|
const cfg = await readCliConfig();
|
|
271
275
|
if (cfg === null) {
|
|
272
276
|
throw new Error("not logged in. Run `fest login` first.");
|
|
273
277
|
}
|
|
278
|
+
const tags = await sessionTags(tagFlags);
|
|
279
|
+
note(describeTags(tags));
|
|
274
280
|
const login = requested === "auto" ? detectSubscriptionLogin() : null;
|
|
275
281
|
const posture = requested === "auto" ? (login.ok ? "subscription" : "key") : requested;
|
|
276
282
|
// Who pays, every time — not only on `gw`. Auto-detection changes the answer
|
|
@@ -302,7 +308,7 @@ export async function runClaude(argv, requested = "auto") {
|
|
|
302
308
|
note(verdict.message);
|
|
303
309
|
}
|
|
304
310
|
}
|
|
305
|
-
const env = buildClaudeEnv(process.env, cfg, posture);
|
|
311
|
+
const env = buildClaudeEnv(process.env, { ...cfg, tags }, posture);
|
|
306
312
|
const child = spawn("claude", argv, { stdio: "inherit", env });
|
|
307
313
|
const code = await new Promise((resolve, reject) => {
|
|
308
314
|
child.on("error", (err) => {
|
package/dist/cli/claude.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../cli/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../cli/claude.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/codex.js
CHANGED
|
@@ -25,6 +25,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
25
25
|
import { homedir } from "node:os";
|
|
26
26
|
import { join } from "node:path";
|
|
27
27
|
import { readCliConfig } from "./config.js";
|
|
28
|
+
import { describeTags, sessionTags, tagSuffix } from "./tags.js";
|
|
28
29
|
/**
|
|
29
30
|
* The child-only variable `env_http_headers` reads the token from. Not
|
|
30
31
|
* `FEST_TOKEN`: that one means "use this instead of ~/.fest" to the fest CLI
|
|
@@ -64,6 +65,7 @@ const toml = (s) => JSON.stringify(s);
|
|
|
64
65
|
* `codex`, `codex exec` and `codex resume` alike) and the child environment.
|
|
65
66
|
*/
|
|
66
67
|
export function buildCodexInvocation(base, cfg, mode) {
|
|
68
|
+
const server = `${cfg.serverUrl}${tagSuffix(cfg.tags ?? {})}`;
|
|
67
69
|
const p = "model_providers.fest";
|
|
68
70
|
const args = [
|
|
69
71
|
"-c", `model_provider=${toml("fest")}`,
|
|
@@ -74,20 +76,22 @@ export function buildCodexInvocation(base, cfg, mode) {
|
|
|
74
76
|
];
|
|
75
77
|
const hasEnvKey = (base["OPENAI_API_KEY"] ?? "") !== "";
|
|
76
78
|
if (mode === "chatgpt") {
|
|
77
|
-
args.push("-c", `${p}.base_url=${toml(`${
|
|
79
|
+
args.push("-c", `${p}.base_url=${toml(`${server}/chatgpt/backend-api/codex`)}`);
|
|
78
80
|
args.push("-c", `${p}.requires_openai_auth=true`);
|
|
79
81
|
}
|
|
80
82
|
else {
|
|
81
|
-
args.push("-c", `${p}.base_url=${toml(`${
|
|
83
|
+
args.push("-c", `${p}.base_url=${toml(`${server}/openai/v1`)}`);
|
|
82
84
|
args.push("-c", hasEnvKey ? `${p}.env_key=${toml("OPENAI_API_KEY")}` : `${p}.requires_openai_auth=true`);
|
|
83
85
|
}
|
|
84
86
|
return { args, env: { ...base, [TOKEN_ENV]: cfg.identityToken } };
|
|
85
87
|
}
|
|
86
88
|
const note = (s) => void process.stderr.write(`fest codex: ${s}\n`);
|
|
87
|
-
export async function runCodex(argv, requested = "auto") {
|
|
89
|
+
export async function runCodex(argv, requested = "auto", tagFlags = []) {
|
|
88
90
|
const cfg = await readCliConfig();
|
|
89
91
|
if (cfg === null)
|
|
90
92
|
throw new Error("not logged in. Run `fest login` first.");
|
|
93
|
+
const tags = await sessionTags(tagFlags);
|
|
94
|
+
note(describeTags(tags));
|
|
91
95
|
const detected = requested === "auto" ? detectCodexMode(process.env) : null;
|
|
92
96
|
const mode = requested === "auto" ? detected.mode : requested;
|
|
93
97
|
// Who pays, every time, as `fest claude` does.
|
|
@@ -97,7 +101,7 @@ export async function runCodex(argv, requested = "auto") {
|
|
|
97
101
|
note("API key forced — the key's owner pays.");
|
|
98
102
|
else
|
|
99
103
|
note(`API key (${detected.detail}) — the key's owner pays.`);
|
|
100
|
-
const { args, env } = buildCodexInvocation(process.env, cfg, mode);
|
|
104
|
+
const { args, env } = buildCodexInvocation(process.env, { ...cfg, tags }, mode);
|
|
101
105
|
const child = spawn("codex", [...args, ...argv], { stdio: "inherit", env });
|
|
102
106
|
const code = await new Promise((resolve, reject) => {
|
|
103
107
|
child.on("error", (err) => {
|
package/dist/cli/codex.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../cli/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../cli/codex.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/copilot.js
CHANGED
|
@@ -32,6 +32,7 @@ import { homedir } from "node:os";
|
|
|
32
32
|
import { join } from "node:path";
|
|
33
33
|
import { BASE_MODELS } from "../shared/base-models.js";
|
|
34
34
|
import { readCliConfig } from "./config.js";
|
|
35
|
+
import { describeTags, sessionTags, tagSuffix } from "./tags.js";
|
|
35
36
|
/**
|
|
36
37
|
* The plan in a Copilot API host, or null for a host the mount cannot relay to
|
|
37
38
|
* (a GHE.com data-residency tenant, say).
|
|
@@ -92,6 +93,9 @@ export function userCacheCandidates(env, home, platform) {
|
|
|
92
93
|
*/
|
|
93
94
|
export function buildCopilotEnv(base, cfg, mode) {
|
|
94
95
|
const env = { ...base };
|
|
96
|
+
// In the path for every mode: on its own login Copilot sends no custom
|
|
97
|
+
// headers, and one carrier is simpler than two.
|
|
98
|
+
const tags = tagSuffix(cfg.tags ?? {});
|
|
95
99
|
// Start from a clean provider: an inherited COPILOT_PROVIDER_BEARER_TOKEN
|
|
96
100
|
// silently takes precedence over the API key set below, and an inherited
|
|
97
101
|
// base URL or type would point the session somewhere else entirely. In
|
|
@@ -108,7 +112,7 @@ export function buildCopilotEnv(base, cfg, mode) {
|
|
|
108
112
|
if (mode === "subscription") {
|
|
109
113
|
if (cfg.plan === undefined)
|
|
110
114
|
throw new Error("subscription mode needs the Copilot plan.");
|
|
111
|
-
env["COPILOT_API_URL"] = `${cfg.serverUrl}/t/${cfg.identityToken}/copilot/${cfg.plan}`;
|
|
115
|
+
env["COPILOT_API_URL"] = `${cfg.serverUrl}/t/${cfg.identityToken}${tags}/copilot/${cfg.plan}`;
|
|
112
116
|
return env;
|
|
113
117
|
}
|
|
114
118
|
const headers = [`X-Fest-Client: copilot`];
|
|
@@ -121,13 +125,13 @@ export function buildCopilotEnv(base, cfg, mode) {
|
|
|
121
125
|
}
|
|
122
126
|
env["COPILOT_PROVIDER_TYPE"] = "openai";
|
|
123
127
|
env["COPILOT_PROVIDER_WIRE_API"] = "responses";
|
|
124
|
-
env["COPILOT_PROVIDER_BASE_URL"] = `${cfg.serverUrl}/openai/v1`;
|
|
128
|
+
env["COPILOT_PROVIDER_BASE_URL"] = `${cfg.serverUrl}${tags}/openai/v1`;
|
|
125
129
|
env["COPILOT_PROVIDER_API_KEY"] = key;
|
|
126
130
|
headers.push(`X-Fest-Token: ${cfg.identityToken}`);
|
|
127
131
|
}
|
|
128
132
|
else {
|
|
129
133
|
env["COPILOT_PROVIDER_TYPE"] = "anthropic";
|
|
130
|
-
env["COPILOT_PROVIDER_BASE_URL"] = cfg.serverUrl
|
|
134
|
+
env["COPILOT_PROVIDER_BASE_URL"] = `${cfg.serverUrl}${tags}`;
|
|
131
135
|
if (mode === "gw") {
|
|
132
136
|
env["COPILOT_PROVIDER_BEARER_TOKEN"] = cfg.identityToken;
|
|
133
137
|
}
|
|
@@ -195,12 +199,14 @@ async function detectPlan(env) {
|
|
|
195
199
|
throw new Error("could not tell which Copilot plan you are on. Run `copilot` once and sign in, " +
|
|
196
200
|
"or set FEST_COPILOT_PLAN=individual|business|enterprise.");
|
|
197
201
|
}
|
|
198
|
-
export async function runCopilot(argv, mode = "subscription") {
|
|
202
|
+
export async function runCopilot(argv, mode = "subscription", tagFlags = []) {
|
|
199
203
|
const cfg = await readCliConfig();
|
|
200
204
|
if (cfg === null)
|
|
201
205
|
throw new Error("not logged in. Run `fest login` first.");
|
|
206
|
+
const tags = await sessionTags(tagFlags);
|
|
207
|
+
note(describeTags(tags));
|
|
202
208
|
const plan = mode === "subscription" ? await detectPlan(process.env) : undefined;
|
|
203
|
-
const env = buildCopilotEnv(process.env, { ...cfg, plan }, mode);
|
|
209
|
+
const env = buildCopilotEnv(process.env, { ...cfg, plan, tags }, mode);
|
|
204
210
|
const args = copilotArgs(cfg.serverUrl, mode, argv);
|
|
205
211
|
if (mode === "subscription") {
|
|
206
212
|
note(`your Copilot ${plan} plan pays; your GitHub login is relayed to GitHub through Fest, never stored.`);
|
package/dist/cli/copilot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../cli/copilot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../cli/copilot.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/tags.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request tags on the developer's side: which tags a `fest claude|codex|copilot`
|
|
3
|
+
* session sends, and `fest tags` for the ones saved as defaults.
|
|
4
|
+
*
|
|
5
|
+
* Precedence, lowest first — a later layer overrides an earlier one per key,
|
|
6
|
+
* and an empty value (`project=`) removes the key:
|
|
7
|
+
*
|
|
8
|
+
* 1. `project=<git repo name>`, when inside a repo
|
|
9
|
+
* 2. global saved tags (`fest tags set -g team=platform`)
|
|
10
|
+
* 3. saved tags for the current directory and each directory above it,
|
|
11
|
+
* outermost first (`fest tags set team=data` in `~/work` applies to every
|
|
12
|
+
* repo under it; `~/work/fest` can override that)
|
|
13
|
+
* 4. `FEST_TAGS="team=platform,project=fest"`
|
|
14
|
+
* 5. `--tag key=value` on the command line
|
|
15
|
+
*
|
|
16
|
+
* Saving is per-directory by default because tags describe the WORK — which
|
|
17
|
+
* team, which project — and the directory is the closest thing a laptop has
|
|
18
|
+
* to that. `-g` is for the few that follow the developer everywhere.
|
|
19
|
+
*
|
|
20
|
+
* The result rides in the `~…` path segment of the base URL each command
|
|
21
|
+
* already builds (see `shared/tags.ts`), so one mechanism serves all three
|
|
22
|
+
* clients — including Copilot on its own login, which cannot send headers.
|
|
23
|
+
*
|
|
24
|
+
* Saved tags live in their own file rather than in `config.json`: `fest login`
|
|
25
|
+
* rewrites that file and `fest logout` deletes it, and neither should cost the
|
|
26
|
+
* developer their team.
|
|
27
|
+
*/
|
|
28
|
+
import { execFileSync } from "node:child_process";
|
|
29
|
+
import { realpathSync } from "node:fs";
|
|
30
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
31
|
+
import { homedir } from "node:os";
|
|
32
|
+
import { basename, join, sep } from "node:path";
|
|
33
|
+
import { CONFIG_DIR } from "./config.js";
|
|
34
|
+
import { MAX_TAG_VALUE_LENGTH, formatTags, parseTagPairs, tagPathSegment, tagsFromPairs, } from "../shared/tags.js";
|
|
35
|
+
export const TAGS_FILE = join(CONFIG_DIR, "tags.json");
|
|
36
|
+
/**
|
|
37
|
+
* Peel leading `--tag key=value` / `--tag=key=value` flags off a command's
|
|
38
|
+
* args. Leading only: everything after the first other argument belongs to
|
|
39
|
+
* the child (`fest claude --tag project=x --resume`), and Fest must never eat
|
|
40
|
+
* a flag the child was meant to see.
|
|
41
|
+
*/
|
|
42
|
+
export function peelTagFlags(argv) {
|
|
43
|
+
const tags = [];
|
|
44
|
+
let i = 0;
|
|
45
|
+
while (i < argv.length) {
|
|
46
|
+
const arg = argv[i];
|
|
47
|
+
if (arg === "--tag") {
|
|
48
|
+
const value = argv[i + 1];
|
|
49
|
+
if (value === undefined)
|
|
50
|
+
throw new Error("--tag needs a value, e.g. --tag project=fest");
|
|
51
|
+
tags.push(value);
|
|
52
|
+
i += 2;
|
|
53
|
+
}
|
|
54
|
+
else if (arg.startsWith("--tag=")) {
|
|
55
|
+
tags.push(arg.slice("--tag=".length));
|
|
56
|
+
i += 1;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { tags, rest: argv.slice(i) };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A repo name as a tag value: characters the tag format refuses become `-`.
|
|
66
|
+
* Null when nothing usable is left.
|
|
67
|
+
*/
|
|
68
|
+
export function repoTagValue(name) {
|
|
69
|
+
const cleaned = name
|
|
70
|
+
.replace(/[^A-Za-z0-9 ._:@-]/g, "-")
|
|
71
|
+
.trim()
|
|
72
|
+
.slice(0, MAX_TAG_VALUE_LENGTH);
|
|
73
|
+
return cleaned === "" ? null : cleaned;
|
|
74
|
+
}
|
|
75
|
+
/** The current git repo's directory name, or null outside a repo / without git. */
|
|
76
|
+
export function gitRepoName(cwd = process.cwd()) {
|
|
77
|
+
try {
|
|
78
|
+
const top = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
79
|
+
cwd,
|
|
80
|
+
encoding: "utf8",
|
|
81
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
82
|
+
}).trim();
|
|
83
|
+
return top === "" ? null : repoTagValue(basename(top));
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const EMPTY_SAVED = { global: {}, paths: {} };
|
|
90
|
+
/** Pure: the precedence chain above, given each layer's raw input. */
|
|
91
|
+
export function resolveTags(layers) {
|
|
92
|
+
const pairs = [];
|
|
93
|
+
if (layers.repo !== null)
|
|
94
|
+
pairs.push({ key: "project", value: layers.repo });
|
|
95
|
+
pairs.push(...toPairs(layers.saved.global));
|
|
96
|
+
for (const [, layer] of pathLayers(layers.saved, layers.cwd))
|
|
97
|
+
pairs.push(...toPairs(layer));
|
|
98
|
+
if (layers.env !== undefined)
|
|
99
|
+
pairs.push(...parseTagPairs(layers.env));
|
|
100
|
+
for (const flag of layers.flags) {
|
|
101
|
+
const parsed = parseTagPairs(flag);
|
|
102
|
+
if (parsed.length === 0)
|
|
103
|
+
throw new Error(`--tag ${flag}: expected key=value`);
|
|
104
|
+
pairs.push(...parsed);
|
|
105
|
+
}
|
|
106
|
+
return tagsFromPairs(pairs);
|
|
107
|
+
}
|
|
108
|
+
const toPairs = (layer) => Object.entries(layer).map(([key, value]) => ({ key, value }));
|
|
109
|
+
/** The saved directories that contain `cwd`, outermost first. */
|
|
110
|
+
export function pathLayers(saved, cwd) {
|
|
111
|
+
return Object.entries(saved.paths)
|
|
112
|
+
.filter(([dir]) => cwd === dir || cwd.startsWith(dir.endsWith(sep) ? dir : dir + sep))
|
|
113
|
+
.sort((a, b) => a[0].length - b[0].length);
|
|
114
|
+
}
|
|
115
|
+
/** Symlink-resolved, so `/tmp/x` and `/private/tmp/x` are one directory. */
|
|
116
|
+
export function canonicalDir(dir) {
|
|
117
|
+
try {
|
|
118
|
+
return realpathSync(dir);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return dir;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** A layer from the (hand-editable) file, re-validated; empty values kept. */
|
|
125
|
+
function readLayer(v) {
|
|
126
|
+
if (v === null || typeof v !== "object" || Array.isArray(v))
|
|
127
|
+
return {};
|
|
128
|
+
const out = {};
|
|
129
|
+
for (const [k, val] of Object.entries(v)) {
|
|
130
|
+
if (typeof val !== "string")
|
|
131
|
+
continue;
|
|
132
|
+
for (const p of parseTagPairs(`${encodeURIComponent(k)}=${encodeURIComponent(val)}`))
|
|
133
|
+
out[p.key] = p.value;
|
|
134
|
+
}
|
|
135
|
+
return out;
|
|
136
|
+
}
|
|
137
|
+
export async function readSavedTags() {
|
|
138
|
+
let raw;
|
|
139
|
+
try {
|
|
140
|
+
raw = await readFile(TAGS_FILE, "utf8");
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
if (err.code === "ENOENT")
|
|
144
|
+
return EMPTY_SAVED;
|
|
145
|
+
throw err;
|
|
146
|
+
}
|
|
147
|
+
const parsed = JSON.parse(raw);
|
|
148
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
149
|
+
return EMPTY_SAVED;
|
|
150
|
+
const obj = parsed;
|
|
151
|
+
// The first version of this file was a flat object of global tags.
|
|
152
|
+
if (!("global" in obj) && !("paths" in obj))
|
|
153
|
+
return { global: readLayer(obj), paths: {} };
|
|
154
|
+
const paths = {};
|
|
155
|
+
if (obj["paths"] !== null && typeof obj["paths"] === "object") {
|
|
156
|
+
for (const [dir, layer] of Object.entries(obj["paths"])) {
|
|
157
|
+
const l = readLayer(layer);
|
|
158
|
+
if (Object.keys(l).length > 0)
|
|
159
|
+
paths[dir] = l;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return { global: readLayer(obj["global"]), paths };
|
|
163
|
+
}
|
|
164
|
+
async function writeSavedTags(saved) {
|
|
165
|
+
await mkdir(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
166
|
+
await writeFile(TAGS_FILE, JSON.stringify(saved, null, 2) + "\n", { mode: 0o600 });
|
|
167
|
+
}
|
|
168
|
+
/** Everything a client command needs: the tags, already resolved. */
|
|
169
|
+
export async function sessionTags(flags, cwd = process.cwd()) {
|
|
170
|
+
return resolveTags({
|
|
171
|
+
repo: gitRepoName(cwd),
|
|
172
|
+
saved: await readSavedTags(),
|
|
173
|
+
cwd: canonicalDir(cwd),
|
|
174
|
+
env: process.env.FEST_TAGS,
|
|
175
|
+
flags,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/** `/~project=fest,team=platform`, or `""` — appended where a path may carry it. */
|
|
179
|
+
export function tagSuffix(tags) {
|
|
180
|
+
const seg = tagPathSegment(tags);
|
|
181
|
+
return seg === "" ? "" : `/${seg}`;
|
|
182
|
+
}
|
|
183
|
+
/** One stderr line, so the developer can see what their usage is filed under. */
|
|
184
|
+
export function describeTags(tags) {
|
|
185
|
+
const s = formatTags(tags).replaceAll(",", ", ");
|
|
186
|
+
return s === "" ? "no tags." : `tags ${decodeURIComponent(s)}.`;
|
|
187
|
+
}
|
|
188
|
+
/** `team=platform, project=(removed)` — a layer as the developer typed it. */
|
|
189
|
+
function showLayer(layer) {
|
|
190
|
+
const keys = Object.keys(layer).sort();
|
|
191
|
+
return keys.length === 0 ? "(none)" : keys.map((k) => `${k}=${layer[k] === "" ? "(removed)" : layer[k]}`).join(", ");
|
|
192
|
+
}
|
|
193
|
+
/** `~/work/fest` rather than `/Users/someone/work/fest`. */
|
|
194
|
+
function showDir(dir) {
|
|
195
|
+
const home = canonicalDir(homedir());
|
|
196
|
+
return dir === home ? "~" : dir.startsWith(home + sep) ? `~${dir.slice(home.length)}` : dir;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* `fest tags` saved layers that apply here, and the result
|
|
200
|
+
* `fest tags set [-g] k=v [k=v …]` save for this directory (or globally)
|
|
201
|
+
* `fest tags unset [-g] k [k …]` remove from this directory (or globally)
|
|
202
|
+
*/
|
|
203
|
+
export async function runTags(argv, opts = {}) {
|
|
204
|
+
const out = opts.out ?? ((s) => void process.stdout.write(`${s}\n`));
|
|
205
|
+
const cwd = canonicalDir(opts.cwd ?? process.cwd());
|
|
206
|
+
const global = argv.includes("-g") || argv.includes("--global");
|
|
207
|
+
const [sub, ...rest] = argv.filter((a) => a !== "-g" && a !== "--global");
|
|
208
|
+
const saved = await readSavedTags();
|
|
209
|
+
const where = global ? "globally" : `for ${showDir(cwd)}`;
|
|
210
|
+
const current = global ? saved.global : (saved.paths[cwd] ?? {});
|
|
211
|
+
const store = async (layer) => {
|
|
212
|
+
const paths = { ...saved.paths };
|
|
213
|
+
if (!global) {
|
|
214
|
+
if (Object.keys(layer).length === 0)
|
|
215
|
+
delete paths[cwd];
|
|
216
|
+
else
|
|
217
|
+
paths[cwd] = layer;
|
|
218
|
+
}
|
|
219
|
+
await writeSavedTags({ global: global ? layer : saved.global, paths });
|
|
220
|
+
out(`saved ${where}: ${showLayer(layer)}`);
|
|
221
|
+
};
|
|
222
|
+
if (sub === "set") {
|
|
223
|
+
if (rest.length === 0)
|
|
224
|
+
throw new Error("usage: fest tags set [-g] key=value [key=value …]");
|
|
225
|
+
const next = { ...current };
|
|
226
|
+
for (const arg of rest) {
|
|
227
|
+
const parsed = parseTagPairs(arg);
|
|
228
|
+
if (parsed.length === 0)
|
|
229
|
+
throw new Error(`${arg}: expected key=value`);
|
|
230
|
+
// An empty value is kept: here it means "not in this directory".
|
|
231
|
+
for (const p of parsed)
|
|
232
|
+
next[p.key] = p.value;
|
|
233
|
+
}
|
|
234
|
+
await store(next);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (sub === "unset") {
|
|
238
|
+
if (rest.length === 0)
|
|
239
|
+
throw new Error("usage: fest tags unset [-g] key [key …]");
|
|
240
|
+
const next = { ...current };
|
|
241
|
+
for (const key of rest)
|
|
242
|
+
delete next[key.toLowerCase()];
|
|
243
|
+
await store(next);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (sub !== undefined)
|
|
247
|
+
throw new Error(`unknown \`fest tags ${sub}\`. Try \`fest tags set key=value\`.`);
|
|
248
|
+
out(`global: ${showLayer(saved.global)}`);
|
|
249
|
+
for (const [dir, layer] of pathLayers(saved, cwd))
|
|
250
|
+
out(`${showDir(dir)}: ${showLayer(layer)}`);
|
|
251
|
+
const effective = await sessionTags([], cwd);
|
|
252
|
+
out(`effective: ${decodeURIComponent(formatTags(effective)) || "(none)"}`);
|
|
253
|
+
out("");
|
|
254
|
+
out("`fest tags set` saves for this directory and everything under it; -g saves globally.");
|
|
255
|
+
out("Effective also adds project=<git repo name> and FEST_TAGS. Override per session with");
|
|
256
|
+
out("--tag key=value; an empty value (project=) removes a key.");
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../cli/tags.ts"],"names":[],"mappings":"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"}
|
package/dist/server/api/live.js
CHANGED
|
@@ -54,6 +54,7 @@ export function toLiveRow(rec) {
|
|
|
54
54
|
rlClaim: rec.rateLimit?.representativeClaim ?? null,
|
|
55
55
|
clientVersion: rec.clientVersion,
|
|
56
56
|
client: rec.client ?? null,
|
|
57
|
+
tags: rec.tags ?? {},
|
|
57
58
|
pipeline: rec.pipeline,
|
|
58
59
|
routeId: rec.routeId,
|
|
59
60
|
credentialsConsidered: rec.credentialsConsidered,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../../server/api/live.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../../server/api/live.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* result arrives as `scope`. Every query takes that scope explicitly, so there
|
|
12
12
|
* is no ambient "current org" a handler could forget to apply.
|
|
13
13
|
*/
|
|
14
|
-
import { listRequests, usageTotals, usageByUser, usageByModel, usageByCredentialOrigin, usageByClient, usageSeries, errorBreakdown, latencySummary, latestQuotaByUser, } from "../store/queries.js";
|
|
14
|
+
import { listRequests, usageTotals, usageByUser, usageByModel, usageByCredentialOrigin, usageByClient, usageSeries, errorBreakdown, latencySummary, latestQuotaByUser, usageByTag, tagValues, } from "../store/queries.js";
|
|
15
|
+
import { isValidTagKey, parseTagFilter } from "../../shared/tags.js";
|
|
15
16
|
import { explainRoutes } from "./routing-view.js";
|
|
16
17
|
import { ADAPTER_TRANSFORMS } from "../adapters/registry.js";
|
|
17
18
|
import { handleLive } from "./live.js";
|
|
@@ -34,7 +35,15 @@ export function parseRange(params, now = Date.now()) {
|
|
|
34
35
|
const toMs = intParam(params, "to") ?? now;
|
|
35
36
|
const fromRaw = intParam(params, "from") ?? toMs - DEFAULT_RANGE_MS;
|
|
36
37
|
const fromMs = Math.max(fromRaw, toMs - MAX_RANGE_MS);
|
|
37
|
-
|
|
38
|
+
const tags = parseTagFilter(params.getAll("tag"));
|
|
39
|
+
return {
|
|
40
|
+
fromMs: Math.min(fromMs, toMs),
|
|
41
|
+
toMs,
|
|
42
|
+
// Only present when filtering, so an unfiltered range is exactly what it
|
|
43
|
+
// was before tags existed. Invalid `tag=` values are dropped by the parser,
|
|
44
|
+
// never bound as-is.
|
|
45
|
+
...(Object.keys(tags).length > 0 ? { tags } : {}),
|
|
46
|
+
};
|
|
38
47
|
}
|
|
39
48
|
function strParam(params, name) {
|
|
40
49
|
const raw = params.get(name);
|
|
@@ -92,10 +101,22 @@ export function handleApi(req, res, path, deps) {
|
|
|
92
101
|
...(params.get("errorsOnly") === "1" ? { errorsOnly: true } : {}),
|
|
93
102
|
...(intParam(params, "before") !== undefined ? { beforeSeq: intParam(params, "before") } : {}),
|
|
94
103
|
...(intParam(params, "limit") !== undefined ? { limit: intParam(params, "limit") } : {}),
|
|
104
|
+
...(range.tags !== undefined ? { tags: range.tags } : {}),
|
|
95
105
|
};
|
|
96
106
|
json(res, 200, listRequests(deps.store, scope, filter));
|
|
97
107
|
return true;
|
|
98
108
|
}
|
|
109
|
+
case "/api/tags": {
|
|
110
|
+
const by = strParam(params, "by")?.trim().toLowerCase();
|
|
111
|
+
const key = by !== undefined && isValidTagKey(by) ? by : null;
|
|
112
|
+
json(res, 200, {
|
|
113
|
+
range,
|
|
114
|
+
keys: tagValues(deps.store, scope, range),
|
|
115
|
+
by: key,
|
|
116
|
+
rows: key === null ? [] : usageByTag(deps.store, scope, range, key),
|
|
117
|
+
});
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
99
120
|
case "/api/users":
|
|
100
121
|
json(res, 200, { range, rows: usageByUser(deps.store, scope, range) });
|
|
101
122
|
return true;
|