@root-signals/scorable-cli 0.13.0 → 0.14.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 (83) hide show
  1. package/README.md +60 -0
  2. package/dist/client.d.ts +1 -0
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +1 -0
  5. package/dist/commands/auth/index.d.ts.map +1 -1
  6. package/dist/commands/auth/index.js +68 -1
  7. package/dist/commands/evaluator/create.d.ts.map +1 -1
  8. package/dist/commands/evaluator/create.js +5 -0
  9. package/dist/commands/evaluator/duplicate.d.ts.map +1 -1
  10. package/dist/commands/evaluator/duplicate.js +5 -2
  11. package/dist/commands/evaluator/execute-by-name.d.ts +1 -0
  12. package/dist/commands/evaluator/execute-by-name.d.ts.map +1 -1
  13. package/dist/commands/evaluator/execute-by-name.js +5 -0
  14. package/dist/commands/evaluator/execute.d.ts +1 -0
  15. package/dist/commands/evaluator/execute.d.ts.map +1 -1
  16. package/dist/commands/evaluator/execute.js +5 -0
  17. package/dist/commands/evaluator/export-yaml.d.ts.map +1 -1
  18. package/dist/commands/evaluator/export-yaml.js +10 -1
  19. package/dist/commands/evaluator/import-yaml.d.ts.map +1 -1
  20. package/dist/commands/evaluator/import-yaml.js +10 -1
  21. package/dist/commands/evaluator/list.d.ts.map +1 -1
  22. package/dist/commands/evaluator/list.js +5 -0
  23. package/dist/commands/evaluator/update.d.ts.map +1 -1
  24. package/dist/commands/evaluator/update.js +5 -0
  25. package/dist/commands/execution-log/list.d.ts.map +1 -1
  26. package/dist/commands/execution-log/list.js +5 -0
  27. package/dist/commands/judge/create.d.ts.map +1 -1
  28. package/dist/commands/judge/create.js +5 -0
  29. package/dist/commands/judge/duplicate.d.ts.map +1 -1
  30. package/dist/commands/judge/duplicate.js +5 -2
  31. package/dist/commands/judge/exec-openai-generic.d.ts.map +1 -1
  32. package/dist/commands/judge/exec-openai-generic.js +5 -0
  33. package/dist/commands/judge/exec-openai.d.ts.map +1 -1
  34. package/dist/commands/judge/exec-openai.js +5 -0
  35. package/dist/commands/judge/execute-by-name.d.ts +1 -0
  36. package/dist/commands/judge/execute-by-name.d.ts.map +1 -1
  37. package/dist/commands/judge/execute-by-name.js +5 -0
  38. package/dist/commands/judge/execute.d.ts +1 -0
  39. package/dist/commands/judge/execute.d.ts.map +1 -1
  40. package/dist/commands/judge/execute.js +5 -0
  41. package/dist/commands/judge/generate.d.ts.map +1 -1
  42. package/dist/commands/judge/generate.js +4 -0
  43. package/dist/commands/judge/list.d.ts.map +1 -1
  44. package/dist/commands/judge/list.js +5 -0
  45. package/dist/commands/judge/update.d.ts.map +1 -1
  46. package/dist/commands/judge/update.js +5 -0
  47. package/dist/commands/project/create.d.ts +3 -0
  48. package/dist/commands/project/create.d.ts.map +1 -0
  49. package/dist/commands/project/create.js +31 -0
  50. package/dist/commands/project/delete.d.ts +3 -0
  51. package/dist/commands/project/delete.d.ts.map +1 -0
  52. package/dist/commands/project/delete.js +37 -0
  53. package/dist/commands/project/get.d.ts +3 -0
  54. package/dist/commands/project/get.d.ts.map +1 -0
  55. package/dist/commands/project/get.js +23 -0
  56. package/dist/commands/project/index.d.ts +3 -0
  57. package/dist/commands/project/index.d.ts.map +1 -0
  58. package/dist/commands/project/index.js +17 -0
  59. package/dist/commands/project/list.d.ts +3 -0
  60. package/dist/commands/project/list.d.ts.map +1 -0
  61. package/dist/commands/project/list.js +39 -0
  62. package/dist/commands/project/set-default.d.ts +3 -0
  63. package/dist/commands/project/set-default.d.ts.map +1 -0
  64. package/dist/commands/project/set-default.js +23 -0
  65. package/dist/commands/project/update.d.ts +3 -0
  66. package/dist/commands/project/update.d.ts.map +1 -0
  67. package/dist/commands/project/update.js +37 -0
  68. package/dist/commands/prompt-test/init.d.ts.map +1 -1
  69. package/dist/commands/prompt-test/init.js +9 -2
  70. package/dist/commands/prompt-test/run.d.ts +1 -1
  71. package/dist/commands/prompt-test/run.d.ts.map +1 -1
  72. package/dist/commands/prompt-test/run.js +9 -2
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +2 -0
  75. package/dist/lib/project-id.d.ts +9 -0
  76. package/dist/lib/project-id.d.ts.map +1 -0
  77. package/dist/lib/project-id.js +23 -0
  78. package/dist/output.d.ts +2 -1
  79. package/dist/output.d.ts.map +1 -1
  80. package/dist/output.js +71 -12
  81. package/dist/types.d.ts +1 -0
  82. package/dist/types.d.ts.map +1 -1
  83. package/package.json +4 -4
