@root-signals/scorable-cli 0.13.0 → 0.15.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 (97) hide show
  1. package/README.md +113 -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/annotation/index.d.ts +3 -0
  6. package/dist/commands/annotation/index.d.ts.map +1 -0
  7. package/dist/commands/annotation/index.js +145 -0
  8. package/dist/commands/auth/index.d.ts.map +1 -1
  9. package/dist/commands/auth/index.js +68 -1
  10. package/dist/commands/calibration-run/index.d.ts +3 -0
  11. package/dist/commands/calibration-run/index.d.ts.map +1 -0
  12. package/dist/commands/calibration-run/index.js +83 -0
  13. package/dist/commands/dataset-item/index.d.ts +3 -0
  14. package/dist/commands/dataset-item/index.d.ts.map +1 -0
  15. package/dist/commands/dataset-item/index.js +160 -0
  16. package/dist/commands/evaluator/calibrate.d.ts +3 -0
  17. package/dist/commands/evaluator/calibrate.d.ts.map +1 -0
  18. package/dist/commands/evaluator/calibrate.js +29 -0
  19. package/dist/commands/evaluator/create.d.ts.map +1 -1
  20. package/dist/commands/evaluator/create.js +8 -0
  21. package/dist/commands/evaluator/duplicate.d.ts.map +1 -1
  22. package/dist/commands/evaluator/duplicate.js +5 -2
  23. package/dist/commands/evaluator/execute-by-name.d.ts +1 -0
  24. package/dist/commands/evaluator/execute-by-name.d.ts.map +1 -1
  25. package/dist/commands/evaluator/execute-by-name.js +5 -0
  26. package/dist/commands/evaluator/execute.d.ts +1 -0
  27. package/dist/commands/evaluator/execute.d.ts.map +1 -1
  28. package/dist/commands/evaluator/execute.js +5 -0
  29. package/dist/commands/evaluator/export-yaml.d.ts.map +1 -1
  30. package/dist/commands/evaluator/export-yaml.js +10 -1
  31. package/dist/commands/evaluator/import-yaml.d.ts.map +1 -1
  32. package/dist/commands/evaluator/import-yaml.js +10 -1
  33. package/dist/commands/evaluator/index.d.ts.map +1 -1
  34. package/dist/commands/evaluator/index.js +2 -0
  35. package/dist/commands/evaluator/list.d.ts.map +1 -1
  36. package/dist/commands/evaluator/list.js +5 -0
  37. package/dist/commands/evaluator/update.d.ts.map +1 -1
  38. package/dist/commands/evaluator/update.js +8 -0
  39. package/dist/commands/execution-log/list.d.ts.map +1 -1
  40. package/dist/commands/execution-log/list.js +5 -0
  41. package/dist/commands/judge/create.d.ts.map +1 -1
  42. package/dist/commands/judge/create.js +5 -0
  43. package/dist/commands/judge/duplicate.d.ts.map +1 -1
  44. package/dist/commands/judge/duplicate.js +5 -2
  45. package/dist/commands/judge/exec-openai-generic.d.ts.map +1 -1
  46. package/dist/commands/judge/exec-openai-generic.js +5 -0
  47. package/dist/commands/judge/exec-openai.d.ts.map +1 -1
  48. package/dist/commands/judge/exec-openai.js +5 -0
  49. package/dist/commands/judge/execute-by-name.d.ts +1 -0
  50. package/dist/commands/judge/execute-by-name.d.ts.map +1 -1
  51. package/dist/commands/judge/execute-by-name.js +5 -0
  52. package/dist/commands/judge/execute.d.ts +1 -0
  53. package/dist/commands/judge/execute.d.ts.map +1 -1
  54. package/dist/commands/judge/execute.js +5 -0
  55. package/dist/commands/judge/generate.d.ts.map +1 -1
  56. package/dist/commands/judge/generate.js +4 -0
  57. package/dist/commands/judge/list.d.ts.map +1 -1
  58. package/dist/commands/judge/list.js +5 -0
  59. package/dist/commands/judge/update.d.ts.map +1 -1
  60. package/dist/commands/judge/update.js +5 -0
  61. package/dist/commands/project/create.d.ts +3 -0
  62. package/dist/commands/project/create.d.ts.map +1 -0
  63. package/dist/commands/project/create.js +31 -0
  64. package/dist/commands/project/delete.d.ts +3 -0
  65. package/dist/commands/project/delete.d.ts.map +1 -0
  66. package/dist/commands/project/delete.js +37 -0
  67. package/dist/commands/project/get.d.ts +3 -0
  68. package/dist/commands/project/get.d.ts.map +1 -0
  69. package/dist/commands/project/get.js +23 -0
  70. package/dist/commands/project/index.d.ts +3 -0
  71. package/dist/commands/project/index.d.ts.map +1 -0
  72. package/dist/commands/project/index.js +17 -0
  73. package/dist/commands/project/list.d.ts +3 -0
  74. package/dist/commands/project/list.d.ts.map +1 -0
  75. package/dist/commands/project/list.js +39 -0
  76. package/dist/commands/project/set-default.d.ts +3 -0
  77. package/dist/commands/project/set-default.d.ts.map +1 -0
  78. package/dist/commands/project/set-default.js +23 -0
  79. package/dist/commands/project/update.d.ts +3 -0
  80. package/dist/commands/project/update.d.ts.map +1 -0
  81. package/dist/commands/project/update.js +37 -0
  82. package/dist/commands/prompt-test/init.d.ts.map +1 -1
  83. package/dist/commands/prompt-test/init.js +9 -2
  84. package/dist/commands/prompt-test/run.d.ts +1 -1
  85. package/dist/commands/prompt-test/run.d.ts.map +1 -1
  86. package/dist/commands/prompt-test/run.js +9 -2
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +8 -0
  89. package/dist/lib/project-id.d.ts +9 -0
  90. package/dist/lib/project-id.d.ts.map +1 -0
  91. package/dist/lib/project-id.js +23 -0
  92. package/dist/output.d.ts +2 -1
  93. package/dist/output.d.ts.map +1 -1
  94. package/dist/output.js +71 -12
  95. package/dist/types.d.ts +1 -0
  96. package/dist/types.d.ts.map +1 -1
  97. package/package.json +4 -4
