@root-signals/scorable-cli 0.12.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 (91) 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 +11 -5
  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 +2 -0
  12. package/dist/commands/evaluator/execute-by-name.d.ts.map +1 -1
  13. package/dist/commands/evaluator/execute-by-name.js +27 -2
  14. package/dist/commands/evaluator/execute.d.ts +2 -0
  15. package/dist/commands/evaluator/execute.d.ts.map +1 -1
  16. package/dist/commands/evaluator/execute.js +27 -2
  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 +11 -5
  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 +12 -5
  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 +21 -11
  33. package/dist/commands/judge/exec-openai.d.ts.map +1 -1
  34. package/dist/commands/judge/exec-openai.js +21 -11
  35. package/dist/commands/judge/execute-by-name.d.ts +2 -0
  36. package/dist/commands/judge/execute-by-name.d.ts.map +1 -1
  37. package/dist/commands/judge/execute-by-name.js +27 -2
  38. package/dist/commands/judge/execute.d.ts +2 -0
  39. package/dist/commands/judge/execute.d.ts.map +1 -1
  40. package/dist/commands/judge/execute.js +27 -2
  41. package/dist/commands/judge/generate.d.ts.map +1 -1
  42. package/dist/commands/judge/generate.js +9 -4
  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 +12 -5
  47. package/dist/commands/otel-filter/create.d.ts.map +1 -1
  48. package/dist/commands/otel-filter/create.js +6 -6
  49. package/dist/commands/project/create.d.ts +3 -0
  50. package/dist/commands/project/create.d.ts.map +1 -0
  51. package/dist/commands/project/create.js +31 -0
  52. package/dist/commands/project/delete.d.ts +3 -0
  53. package/dist/commands/project/delete.d.ts.map +1 -0
  54. package/dist/commands/project/delete.js +37 -0
  55. package/dist/commands/project/get.d.ts +3 -0
  56. package/dist/commands/project/get.d.ts.map +1 -0
  57. package/dist/commands/project/get.js +23 -0
  58. package/dist/commands/project/index.d.ts +3 -0
  59. package/dist/commands/project/index.d.ts.map +1 -0
  60. package/dist/commands/project/index.js +17 -0
  61. package/dist/commands/project/list.d.ts +3 -0
  62. package/dist/commands/project/list.d.ts.map +1 -0
  63. package/dist/commands/project/list.js +39 -0
  64. package/dist/commands/project/set-default.d.ts +3 -0
  65. package/dist/commands/project/set-default.d.ts.map +1 -0
  66. package/dist/commands/project/set-default.js +23 -0
  67. package/dist/commands/project/update.d.ts +3 -0
  68. package/dist/commands/project/update.d.ts.map +1 -0
  69. package/dist/commands/project/update.js +37 -0
  70. package/dist/commands/prompt-test/init.d.ts.map +1 -1
  71. package/dist/commands/prompt-test/init.js +9 -2
  72. package/dist/commands/prompt-test/run.d.ts +1 -1
  73. package/dist/commands/prompt-test/run.d.ts.map +1 -1
  74. package/dist/commands/prompt-test/run.js +9 -2
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2 -0
  77. package/dist/lib/filter-yaml.d.ts +8 -0
  78. package/dist/lib/filter-yaml.d.ts.map +1 -1
  79. package/dist/lib/filter-yaml.js +1 -1
  80. package/dist/lib/project-id.d.ts +9 -0
  81. package/dist/lib/project-id.d.ts.map +1 -0
  82. package/dist/lib/project-id.js +23 -0
  83. package/dist/output.d.ts +2 -1
  84. package/dist/output.d.ts.map +1 -1
  85. package/dist/output.js +71 -12
  86. package/dist/types.d.ts +1 -0
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/utils.d.ts +9 -0
  89. package/dist/utils.d.ts.map +1 -1
  90. package/dist/utils.js +27 -7
  91. 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;AAMpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA+E9D"}
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"}
@@ -1,6 +1,9 @@
1
1
  import ora from "ora";