package/README.md CHANGED
@@ -78,6 +78,66 @@ export SCORABLE_API_KEY="sk-your-api-key"
78
78
 
79
79
  The key lookup order is: `SCORABLE_API_KEY` env var → `api_key` in `~/.scorable/settings.json` → `temporary_api_key` in `~/.scorable/settings.json`.
80
80
 
81
+ ## Projects
82
+
83
+ A **project** is a workspace inside your organization that groups related judges, evaluators, datasets, and execution logs. Every resource belongs to a project; omitting the project at create/execute time files things under the org's default project.
84
+
85
+ ### Manage projects
86
+
87
+ ```bash
88
+ scorable project list # list all projects (default marked)
89
+ scorable project get <project_id> # show a single project
90
+ scorable project create --name "Production" # create a project
91
+ scorable project create --name "Production" --is-default
92
+ scorable project update <project_id> --name "Renamed"
93
+ scorable project update <project_id> --is-default # promote to default
94
+ scorable project set-default <project_id> # convenience for `update --is-default`
95
+ scorable project delete <project_id>
96
+ ```
97
+
98
+ ### `--project-id` on every project-aware command
99
+
100
+ Every command that creates, executes, lists, or filters a project-scoped resource accepts `--project-id <uuid>`:
101
+
102
+ ```bash
103
+ # Filter list endpoints
104
+ scorable judge list --project-id <project_id>
105
+ scorable evaluator list --project-id <project_id>
106
+ scorable execution-log list --project-id <project_id>
107
+
108
+ # Route an execution log to a project
109
+ scorable judge execute <judge_id> --project-id <project_id>
110
+ scorable evaluator execute <evaluator_id> --project-id <project_id>
111
+
112
+ # Pin a resource to a project at creation
113
+ scorable judge create --name X --intent Y --project-id <project_id>
114
+ scorable evaluator import-yaml --file evaluator.yaml --project-id <project_id>
115
+
116
+ # Move a resource between projects
117
+ scorable judge update <judge_id> --project-id <other_project_id>
118
+
119
+ # OpenAI-compat (translated to X-Project-Id header)
120
+ scorable judge exec-openai <judge_id> --project-id <project_id>
121
+ ```
122
+
123
+ ### Setting a default project for your shell
124
+
125
+ To avoid passing `--project-id` on every command, set an env var or persist a per-machine default:
126
+
127
+ ```bash
128
+ # Environment variable (great for CI)
129
+ export SCORABLE_PROJECT_ID=<project_id>
130
+
131
+ # Persistent default written to ~/.scorable/settings.json
132
+ scorable auth set-project <project_id>
133
+ scorable auth show-project # see what's resolved and from where
134
+ scorable auth unset-project # remove the saved default
135
+ ```
136
+
137
+ Resolution order: `--project-id` flag → `SCORABLE_PROJECT_ID` env var → `project_id` in `~/.scorable/settings.json` → omitted (backend resolves to org default). Pass `--project-id ""` to explicitly opt out of an inherited default for a single invocation.
138
+
139
+ `scorable auth logout` clears the entire auth section of `~/.scorable/settings.json`, including the saved project_id.
140
+
81
141
  ## Scorable Skills for AI Coding Agents