@@ -4,6 +4,7 @@ import { z } from "zod";
4
4
  import { requireApiKey, getSdkClient } from "../../auth.js";
5
5
  import { printSuccess, printError, printWarning, printInfo, printJson, handleSdkError, } from "../../output.js";
6
6
  import { parseJsonArg } from "../../utils.js";
7
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
7
8
  import { CliError } from "../../types.js";
8
9
  import { uploadFile } from "../file/upload.js";
9
10
  export function registerGenerateCommand(judge) {
@@ -28,6 +29,7 @@ offer to connect the guest with a human agent when uncertain."`)
28
29
  .option("--context-aware", "Enable context-aware evaluators for RAG applications (hallucination detection, context drift, etc.)", false)
29
30
  .option("--file <path>", "Path to a file (PDF, PNG, JPG) to upload and attach as context for the judge")
30
31
  .option("--file-id <id>", "ID of an already-uploaded file to use as context for the judge")
32
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
31
33
  .action(async (opts) => {
32
34
  const acceptedVisibilities = ["private", "public"];
33
35
  const visibility = opts.visibility;
@@ -57,6 +59,7 @@ offer to connect the guest with a human agent when uncertain."`)
57
59
  fileId = uploaded.id;
58
60
  }
59
61
  const client = getSdkClient(apiKey);
62
+ const projectId = resolveProjectIdValue(opts.projectId);
60
63
  const result = (await client.judges.generate({
61
64
  intent: opts.intent,
62
65
  visibility: visibility,
@@ -67,6 +70,7 @@ offer to connect the guest with a human agent when uncertain."`)
67
70
  file_id: fileId,
68
71
  extra_contexts: extra_contexts ?? null,
69
72
  enable_context_aware_evaluators: opts.contextAware || undefined,
73
+ ...(projectId !== undefined ? { projectId } : {}),
70
74
  ...(opts.reasoningEffort && {
71
75
  generating_model_params: {
72
76
  reasoning_effort: opts.reasoningEffort,
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA4CxD"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAgDxD"}
@@ -1,6 +1,7 @@
1
1
  import ora from "ora";
2
2
  import { requireApiKey, getSdkClient } from "../../auth.js";
3
3
  import { printMessage, printJudgeTable, handleSdkError } from "../../output.js";
4
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
4
5
  export function registerListCommand(judge) {
5
6
  judge
6
7
  .command("list")
@@ -10,6 +11,7 @@ export function registerListCommand(judge) {
10
11
  .option("--search <term>", "A search term to filter by")
11
12
  .option("--name <name>", "Filter by exact judge 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(judge) {
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/judge/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAkD1D"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/judge/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CA8D1D"}
@@ -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
  const EvaluatorRefsSchema = z.array(z.object({ id: z.string() }).passthrough());
7
8
  export function registerUpdateCommand(judge) {
8
9
  judge
@@ -11,6 +12,7 @@ export function registerUpdateCommand(judge) {
11
12
  .option("--name <name>", "The new name for the judge")
12
13
  .option("--stage <stage>", "The new stage for the judge")
13
14
  .option("--evaluator-references <json>", 'JSON string to update evaluator references. Use "[]" to clear.')
15
+ .option("--project-id <uuid>", "Move the judge to this project (within the same organization). " + PROJECT_ID_FLAG_DESC)
14
16
  .action(async (judgeId, opts) => {
15
17
  const apiKey = await requireApiKey();
16
18
  const payload = {};
@@ -26,6 +28,9 @@ export function registerUpdateCommand(judge) {
26
28
  }
27
29
  payload.evaluator_references = r.value;
28
30
  }
31
+ const projectId = resolveProjectIdValue(opts.projectId);
32
+ if (projectId !== undefined)
33
+ payload.projectId = projectId;
29
34
  if (Object.keys(payload).length === 0) {
30
35
  printInfo("No update parameters provided. Aborting.");
31
36
  return;
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerCreateCommand(project: Command): void;
3
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/project/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8B5D"}
@@ -0,0 +1,31 @@
1
+ import ora from "ora";
2
+ import { requireApiKey, getSdkClient } from "../../auth.js";
3
+ import { printSuccess, printJson, handleSdkError } from "../../output.js";
4
+ export function registerCreateCommand(project) {
5
+ project
6
+ .command("create")
7
+ .description("Create a new project")
8
+ .requiredOption("--name <name>", "Project name")
9
+ .option("--description <text>", "Project description")
10
+ .option("--is-default", "Mark this project as the org default (atomically clears any previous default).", false)
11
+ .action(async (opts) => {
12
+ const apiKey = await requireApiKey();
13
+ const payload = { name: opts.name };
14
+ if (opts.description !== undefined)
15
+ payload.description = opts.description;
16
+ if (opts.isDefault)
17
+ payload.is_default = true;
18
+ const spinner = ora("Creating...").start();
19
+ try {
20
+ const client = getSdkClient(apiKey);
21
+ const result = await client.projects.create(payload);
22
+ spinner.stop();
23
+ printSuccess("Project created successfully!");
24
+ printJson(result);
25
+ }
26
+ catch (e) {
27
+ spinner.stop();
28
+ handleSdkError(e);
29
+ }
30
+ });
31
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerDeleteCommand(project: Command): void;
3
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/project/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoC5D"}
@@ -0,0 +1,37 @@
1
+ import ora from "ora";
2
+ import { requireApiKey, getSdkClient } from "../../auth.js";
3
+ import { printSuccess, handleSdkError } from "../../output.js";
4
+ import { CliError } from "../../types.js";
5
+ export function registerDeleteCommand(project) {
6
+ project
7
+ .command("delete <projectId>")
8
+ .description("Delete a project by its ID")
9
+ .option("--yes", "Skip confirmation prompt")
10
+ .action(async (projectId, opts) => {
11
+ const apiKey = await requireApiKey();
12
+ if (!opts.yes) {
13
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
14
+ throw new CliError(1, "Refusing to prompt for confirmation in a non-interactive environment. Pass --yes to skip the prompt.");
15
+ }
16
+ const { confirm } = await import("@inquirer/prompts");
17
+ const ok = await confirm({
18
+ message: "Are you sure you want to delete this project?",
19
+ default: false,
20
+ });
21
+ if (!ok) {
22
+ throw new CliError(1, "Aborted");
23
+ }
24
+ }
25
+ const spinner = ora("Deleting...").start();
26
+ try {
27
+ const client = getSdkClient(apiKey);
28
+ await client.projects.delete(projectId);
29
+ spinner.stop();
30
+ printSuccess(`Project ${projectId} deleted successfully.`);
31
+ }
32
+ catch (e) {
33
+ spinner.stop();
34
+ handleSdkError(e);
35
+ }
36
+ });
37
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerGetCommand(project: Command): void;
3
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/project/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkBzD"}
@@ -0,0 +1,23 @@
1
+ import ora from "ora";
2
+ import { requireApiKey, getSdkClient } from "../../auth.js";
3
+ import { printSuccess, printJson, handleSdkError } from "../../output.js";
4
+ export function registerGetCommand(project) {
5
+ project
6
+ .command("get <projectId>")
7
+ .description("Get a specific project by its ID")
8
+ .action(async (projectId) => {
9
+ const apiKey = await requireApiKey();
10
+ const spinner = ora("Fetching...").start();
11
+ try {
12
+ const client = getSdkClient(apiKey);
13
+ const result = await client.projects.retrieve(projectId);
14
+ spinner.stop();
15
+ printSuccess(`Project '${result.name}' details:`);
16
+ printJson(result);
17
+ }
18
+ catch (e) {
19
+ spinner.stop();
20
+ handleSdkError(e);
21
+ }
22
+ });
23
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerProjectCommands(program: Command): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/project/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAW9D"}
@@ -0,0 +1,17 @@
1
+ import { Command } from "commander";
2
+ import { registerListCommand } from "./list.js";
3
+ import { registerGetCommand } from "./get.js";
4
+ import { registerCreateCommand } from "./create.js";
5
+ import { registerUpdateCommand } from "./update.js";
6
+ import { registerDeleteCommand } from "./delete.js";
7
+ import { registerSetDefaultCommand } from "./set-default.js";
8
+ export function registerProjectCommands(program) {
9
+ const project = new Command("project").description("Project management commands");
10
+ registerListCommand(project);
11
+ registerGetCommand(project);
12
+ registerCreateCommand(project);
13
+ registerUpdateCommand(project);
14
+ registerDeleteCommand(project);
15
+ registerSetDefaultCommand(project);
16
+ program.addCommand(project);
17
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerListCommand(project: Command): void;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/project/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoC1D"}
@@ -0,0 +1,39 @@
1
+ import ora from "ora";
2
+ import { requireApiKey, getSdkClient } from "../../auth.js";
3
+ import { printMessage, printProjectTable, handleSdkError } from "../../output.js";
4
+ export function registerListCommand(project) {
5
+ project
6
+ .command("list")
7
+ .description("List projects in your organization")
8
+ .option("--page-size <number>", "Number of results to return per page", (v) => parseInt(v, 10))
9
+ .option("--cursor <cursor>", "The pagination cursor value")
10
+ .option("--search <term>", "A search term to filter by")
11
+ .option("--ordering <field>", "Which field to use for ordering the results")
12
+ .action(async (opts) => {
13
+ const apiKey = await requireApiKey();
14
+ const params = {};
15
+ if (opts.pageSize !== undefined)
16
+ params.page_size = opts.pageSize;
17
+ if (opts.cursor !== undefined)
18
+ params.cursor = opts.cursor;
19
+ if (opts.search !== undefined)
20
+ params.search = opts.search;
21
+ if (opts.ordering !== undefined)
22
+ params.ordering = opts.ordering;
23
+ const spinner = ora("Fetching...").start();
24
+ try {
25
+ const client = getSdkClient(apiKey);
26
+ const response = await client.projects.list(params);
27
+ spinner.stop();
28
+ if (!response.results.length) {
29
+ printMessage("No projects found.");
30
+ return;
31
+ }
32
+ printProjectTable(response.results, response.next);
33
+ }
34
+ catch (e) {
35
+ spinner.stop();
36
+ handleSdkError(e);
37
+ }
38
+ });
39
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerSetDefaultCommand(project: Command): void;
3
+ //# sourceMappingURL=set-default.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-default.d.ts","sourceRoot":"","sources":["../../../src/commands/project/set-default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkBhE"}
@@ -0,0 +1,23 @@
1
+ import ora from "ora";
2
+ import { requireApiKey, getSdkClient } from "../../auth.js";
3
+ import { printSuccess, printJson, handleSdkError } from "../../output.js";
4
+ export function registerSetDefaultCommand(project) {
5
+ project
6
+ .command("set-default <projectId>")
7
+ .description("Promote a project to the org default. Atomically clears the previous default.")
8
+ .action(async (projectId) => {
9
+ const apiKey = await requireApiKey();
10
+ const spinner = ora("Updating default project...").start();
11
+ try {
12
+ const client = getSdkClient(apiKey);
13
+ const result = await client.projects.update(projectId, { is_default: true });
14
+ spinner.stop();
15
+ printSuccess(`Project ${projectId} is now the org default.`);
16
+ printJson(result);
17
+ }
18
+ catch (e) {
19
+ spinner.stop();
20
+ handleSdkError(e);
21
+ }
22
+ });
23
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerUpdateCommand(project: Command): void;
3
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/project/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyC5D"}
@@ -0,0 +1,37 @@
1
+ import ora from "ora";
2
+ import { requireApiKey, getSdkClient } from "../../auth.js";
3
+ import { printSuccess, printInfo, printJson, handleSdkError } from "../../output.js";
4
+ export function registerUpdateCommand(project) {
5
+ project
6
+ .command("update <projectId>")
7
+ .description("Update an existing project (PATCH)")
8
+ .option("--name <name>", "New project name")
9
+ .option("--description <text>", "New project description")
10
+ .option("--is-default", "Promote this project to org default. Atomically clears the previous default. Clearing the default directly is not supported by the backend; promote another project instead.", false)
11
+ .action(async (projectId, opts) => {
12
+ const apiKey = await requireApiKey();
13
+ const payload = {};
14
+ if (opts.name !== undefined)
15
+ payload.name = opts.name;
16
+ if (opts.description !== undefined)
17
+ payload.description = opts.description;
18
+ if (opts.isDefault)
19
+ payload.is_default = true;
20
+ if (Object.keys(payload).length === 0) {
21
+ printInfo("No update parameters provided. Aborting.");
22
+ return;
23
+ }
24
+ const spinner = ora("Updating...").start();
25
+ try {
26
+ const client = getSdkClient(apiKey);
27
+ const result = await client.projects.update(projectId, payload);
28
+ spinner.stop();
29
+ printSuccess(`Project ${projectId} updated successfully!`);
30
+ printJson(result);
31
+ }
32
+ catch (e) {
33
+ spinner.stop();
34
+ handleSdkError(e);
35
+ }
36
+ });
37
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/prompt-test/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqDpC,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CA6BrD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/prompt-test/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4DpC,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CA8BrD"}
@@ -1,5 +1,6 @@
1
1
  import { writeFileSync, existsSync } from "node:fs";
2
2
  import { printWarning, printSuccess, printInfo, printError } from "../../output.js";
3
+ import { PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
3
4
  const TEMPLATE = `# Prompt Testing Configuration
4
5
  # This file defines a test suite of prompt and model combinations, with optional evaluators.
5
6
 
@@ -48,10 +49,16 @@ evaluators:
48
49
  # description: "The username of the user. Must start with @"
49
50
  # additionalProperties: false
50
51
  `;
52
+ function buildTemplate(projectId) {
53
+ if (!projectId)
54
+ return TEMPLATE;
55
+ return `${TEMPLATE}\n# Project to assign prompt-test runs to. Override per-run with \`--project-id\`.\nproject_id: "${projectId}"\n`;
56
+ }
51
57
  export function registerInitCommand(pt) {
52
58
  pt.command("init")
53
59
  .description("Initializes a new prompt-tests.yaml file in the current directory")
54
- .action(async () => {
60
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC)
61
+ .action(async (opts) => {
55
62
  const configPath = "prompt-tests.yaml";
56
63
  if (existsSync(configPath)) {
57
64
  printWarning(`'${configPath}' already exists in the current directory.`);
@@ -66,7 +73,7 @@ export function registerInitCommand(pt) {
66
73
  }
67
74
  }
68
75
  try {
69
- writeFileSync(configPath, TEMPLATE);
76
+ writeFileSync(configPath, buildTemplate(opts.projectId));
70
77
  printSuccess(`'${configPath}' created successfully.`);
71
78
  printInfo("Update the file with your prompt test details and run `pt run`.");
72
79
  }
@@ -1,4 +1,4 @@
1
1
  import { Command } from "commander";
2
- export declare function runPromptTests(outputFile: string | undefined, configPath: string, sleep?: (ms: number) => Promise<void>): Promise<void>;
2
+ export declare function runPromptTests(outputFile: string | undefined, configPath: string, sleep?: (ms: number) => Promise<void>, projectIdOverride?: string): Promise<void>;
3
3
  export declare function registerRunCommand(pt: Command): void;
4
4
  //# sourceMappingURL=run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/prompt-test/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6GpC,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAiD,GACnF,OAAO,CAAC,IAAI,CAAC,CAiHf;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAYpD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/prompt-test/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8GpC,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAiD,EACpF,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Hf;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAapD"}
@@ -23,6 +23,7 @@ const UNICODE_CHARS = {
23
23
  middle: "│",
24
24
  };
25
25
  import { CliError } from "../../types.js";
26
+ import { resolveProjectIdValue, PROJECT_ID_FLAG_DESC } from "../../lib/project-id.js";
26
27
  function isPromptTestComplete(exp) {
27
28
  if (!exp.tasks.length)
28
29
  return false;
@@ -93,7 +94,7 @@ function displayAggregatedResults(experiments) {
93
94
  }
94
95
  console.log(table.toString());
95
96
  }
96
- export async function runPromptTests(outputFile, configPath, sleep = (ms) => new Promise((r) => setTimeout(r, ms))) {
97
+ export async function runPromptTests(outputFile, configPath, sleep = (ms) => new Promise((r) => setTimeout(r, ms)), projectIdOverride) {
97
98
  let rawConfig;
98
99
  try {
99
100
  rawConfig = yaml.load(readFileSync(configPath, "utf8"));
@@ -118,6 +119,9 @@ export async function runPromptTests(outputFile, configPath, sleep = (ms) => new
118
119
  }
119
120
  const apiKey = await requireApiKey();
120
121
  printInfo("Starting prompt tests");
122
+ const resolvedProjectId = projectIdOverride !== undefined
123
+ ? resolveProjectIdValue(projectIdOverride)
124
+ : (config.project_id ?? resolveProjectIdValue(undefined));
121
125
  const experiments = {};
122
126
  for (const prompt of config.prompts) {
123
127
  for (const model of config.models) {
@@ -141,6 +145,8 @@ export async function runPromptTests(outputFile, configPath, sleep = (ms) => new
141
145
  payload["response_schema"] = config.response_schema;
142
146
  if (config.dataset_id)
143
147
  payload["dataset_id"] = config.dataset_id;
148
+ if (resolvedProjectId !== undefined)
149
+ payload["project_id"] = resolvedProjectId;
144
150
  const result = (await apiRequest("POST", "prompt-tests", {
145
151
  payload,
146
152
  apiKey,
@@ -200,9 +206,10 @@ export function registerRunCommand(pt) {
200
206
  .description("Runs prompt tests from the prompt-tests.yaml file")
201
207
  .option("-o, --output <path>", "Output file path to save prompt test results as JSON")
202
208
  .option("-c, --config <path>", "Path to prompt testing configuration file", "prompt-tests.yaml")
209
+ .option("--project-id <uuid>", PROJECT_ID_FLAG_DESC + " Overrides project_id from config file.")
203
210
  .action(async (opts) => {
204
211
  try {
205
- await runPromptTests(opts.output, opts.config);
212
+ await runPromptTests(opts.output, opts.config, undefined, opts.projectId);
206
213
  }
207
214
  catch (e) {
208
215
  handleSdkError(e);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDpC,wBAAgB,SAAS,IAAI,OAAO,CA+BnC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwDpC,wBAAgB,SAAS,IAAI,OAAO,CAmCnC"}
package/dist/index.js CHANGED
@@ -14,6 +14,10 @@ import { registerFileCommands } from "./commands/file/index.js";
14
14
  import { registerOtelFilterCommands } from "./commands/otel-filter/index.js";
15
15
  import { registerOtelTraceCommands } from "./commands/otel-trace/index.js";
16
16
  import { registerModelCommands } from "./commands/model/index.js";
17
+ import { registerProjectCommands } from "./commands/project/index.js";
18
+ import { registerAnnotationCommands } from "./commands/annotation/index.js";
19
+ import { registerCalibrationRunCommands } from "./commands/calibration-run/index.js";
20
+ import { registerDatasetItemCommands } from "./commands/dataset-item/index.js";
17
21
  const { version } = createRequire(import.meta.url)("../package.json");
18
22
  function buildBanner(ver) {
19
23
  const logo = chalk.hex("#4D9FFF");
@@ -76,6 +80,10 @@ export function createCli() {
76
80
  registerOtelFilterCommands(program);
77
81
  registerOtelTraceCommands(program);
78
82
  registerModelCommands(program);
83
+ registerProjectCommands(program);
84
+ registerAnnotationCommands(program);
85
+ registerCalibrationRunCommands(program);
86
+ registerDatasetItemCommands(program);
79
87
  return program;
80
88
  }
81
89
  if (realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
@@ -0,0 +1,9 @@
1
+ export type ProjectIdSource = "flag" | "env" | "settings" | "none";
2
+ export interface ResolvedProjectId {
3
+ value: string | undefined;
4
+ source: ProjectIdSource;
5
+ }
6
+ export declare function resolveProjectId(flagValue?: string): ResolvedProjectId;
7
+ export declare function resolveProjectIdValue(flagValue?: string): string | undefined;
8
+ export declare const PROJECT_ID_FLAG_DESC = "Project UUID to scope this operation. Pass \"\" to opt out of inherited defaults from SCORABLE_PROJECT_ID or ~/.scorable/settings.json.";
9
+ //# sourceMappingURL=project-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-id.d.ts","sourceRoot":"","sources":["../../src/lib/project-id.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAKhC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;CACzB;AAYD,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAqBtE;AAKD,wBAAgB,qBAAqB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE5E;AAKD,eAAO,MAAM,oBAAoB,4IACwG,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { loadSettings } from "../auth.js";
2
+ export function resolveProjectId(flagValue) {
3
+ if (flagValue !== undefined) {
4
+ if (flagValue === "") {
5
+ return { value: undefined, source: "flag" };
6
+ }
7
+ return { value: flagValue, source: "flag" };
8
+ }
9
+ const fromEnv = process.env["SCORABLE_PROJECT_ID"];
10
+ if (fromEnv !== undefined && fromEnv !== "") {
11
+ return { value: fromEnv, source: "env" };
12
+ }
13
+ const settings = loadSettings();
14
+ const fromSettings = settings["project_id"];
15
+ if (typeof fromSettings === "string" && fromSettings !== "") {
16
+ return { value: fromSettings, source: "settings" };
17
+ }
18
+ return { value: undefined, source: "none" };
19
+ }
20
+ export function resolveProjectIdValue(flagValue) {
21
+ return resolveProjectId(flagValue).value;
22
+ }
23
+ export const PROJECT_ID_FLAG_DESC = 'Project UUID to scope this operation. Pass "" to opt out of inherited defaults from SCORABLE_PROJECT_ID or ~/.scorable/settings.json.';
package/dist/output.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Judge, EvaluatorListItem, ExecutionLogList, ModelList } from "@root-signals/scorable";
1
+ import type { Judge, EvaluatorListItem, ExecutionLogList, ModelList, Project } from "@root-signals/scorable";
2
2
  export declare function printJson(data: unknown): void;
3
3
  export declare function printError(msg: string): void;
4
4
  export declare function handleSdkError(e: unknown): never;
@@ -8,6 +8,7 @@ export declare function printWarning(msg: string): void;
8
8
  export declare function printMessage(msg: string): void;
9
9
  export declare function printJudgeTable(judges: Judge[], nextCursor?: string): void;
10
10
  export declare function printEvaluatorTable(evaluators: EvaluatorListItem[], nextCursor?: string): void;
11
+ export declare function printProjectTable(projects: Project[], nextCursor?: string): void;
11
12
  export declare function printModelTable(models: ModelList[], nextCursor?: string): void;
12
13
  export declare function printExecutionLogTable(logs: ExecutionLogList[], nextCursor?: string): void;
13
14
  //# sourceMappingURL=output.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAoBpG,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAE7C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAKhD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAMD,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAmB1E;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAmB9F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAmB9E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAoB1F"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,KAAK,EACL,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,OAAO,EACR,MAAM,wBAAwB,CAAC;AAoBhC,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAE7C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAmBD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAgBhD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAUD,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAmB1E;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAmB9F;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAoBhF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAmB9E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CA6B1F"}