2
+ import { z } from "zod";
2
3
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
4
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
5
+ import { parseJsonArg } from "../../utils.js";
6
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
7
  export function registerCreateCommand(evaluator) {
5
8
  evaluator
6
9
  .command("create")
@@ -12,6 +15,7 @@ export function registerCreateCommand(evaluator) {
12
15
  .option("--models <json>", "JSON array of model names, in priority order. E.g., '[\"gpt-5-mini\"]'")
13
16
  .option("--overwrite", "Overwrite if evaluator with same name exists")
14
17
  .option("--objective-version-id <id>", "Objective version ID")
18
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
15
19
  .action(async (opts) => {
16
20
  if (!opts.intent && !opts.objectiveId) {
17
21
  printError("Either --intent or --objective-id is required.");
@@ -36,14 +40,16 @@ export function registerCreateCommand(evaluator) {
36
40
  if (opts.objectiveVersionId)
37
41
  payload.objective_version_id = opts.objectiveVersionId;
38
42
  if (opts.models) {
39
- try {
40
- payload.models = JSON.parse(opts.models);
41
- }
42
- catch {
43
- printError("Invalid JSON format for --models.");
43
+ const r = parseJsonArg(opts.models, z.array(z.string()));
44
+ if (!r.ok) {
45
+ printError("Invalid JSON format for --models. Expected an array of model name strings.");
44
46
  return;
45
47
  }
48
+ payload.models = r.value;
46
49
  }
50
+ const projectId = resolveProjectIdValue(opts.projectId);
51
+ if (projectId !== undefined)
52
+ payload.projectId = projectId;
47
53
  const spinner = ora("Creating...").start();
48
54
  try {
49
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);
@@ -4,6 +4,7 @@ export declare function executeEvaluatorByName(evaluatorName: string, opts: {
4
4
  request?: string;
5
5
  response?: string;
6
6
  turns?: string;
7
+ tools?: string;
7
8
  contexts?: string;
8
9
  expectedOutput?: string;
9
10
  tag?: string[];
@@ -11,6 +12,7 @@ export declare function executeEvaluatorByName(evaluatorName: string, opts: {
11
12
  sessionId?: string;
12
13
  systemPrompt?: string;
13
14
  variables?: string;
15
+ projectId?: string;
14
16
  }, readStdin?: typeof readStdinDefault): Promise<void>;
15
17
  export declare function registerExecuteByNameCommand(evaluator: Command): void;
16
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,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,CA2Ef;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA4ErE"}
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"}
@@ -1,7 +1,8 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
4
- import { isTurnArray, isStringArray, isStringRecord } from "../../utils.js";
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)
@@ -47,6 +48,20 @@ export async function executeEvaluatorByName(evaluatorName, opts, readStdin = re
47
48
  return;
48
49
  }
49
50
  }
51
+ if (opts.tools) {
52
+ try {
53
+ const parsed = JSON.parse(opts.tools);
54
+ if (!isToolCatalog(parsed)) {
55
+ printError("Invalid JSON for --tools. Expected array of tool objects.");
56
+ return;
57
+ }
58
+ payload.tools = parsed;
59
+ }
60
+ catch {
61
+ printError("Invalid JSON for --tools.");
62
+ return;
63
+ }
64
+ }
50
65
  if (opts.contexts) {
51
66
  try {
52
67
  const parsed = JSON.parse(opts.contexts);
@@ -75,6 +90,9 @@ export async function executeEvaluatorByName(evaluatorName, opts, readStdin = re
75
90
  return;
76
91
  }
77
92
  }
93
+ const projectId = resolveProjectIdValue(opts.projectId);
94
+ if (projectId !== undefined)
95
+ payload.projectId = projectId;
78
96
  const spinner = ora("Running evaluator...").start();
79
97
  try {
80
98
  const client = getSdkClient(apiKey);
@@ -100,8 +118,10 @@ export function registerExecuteByNameCommand(evaluator) {
100
118
  .option("--user-id <id>", "User identifier for tracking purposes")
101
119
  .option("--session-id <id>", "Session identifier for tracking purposes")
102
120
  .option("--system-prompt <text>", "System prompt that was used for the LLM call")
103
- .option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
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"}]\'')
122
+ .option("--tools <json>", "JSON array of OpenAI-style tool definitions available to the agent.")
104
123
  .option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
124
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
105
125
  .addHelpText("after", `
106
126
  Examples:
107
127
  # Check helpfulness of a support response
@@ -124,6 +144,11 @@ Examples:
124
144
  $ scorable evaluator execute-by-name "Helpfulness" \\
125
145
  --turns '[{"role":"user","content":"Hello, I need help with my order"},{"role":"assistant","content":"I\\'d be happy to help! What\\'s your order number?"},{"role":"user","content":"It\\'s ORDER-12345"}]'
126
146
 
147
+ # Tool-aware evaluation: assistant tool_calls + tool-role result + tool catalog
148
+ $ scorable evaluator execute-by-name "Tool Selection" \\
149
+ --turns '[{"role":"user","content":"What is the weather in Paris?"},{"role":"assistant","content":null,"tool_calls":[{"id":"call_1","type":"function","function":{"name":"get_weather","arguments":"{\\"city\\":\\"Paris\\"}"}}]},{"role":"tool","tool_call_id":"call_1","content":"{\\"temp\\":12}"},{"role":"assistant","content":"It is 12C in Paris."}]' \\
150
+ --tools '[{"type":"function","function":{"name":"get_weather","description":"Get weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}}}}}]'
151
+
127
152
  # Pipe a response from your app via stdin
128
153
  $ ./my-app respond "Do you offer refunds?" | \\
129
154
  scorable evaluator execute-by-name "Helpfulness" --request "Do you offer refunds?"`)
@@ -4,6 +4,7 @@ export declare function executeEvaluator(evaluatorId: string, opts: {
4
4
  request?: string;
5
5
  response?: string;
6
6
  turns?: string;
7
+ tools?: string;
7
8
  contexts?: string;
8
9
  expectedOutput?: string;
9
10
  tag?: string[];
@@ -12,6 +13,7 @@ export declare function executeEvaluator(evaluatorId: string, opts: {
12
13
  systemPrompt?: string;
13
14
  variables?: string;
14
15
  fileIds?: string;
16
+ projectId?: string;
15
17
  }, readStdin?: typeof readStdinDefault): Promise<void>;
16
18
  export declare function registerExecuteCommand(evaluator: Command): void;
17
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,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,CAwFf;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CA2F/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"}
@@ -1,7 +1,8 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printSuccess, printError, printJson, handleSdkError } from "../../output.js";
4
- import { isTurnArray, isStringArray, isStringRecord } from "../../utils.js";
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)
@@ -47,6 +48,20 @@ export async function executeEvaluator(evaluatorId, opts, readStdin = readStdinD
47
48
  return;
48
49
  }
49
50
  }
51
+ if (opts.tools) {
52
+ try {
53
+ const parsed = JSON.parse(opts.tools);
54
+ if (!isToolCatalog(parsed)) {
55
+ printError("Invalid JSON for --tools. Expected array of tool objects.");
56
+ return;
57
+ }
58
+ payload.tools = parsed;
59
+ }
60
+ catch {
61
+ printError("Invalid JSON for --tools.");
62
+ return;
63
+ }
64
+ }
50
65
  if (opts.contexts) {
51
66
  try {
52
67
  const parsed = JSON.parse(opts.contexts);
@@ -88,6 +103,9 @@ export async function executeEvaluator(evaluatorId, opts, readStdin = readStdinD
88
103
  }
89
104
  payload.file_ids = parsed;
90
105
  }
106
+ const projectId = resolveProjectIdValue(opts.projectId);
107
+ if (projectId !== undefined)
108
+ payload.projectId = projectId;
91
109
  const spinner = ora("Running evaluator...").start();
92
110
  try {
93
111
  const client = getSdkClient(apiKey);
@@ -113,9 +131,11 @@ export function registerExecuteCommand(evaluator) {
113
131
  .option("--user-id <id>", "User identifier for tracking purposes")
114
132
  .option("--session-id <id>", "Session identifier for tracking purposes")
115
133
  .option("--system-prompt <text>", "System prompt that was used for the LLM call")
116
- .option("--turns <json>", 'JSON array of conversation turns. E.g., \'[{"role":"user","content":"Hello"}]\'')
134
+ .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"}]\'')
135
+ .option("--tools <json>", "JSON array of OpenAI-style tool definitions available to the agent.")
117
136
  .option("--variables <json>", 'JSON object of extra template variables. E.g., \'{"lang":"EN"}\'')
118
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)
119
139
  .addHelpText("after", `
120
140
  Examples:
121
141
  # Check helpfulness of a support response
@@ -139,6 +159,11 @@ Examples:
139
159
  $ scorable evaluator execute <evaluatorId> \\
140
160
  --turns '[{"role":"user","content":"Hello, I need help with my order"},{"role":"assistant","content":"I\\'d be happy to help! What\\'s your order number?"},{"role":"user","content":"It\\'s ORDER-12345"},{"role":"assistant","content":"I found your order. It\\'s currently in transit."}]'
141
161
 
162
+ # Tool-aware evaluation: assistant tool_calls, tool-role result, and tool catalog
163
+ $ scorable evaluator execute <evaluatorId> \\
164
+ --turns '[{"role":"user","content":"What is the weather in Paris?"},{"role":"assistant","content":null,"tool_calls":[{"id":"call_1","type":"function","function":{"name":"get_weather","arguments":"{\\"city\\":\\"Paris\\"}"}}]},{"role":"tool","tool_call_id":"call_1","content":"{\\"temp\\":12}"},{"role":"assistant","content":"It is 12C in Paris."}]' \\
165
+ --tools '[{"type":"function","function":{"name":"get_weather","description":"Get weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}}}}}]'
166
+
142
167
  # With custom template variables and tracking
143
168
  $ scorable evaluator execute <evaluatorId> \\
144
169
  --request "How do I cancel my subscription?" \\
@@ -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;AAMpC,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAwD9D"}
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"}
@@ -1,6 +1,9 @@
1
1
  import ora from "ora";
2
+ import { z } from "zod";
2
3
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
4
  import { printInfo, printSuccess, printError, printJson, handleSdkError } from "../../output.js";
5
+ import { parseJsonArg } from "../../utils.js";
6
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
7
  export function registerUpdateCommand(evaluator) {
5
8
  evaluator
6
9
  .command("update <evaluatorId>")
@@ -10,6 +13,7 @@ export function registerUpdateCommand(evaluator) {
10
13
  .option("--models <json>", "JSON array of model names. E.g., '[\"gpt-5.5\"]'")
11
14
  .option("--objective-id <id>", "The new objective ID")
12
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)
13
17
  .action(async (evaluatorId, opts) => {
14
18
  const apiKey = await requireApiKey();
15
19
  const payload = {};
@@ -22,14 +26,16 @@ export function registerUpdateCommand(evaluator) {
22
26
  if (opts.objectiveVersionId !== undefined)
23
27
  payload.objective_version_id = opts.objectiveVersionId;
24
28
  if (opts.models !== undefined) {
25
- try {
26
- payload.models = JSON.parse(opts.models);
27
- }
28
- catch {
29
- printError("Invalid JSON format for --models.");
29
+ const r = parseJsonArg(opts.models, z.array(z.string()));
30
+ if (!r.ok) {
31
+ printError("Invalid JSON format for --models. Expected an array of model name strings.");
30
32
  return;
31
33
  }
34
+ payload.models = r.value;
32
35
  }
36
+ const projectId = resolveProjectIdValue(opts.projectId);
37
+ if (projectId !== undefined)
38
+ payload.projectId = projectId;
33
39
  if (Object.keys(payload).length === 0) {
34
40
  printInfo("No update parameters provided. Aborting.");
35
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;AAMpC,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"}