82
142
 
83
143
  Install Scorable skills into your project so your AI coding agent (Claude Code, Cursor, etc.) can integrate evaluators automatically:
package/dist/client.d.ts CHANGED
@@ -3,6 +3,7 @@ interface RequestOptions {
3
3
  params?: Record<string, unknown>;
4
4
  apiKey?: string;
5
5
  baseUrl?: string;
6
+ headers?: Record<string, string>;
6
7
  }
7
8
  export interface ApiRequestResult {
8
9
  ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAQD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAoD3B;AAKD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAGlB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAQA,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAQD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAqD3B;AAKD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAGlB"}
package/dist/client.js CHANGED
@@ -15,6 +15,7 @@ export async function apiRequestStatus(method, endpoint, options) {
15
15
  }
16
16
  }
17
17
  const headers = {
18
+ ...options?.headers,
18
19
  Authorization: `Api-Key ${apiKey}`,
19
20
  "Content-Type": "application/json",
20
21
  Accept: "application/json",
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgE3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsI3D"}
@@ -1,7 +1,9 @@
1
1
  import ora from "ora";
2
2
  import { loadSettings, saveSettings, createDemoKey } from "../../auth.js";
3
- import { printSuccess, printError } from "../../output.js";
3
+ import { printSuccess, printError, printInfo, printMessage } from "../../output.js";
4
+ import { resolveProjectId } from "../../lib/project-id.js";
4
5
  import { CliError } from "../../types.js";
6
+ const AUTH_SETTINGS_KEYS = ["api_key", "temporary_api_key", "project_id"];
5
7
  export function registerAuthCommands(program) {
6
8
  const auth = program.command("auth").description("Manage authentication");
7
9
  auth
@@ -39,6 +41,71 @@ export function registerAuthCommands(program) {
39
41
  }
40
42
  printSuccess("API key saved to ~/.scorable/settings.json");
41
43
  });
44
+ auth
45
+ .command("set-project <projectId>")
46
+ .description("Persist a project_id to ~/.scorable/settings.json")
47
+ .action((projectId) => {
48
+ if (!projectId.trim()) {
49
+ printError("Project ID must not be empty.");
50
+ throw new CliError(1, "Empty project id");
51
+ }
52
+ const settings = loadSettings();
53
+ settings["project_id"] = projectId.trim();
54
+ if (!saveSettings(settings)) {
55
+ printError("Failed to save project_id to ~/.scorable/settings.json");
56
+ throw new CliError(1, "Failed to save project_id");
57
+ }
58
+ printSuccess(`project_id saved to ~/.scorable/settings.json`);
59
+ });
60
+ auth
61
+ .command("unset-project")
62
+ .description("Remove the persisted project_id from ~/.scorable/settings.json")
63
+ .action(() => {
64
+ const settings = loadSettings();
65
+ if (!("project_id" in settings)) {
66
+ printInfo("No project_id was set.");
67
+ return;
68
+ }
69
+ delete settings["project_id"];
70
+ if (!saveSettings(settings)) {
71
+ printError("Failed to update ~/.scorable/settings.json");
72
+ throw new CliError(1, "Failed to update settings");
73
+ }
74
+ printSuccess("project_id removed from ~/.scorable/settings.json");
75
+ });
76
+ auth
77
+ .command("show-project")
78
+ .description("Print the resolved project_id and its source (flag/env/settings/none)")
79
+ .action(() => {
80
+ const resolved = resolveProjectId(undefined);
81
+ if (resolved.value === undefined) {
82
+ printMessage("project_id: <none> (source: none)");
83
+ return;
84
+ }
85
+ printMessage(`project_id: ${resolved.value} (source: ${resolved.source})`);
86
+ });
87
+ auth
88
+ .command("logout")
89
+ .description("Clear the auth section of ~/.scorable/settings.json (api keys + project_id)")
90
+ .action(() => {
91
+ const settings = loadSettings();
92
+ let touched = false;
93
+ for (const k of AUTH_SETTINGS_KEYS) {
94
+ if (k in settings) {
95
+ delete settings[k];
96
+ touched = true;
97
+ }
98
+ }
99
+ if (!touched) {
100
+ printInfo("Already logged out.");
101
+ return;
102
+ }
103
+ if (!saveSettings(settings)) {
104
+ printError("Failed to update ~/.scorable/settings.json");
105
+ throw new CliError(1, "Failed to update settings");
106
+ }
107
+ printSuccess("Logged out — cleared api_key, temporary_api_key, and project_id.");
108
+ });
42
109
  auth
43
110
  .command("demo-key")
44
111
  .description("Create a free demo API key and save it to ~/.scorable/settings.json")
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAiF9D"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAsF9D"}
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  import { requireApiKey, getSdkClient } from "../../auth.js";
4
4
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
5
5
  import { parseJsonArg } from "../../utils.js";
6
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
6
7
  export function registerCreateCommand(evaluator) {
7
8
  evaluator
8
9
  .command("create")
@@ -14,6 +15,7 @@ export function registerCreateCommand(evaluator) {
14
15
  .option("--models <json>", "JSON array of model names, in priority order. E.g., '[\"gpt-5-mini\"]'")
15
16
  .option("--overwrite", "Overwrite if evaluator with same name exists")
16
17
  .option("--objective-version-id <id>", "Objective version ID")
18
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
17
19
  .action(async (opts) => {
18
20
  if (!opts.intent && !opts.objectiveId) {
19
21
  printError("Either --intent or --objective-id is required.");
@@ -45,6 +47,9 @@ export function registerCreateCommand(evaluator) {
45
47
  }
46
48
  payload.models = r.value;
47
49
  }
50
+ const projectId = resolveProjectIdValue(opts.projectId);
51
+ if (projectId !== undefined)
52
+ payload.projectId = projectId;
48
53
  const spinner = ora("Creating...").start();
49
54
  try {
50
55
  const apiKey = await requireApiKey();
@@ -1 +1 @@
1
- {"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAkBjE"}
1
+ {"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAuBjE"}
@@ -1,16 +1,19 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printSuccess, printJson, handleSdkError } from "../../output.js";
4
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
5
  export function registerDuplicateCommand(evaluator) {
5
6
  evaluator
6
7
  .command("duplicate <evaluatorId>")
7
8
  .description("Duplicate an existing evaluator")
8
- .action(async (evaluatorId) => {
9
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
10
+ .action(async (evaluatorId, opts) => {
9
11
  const apiKey = await requireApiKey();
10
12
  const spinner = ora("Duplicating...").start();
11
13
  try {
12
14
  const client = getSdkClient(apiKey);
13
- const result = await client.evaluators.duplicate(evaluatorId);
15
+ const projectId = resolveProjectIdValue(opts.projectId);
16
+ const result = await client.evaluators.duplicate(evaluatorId, projectId !== undefined ? { projectId } : {});
14
17
  spinner.stop();
15
18
  printSuccess(`Evaluator ${evaluatorId} duplicated successfully!`);
16
19
  printJson(result);
@@ -12,6 +12,7 @@ export declare function executeEvaluatorByName(evaluatorName: string, opts: {
12
12
  sessionId?: string;
13
13
  systemPrompt?: string;
14
14
  variables?: string;
15
+ projectId?: string;
15
16
  }, readStdin?: typeof readStdinDefault): Promise<void>;
16
17
  export declare function registerExecuteByNameCommand(evaluator: Command): void;
17
18
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"execute-by-name.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute-by-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyFf;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAmFrE"}
1
+ {"version":3,"file":"execute-by-name.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute-by-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA4Ff;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAqFrE"}
@@ -2,6 +2,7 @@ import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
4
4
  import { isTurnArray, isToolCatalog, isStringArray, isStringRecord } from "../../utils.js";
5
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
5
6
  async function readStdinDefault() {
6
7
  const chunks = [];
7
8
  for await (const chunk of process.stdin)
@@ -89,6 +90,9 @@ export async function executeEvaluatorByName(evaluatorName, opts, readStdin = re
89
90
  return;
90
91
  }
91
92
  }
93
+ const projectId = resolveProjectIdValue(opts.projectId);
94
+ if (projectId !== undefined)
95
+ payload.projectId = projectId;
92
96
  const spinner = ora("Running evaluator...").start();
93
97
  try {
94
98
  const client = getSdkClient(apiKey);
@@ -117,6 +121,7 @@ export function registerExecuteByNameCommand(evaluator) {
117
121
  .option("--turns <json>", 'JSON array of conversation turns. Roles: user|assistant|tool. Assistant turns may carry `tool_calls`; tool results use a `tool` role with `tool_call_id`. E.g., \'[{"role":"user","content":"Hello"}]\'')
118
122
  .option("--tools <json>", "JSON array of OpenAI-style tool definitions available to the agent.")
119
123
  .option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
124
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
120
125
  .addHelpText("after", `
121
126
  Examples:
122
127
  # Check helpfulness of a support response
@@ -13,6 +13,7 @@ export declare function executeEvaluator(evaluatorId: string, opts: {
13
13
  systemPrompt?: string;
14
14
  variables?: string;
15
15
  fileIds?: string;
16
+ projectId?: string;
16
17
  }, readStdin?: typeof readStdinDefault): Promise<void>;
17
18
  export declare function registerExecuteCommand(evaluator: Command): void;
18
19
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAsGf;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAkG/D"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,iBAAe,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAIjD;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,SAAS,0BAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyGf;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAoG/D"}
@@ -2,6 +2,7 @@ import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
4
4
  import { isTurnArray, isToolCatalog, isStringArray, isStringRecord } from "../../utils.js";
5
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
5
6
  async function readStdinDefault() {
6
7
  const chunks = [];
7
8
  for await (const chunk of process.stdin)
@@ -102,6 +103,9 @@ export async function executeEvaluator(evaluatorId, opts, readStdin = readStdinD
102
103
  }
103
104
  payload.file_ids = parsed;
104
105
  }
106
+ const projectId = resolveProjectIdValue(opts.projectId);
107
+ if (projectId !== undefined)
108
+ payload.projectId = projectId;
105
109
  const spinner = ora("Running evaluator...").start();
106
110
  try {
107
111
  const client = getSdkClient(apiKey);
@@ -131,6 +135,7 @@ export function registerExecuteCommand(evaluator) {
131
135
  .option("--tools <json>", "JSON array of OpenAI-style tool definitions available to the agent.")
132
136
  .option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
133
137
  .option("--file-ids <json>", "JSON array of file UUIDs from 'scorable file upload'. E.g., '[\"uuid1\"]'")
138
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
134
139
  .addHelpText("after", `
135
140
  Examples:
136
141
  # Check helpfulness of a support response
@@ -1 +1 @@
1
- {"version":3,"file":"export-yaml.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/export-yaml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAwBlE"}
1
+ {"version":3,"file":"export-yaml.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/export-yaml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAwBlE"}
@@ -1,7 +1,16 @@
1
1
  import { writeFileSync } from "node:fs";
2
+ import yaml from "js-yaml";
2
3
  import ora from "ora";
3
4
  import { requireApiKey, getSdkClient } from "../../auth.js";
4
5
  import { printSuccess, handleSdkError } from "../../output.js";
6
+ function stripProjectId(yamlContent) {
7
+ const parsed = yaml.load(yamlContent);
8
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
9
+ delete parsed.project_id;
10
+ return yaml.dump(parsed);
11
+ }
12
+ return yamlContent;
13
+ }
5
14
  export function registerExportYamlCommand(evaluator) {
6
15
  evaluator
7
16
  .command("export-yaml")
@@ -13,7 +22,7 @@ export function registerExportYamlCommand(evaluator) {
13
22
  try {
14
23
  const apiKey = await requireApiKey();
15
24
  const client = getSdkClient(apiKey);
16
- const yaml = await client.evaluators.exportYaml(id);
25
+ const yaml = stripProjectId(await client.evaluators.exportYaml(id));
17
26
  spinner.stop();
18
27
  if (opts.output) {
19
28
  writeFileSync(opts.output, yaml, "utf8");
@@ -1 +1 @@
1
- {"version":3,"file":"import-yaml.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/import-yaml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA2ClE"}
1
+ {"version":3,"file":"import-yaml.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/import-yaml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAkDlE"}
@@ -2,12 +2,14 @@ import { readFileSync } from "node:fs";
2
2
  import ora from "ora";
3
3
  import { requireApiKey, getBaseUrl } from "../../auth.js";
4
4
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
5
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
5
6
  export function registerImportYamlCommand(evaluator) {
6
7
  evaluator
7
8
  .command("import-yaml")
8
9
  .description("Import an evaluator from a YAML file")
9
10
  .requiredOption("--file <path>", "Path to the YAML file to import")
10
11
  .option("--overwrite", "Overwrite if an evaluator with the same name already exists")
12
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
11
13
  .action(async (opts) => {
12
14
  let yamlContent;
13
15
  try {
@@ -21,13 +23,20 @@ export function registerImportYamlCommand(evaluator) {
21
23
  try {
22
24
  const apiKey = await requireApiKey();
23
25
  const baseUrl = getBaseUrl();
26
+ const projectId = resolveProjectIdValue(opts.projectId);
27
+ const body = {
28
+ yaml: yamlContent,
29
+ overwrite: opts.overwrite ?? false,
30
+ };
31
+ if (projectId !== undefined)
32
+ body["project_id"] = projectId;
24
33
  const response = await fetch(`${baseUrl}/v1/evaluators/import-yaml/`, {
25
34
  method: "POST",
26
35
  headers: {
27
36
  Authorization: `Api-Key ${apiKey}`,
28
37
  "Content-Type": "application/json",
29
38
  },
30
- body: JSON.stringify({ yaml: yamlContent, overwrite: opts.overwrite ?? false }),
39
+ body: JSON.stringify(body),
31
40
  });
32
41
  if (!response.ok) {
33
42
  spinner.stop();
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA4C5D"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAgD5D"}
@@ -1,6 +1,7 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printMessage, printEvaluatorTable, handleSdkError } from "../../output.js";
4
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
5
  export function registerListCommand(evaluator) {
5
6
  evaluator
6
7
  .command("list")
@@ -10,6 +11,7 @@ export function registerListCommand(evaluator) {
10
11
  .option("--search <term>", "A search term to filter by")
11
12
  .option("--name <name>", "Filter by exact evaluator name")
12
13
  .option("--ordering <field>", "Which field to use for ordering the results")
14
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
13
15
  .action(async (opts) => {
14
16
  const apiKey = await requireApiKey();
15
17
  const params = {};
@@ -23,6 +25,9 @@ export function registerListCommand(evaluator) {
23
25
  params.name = opts.name;
24
26
  if (opts.ordering !== undefined)
25
27
  params.ordering = opts.ordering;
28
+ const projectId = resolveProjectIdValue(opts.projectId);
29
+ if (projectId !== undefined)
30
+ params.projectId = projectId;
26
31
  const spinner = ora("Fetching...").start();
27
32
  try {
28
33
  const client = getSdkClient(apiKey);
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA0D9D"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/evaluator/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAkE9D"}
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  import { requireApiKey, getSdkClient } from "../../auth.js";
4
4
  import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
5
5
  import { parseJsonArg } from "../../utils.js";
6
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
6
7
  export function registerUpdateCommand(evaluator) {
7
8
  evaluator
8
9
  .command("update <evaluatorId>")
@@ -12,6 +13,7 @@ export function registerUpdateCommand(evaluator) {
12
13
  .option("--models <json>", "JSON array of model names. E.g., '[\"gpt-5.5\"]'")
13
14
  .option("--objective-id <id>", "The new objective ID")
14
15
  .option("--objective-version-id <id>", "The new objective version ID")
16
+ .option("--project-id <uuid>", "Move the evaluator to this project (within the same organization). " + PROJECT_ID_FLAG_DESC)
15
17
  .action(async (evaluatorId, opts) => {
16
18
  const apiKey = await requireApiKey();
17
19
  const payload = {};
@@ -31,6 +33,9 @@ export function registerUpdateCommand(evaluator) {
31
33
  }
32
34
  payload.models = r.value;
33
35
  }
36
+ const projectId = resolveProjectIdValue(opts.projectId);
37
+ if (projectId !== undefined)
38
+ payload.projectId = projectId;
34
39
  if (Object.keys(payload).length === 0) {
35
40
  printInfo("No update parameters provided. Aborting.");
36
41
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/execution-log/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAiE/D"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/execution-log/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAqE/D"}
@@ -1,6 +1,7 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printMessage, printExecutionLogTable, handleSdkError } from "../../output.js";
4
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
5
  export function registerListCommand(executionLog) {
5
6
  executionLog
6
7
  .command("list")
@@ -17,6 +18,7 @@ export function registerListCommand(executionLog) {
17
18
  .option("--created-at-after <date>", "Filter logs created after this date (ISO 8601)")
18
19
  .option("--created-at-before <date>", "Filter logs created before this date (ISO 8601)")
19
20
  .option("--owner-email <email>", "Filter by owner email")
21
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
20
22
  .action(async (opts) => {
21
23
  const apiKey = await requireApiKey();
22
24
  const params = {};
@@ -44,6 +46,9 @@ export function registerListCommand(executionLog) {
44
46
  params.created_at_before = opts.createdAtBefore;
45
47
  if (opts.ownerEmail !== undefined)
46
48
  params.owner__email = opts.ownerEmail;
49
+ const projectId = resolveProjectIdValue(opts.projectId);
50
+ if (projectId !== undefined)
51
+ params.projectId = projectId;
47
52
  const spinner = ora("Fetching...").start();
48
53
  try {
49
54
  const client = getSdkClient(apiKey);
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA+C1D"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAoD1D"}
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  import { requireApiKey, getSdkClient } from "../../auth.js";
4
4
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
5
5
  import { parseJsonArg } from "../../utils.js";
6
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
6
7
  const EvaluatorRefsSchema = z.array(z.object({ id: z.string() }).passthrough());
7
8
  export function registerCreateCommand(judge) {
8
9
  judge
@@ -12,6 +13,7 @@ export function registerCreateCommand(judge) {
12
13
  .requiredOption("--intent <intent>", "The intent for the new judge")
13
14
  .option("--stage <stage>", "The stage for the new judge")
14
15
  .option("--evaluator-references <json>", 'JSON string for evaluator references. E.g., \'[{"id": "eval-id"}]\'')
16
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
15
17
  .action(async (opts) => {
16
18
  const apiKey = await requireApiKey();
17
19
  const payload = { name: opts.name, intent: opts.intent };
@@ -25,6 +27,9 @@ export function registerCreateCommand(judge) {
25
27
  }
26
28
  payload.evaluator_references = r.value;
27
29
  }
30
+ const projectId = resolveProjectIdValue(opts.projectId);
31
+ if (projectId !== undefined)
32
+ payload.projectId = projectId;
28
33
  const spinner = ora("Creating...").start();
29
34
  try {
30
35
  const client = getSdkClient(apiKey);
@@ -1 +1 @@
1
- {"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAkB7D"}
1
+ {"version":3,"file":"duplicate.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/duplicate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAuB7D"}
@@ -1,16 +1,19 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printSuccess, printJson, handleSdkError } from "../../output.js";
4
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
5
  export function registerDuplicateCommand(judge) {
5
6
  judge
6
7
  .command("duplicate <judgeId>")
7
8
  .description("Duplicate an existing judge")
8
- .action(async (judgeId) => {
9
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
10
+ .action(async (judgeId, opts) => {
9
11
  const apiKey = await requireApiKey();
10
12
  const spinner = ora("Duplicating...").start();
11
13
  try {
12
14
  const client = getSdkClient(apiKey);
13
- const result = await client.judges.duplicate(judgeId);
15
+ const projectId = resolveProjectIdValue(opts.projectId);
16
+ const result = await client.judges.duplicate(judgeId, projectId !== undefined ? { projectId } : {});
14
17
  spinner.stop();
15
18
  printSuccess(`Judge ${judgeId} duplicated successfully!`);
16
19
  printJson(result);
@@ -1 +1 @@
1
- {"version":3,"file":"exec-openai-generic.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai-generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAiDrE"}
1
+ {"version":3,"file":"exec-openai-generic.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai-generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAwDrE"}
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { requireApiKey } from "../../auth.js";
3
3
  import { printInfo, printSuccess, printError, printWarning, printJson, handleSdkError, } from "../../output.js";
4
4
  import { parseJsonArg } from "../../utils.js";
5
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
5
6
  import { apiRequest } from "../../client.js";
6
7
  const MessagesSchema = z.array(z.object({ role: z.string() }).passthrough());
7
8
  const ExtraBodySchema = z.record(z.string(), z.unknown());
@@ -12,6 +13,7 @@ export function registerExecOpenaiGenericCommand(judge) {
12
13
  .requiredOption("--model <model>", "Judge ID (or name) to use as the 'model' field")
13
14
  .requiredOption("--messages <json>", "JSON string of the messages payload")
14
15
  .option("--extra-body <json>", "Optional JSON string for extra_body parameters")
16
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
15
17
  .action(async (opts) => {
16
18
  const apiKey = await requireApiKey();
17
19
  const messagesResult = parseJsonArg(opts.messages, MessagesSchema);
@@ -35,10 +37,13 @@ export function registerExecOpenaiGenericCommand(judge) {
35
37
  printInfo(`Executing a Judge using generic OpenAI endpoint. Judge ID/Name: ${opts.model}`);
36
38
  printInfo("Attempting to execute with OpenAI compatible payload:");
37
39
  printJson(payload);
40
+ const projectId = resolveProjectIdValue(opts.projectId);
41
+ const headers = projectId !== undefined ? { "X-Project-Id": projectId } : undefined;
38
42
  try {
39
43
  const result = await apiRequest("POST", "judges/openai/chat/completions", {
40
44
  payload,
41
45
  apiKey,
46
+ headers,
42
47
  });
43
48
  if (result) {
44
49
  printSuccess("OpenAI compatible execution successful!");
@@ -1 +1 @@
1
- {"version":3,"file":"exec-openai.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA4D9D"}
1
+ {"version":3,"file":"exec-openai.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/exec-openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAiE9D"}
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { requireApiKey } from "../../auth.js";
3
3
  import { printInfo, printSuccess, printError, printWarning, printJson, handleSdkError, } from "../../output.js";
4
4
  import { parseJsonArg } from "../../utils.js";
5
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
5
6
  import { apiRequest } from "../../client.js";
6
7
  const MessagesSchema = z.array(z.object({ role: z.string() }).passthrough());
7
8
  const ExtraBodySchema = z.record(z.string(), z.unknown());
@@ -12,6 +13,7 @@ export function registerExecOpenaiCommand(judge) {
12
13
  .requiredOption("--model <model>", "LLM model for judge execution (e.g., gpt-5.5)")
13
14
  .requiredOption("--messages <json>", "JSON string of the messages payload")
14
15
  .option("--extra-body <json>", "Optional JSON string for extra_body parameters")
16
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
15
17
  .action(async (judgeIdInPath, opts) => {
16
18
  const apiKey = await requireApiKey();
17
19
  const messagesResult = parseJsonArg(opts.messages, MessagesSchema);
@@ -35,10 +37,13 @@ export function registerExecOpenaiCommand(judge) {
35
37
  printInfo(`Executing Judge ID (via path): ${judgeIdInPath} using OpenAI chat completions format.`);
36
38
  printInfo("Attempting to execute with OpenAI compatible payload:");
37
39
  printJson(payload);
40
+ const projectId = resolveProjectIdValue(opts.projectId);
41
+ const headers = projectId !== undefined ? { "X-Project-Id": projectId } : undefined;
38
42
  try {
39
43
  const result = await apiRequest("POST", `judges/${judgeIdInPath}/openai/chat/completions`, {
40
44
  payload,
41
45
  apiKey,
46
+ headers,
42
47
  });
43
48
  if (result) {
44
49
  printSuccess("OpenAI compatible execution successful!");