apiblaze 0.21.75 → 0.21.76

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 (2) hide show
  1. package/dist/index.js +36 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__
34
34
  var version;
35
35
  var init_package = __esm({
36
36
  "package.json"() {
37
- version = "0.21.75";
37
+ version = "0.21.76";
38
38
  }
39
39
  });
40
40
 
@@ -5577,6 +5577,7 @@ __export(directory_exports, {
5577
5577
  stepOpen: () => stepOpen,
5578
5578
  stepRunnable: () => stepRunnable,
5579
5579
  summaryOf: () => summaryOf,
5580
+ testCasesText: () => testCasesText,
5580
5581
  withBrandSource: () => withBrandSource,
5581
5582
  writeJsonLine: () => writeJsonLine
5582
5583
  });
@@ -5675,6 +5676,22 @@ function directoryBodyFromFlags(f2) {
5675
5676
  }
5676
5677
  return out;
5677
5678
  }
5679
+ function testCasesText(r, platforms) {
5680
+ const cases = r?.target?.metadata?.portalAnswers?.test_cases ?? [];
5681
+ if (!cases.length) return null;
5682
+ const dirs = ["claude", "chatgpt"].filter((x) => platforms.includes(x));
5683
+ const lines = ["Test cases (what reviewers try; results are our pre-check, not their review)"];
5684
+ for (const c of cases) {
5685
+ lines.push(` "${c.prompt}" (${c.kind === "refuse" ? "should say no" : c.tool ? `should use ${c.tool}` : "pick the tool it should use"})`);
5686
+ for (const dir of dirs) {
5687
+ const x = (r?.case_results ?? []).find((y) => y.caseId === c.id && y.directory === dir);
5688
+ const word = !x ? "not run yet" : !x.current ? "out of date, run again" : `${x.pass ? "\u2713" : "\u2717"} ${CASE_STATE[x.state]}${x.state === "other_tool" || x.state === "acted" ? `: ${x.tools.join(", ")}` : ""} \xB7 ${CASE_SOURCE[x.source]}, ${x.at.slice(0, 10)}`;
5689
+ lines.push(` for ${dir === "claude" ? "Claude" : "ChatGPT"}: ${word}`);
5690
+ }
5691
+ }
5692
+ lines.push(" Run them on the Testing tab, or with the Claude Code lines below.");
5693
+ return lines.join("\n");
5694
+ }
5678
5695
  function withBrandSource(url, cli = B.cli) {
5679
5696
  return cli === "mcpblaze" ? `${url}?source=mcpblazeCli` : url;
5680
5697
  }
@@ -5821,6 +5838,7 @@ function claudeCodeTests(r, proj2) {
5821
5838
  seen.add(p);
5822
5839
  cases.push({ prompt: p, line: askLine(name, p), expect, refuse });
5823
5840
  };
5841
+ for (const c of t?.metadata?.portalAnswers?.test_cases ?? []) add(c.prompt, c.kind === "refuse" ? `it says it can't help${c.why ? ` (${c.why})` : ""}, and calls no tool` : c.expect || "it calls your tools and answers from what comes back", c.kind === "refuse");
5824
5842
  for (const p of t?.metadata?.examplePrompts ?? []) add(p, "it calls your tools and answers from what comes back", false);
5825
5843
  const tc = t?.metadata?.portalAnswers?.chatgpt_test_cases;
5826
5844
  for (const c of tc?.positive ?? []) add(c.prompt, c.expected_behavior || "it calls your tools and answers from what comes back", false);
@@ -5840,7 +5858,7 @@ function claudeCodeText(cc) {
5840
5858
  else lines.push(` ${n}. One line per use case:`, ...cc.cases.flatMap((c) => [` ${c.line}`, ` expect: ${c.expect}`]));
5841
5859
  return lines.join("\n");
5842
5860
  }
5843
- var import_node_fs, import_chalk17, PLATFORMS, ATTESTATIONS, OPENAI_CATEGORIES, AUTH_MODES, DATA_HANDLING_MODES, STEP_IDS, reportPath, DESCRIPTION_MIN, ccServerName, shellQuote2, askLine;
5861
+ var import_node_fs, import_chalk17, PLATFORMS, ATTESTATIONS, OPENAI_CATEGORIES, AUTH_MODES, DATA_HANDLING_MODES, STEP_IDS, CASE_SOURCE, CASE_STATE, reportPath, DESCRIPTION_MIN, ccServerName, shellQuote2, askLine;
5844
5862
  var init_directory = __esm({
5845
5863
  "src/lib/directory.ts"() {
5846
5864
  "use strict";
@@ -5872,6 +5890,8 @@ var init_directory = __esm({
5872
5890
  AUTH_MODES = ["signin", "open"];
5873
5891
  DATA_HANDLING_MODES = ["own", "proxied", "third-party"];
5874
5892
  STEP_IDS = ["mode", "address", "access", "tools", "listing", "answers", "attestations", "prove", "signin", "token", "packet", "submit"];
5893
+ CASE_SOURCE = { "our-claude": "our test, Claude model", "our-gpt": "our test, GPT model", "claude-code": "your Claude Code", codex: "your Codex CLI", chatgpt: "ChatGPT", claude: "Claude" };
5894
+ CASE_STATE = { passed: "used the right tool", chose_write: "chose the right tool (not run: it changes data)", other_tool: "used a different tool", no_tool: "didn't use a tool", tool_failed: "the tool failed", said_no: "said no", acted: "used a tool when it shouldn't" };
5875
5895
  reportPath = (proj2) => `/projects/${encodeURIComponent(proj2.projectId)}/${encodeURIComponent(proj2.apiVersion)}/directory-report`;
5876
5896
  DESCRIPTION_MIN = 300;
5877
5897
  ccServerName = (projectId) => projectId.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "app";
@@ -8650,8 +8670,12 @@ async function runConnectorExercise(project, opts = {}) {
8650
8670
  const codex = deps.codexInstalled !== void 0 ? { installed: deps.codexInstalled, loggedIn: deps.codexInstalled } : clients.includes("codex") ? detectCodex(deps.spawn ?? import_child_process5.spawnSync) : { installed: false, loggedIn: false };
8651
8671
  const proven = opts.provenPromptNotes ?? [];
8652
8672
  const provenFor = (client) => new Map(proven.filter((n) => n.kind === "prompt" && (n.client ?? "claude") === client).map((n) => [n.prompt.trim(), n]));
8653
- const passPrompts = (opts.promptsOnly ?? target2.metadata?.examplePrompts ?? []).filter((p) => typeof p === "string" && p.trim()).slice(0, 5);
8654
- const negatives = (target2.metadata?.portalAnswers?.chatgpt_test_cases?.negative ?? []).map((c) => c.prompt).filter((p) => typeof p === "string" && p.trim()).slice(0, 3);
8673
+ const testCases = target2.metadata?.portalAnswers?.test_cases ?? [];
8674
+ const readTools = new Set(readOnlyToolNames(tools));
8675
+ const casePrompts = testCases.filter((c) => c.kind === "use" && (!c.tool || readTools.has(c.tool))).map((c) => c.prompt);
8676
+ const passPrompts = opts.promptsOnly ?? [...new Set([...(target2.metadata?.examplePrompts ?? []).slice(0, 5), ...casePrompts].filter((p) => typeof p === "string" && p.trim()).map((p) => p.trim()))].slice(0, 10);
8677
+ const refusals = testCases.filter((c) => c.kind === "refuse");
8678
+ const negatives = (refusals.length ? [...refusals.filter((c) => c.send), ...refusals.filter((c) => !c.send)].map((c) => c.prompt) : (target2.metadata?.portalAnswers?.chatgpt_test_cases?.negative ?? []).map((c) => c.prompt)).filter((p) => typeof p === "string" && p.trim()).slice(0, 3);
8655
8679
  const readOnly2 = readOnlyToolNames(tools);
8656
8680
  const requiredCount = (t) => Object.values(t.inputProperties ?? {}).filter((p) => p.required).length;
8657
8681
  const firstRead = [...tools].filter((t) => toolRole(t) === "read").sort((a, b) => requiredCount(a) - requiredCount(b))[0] ?? tools[0];
@@ -13956,12 +13980,15 @@ async function runConnector(target2, opts) {
13956
13980
  if (opts.status) {
13957
13981
  const cc = claudeCodeTests(r, proj2);
13958
13982
  if (json) {
13959
- writeJsonLine({ ready: isReady(r, platforms), project: proj2.projectId, headline: r.rendered.headline, summary: r.progress?.summary ?? null, progress: r.progress ?? null, claude_code: cc, report: r.report });
13983
+ writeJsonLine({ ready: isReady(r, platforms), project: proj2.projectId, headline: r.rendered.headline, summary: r.progress?.summary ?? null, progress: r.progress ?? null, claude_code: cc, test_cases: r.case_results ?? null, report: r.report });
13960
13984
  process.exit(isReady(r, platforms) ? 0 : 1);
13961
13985
  }
13962
13986
  const card2 = scorecardText(r);
13963
13987
  if (card2) console.log(card2);
13964
13988
  else printReport(r, false);
13989
+ const tc = testCasesText(r, platforms);
13990
+ if (tc) console.log(`
13991
+ ${tc}`);
13965
13992
  if (cc) console.log(`
13966
13993
  ${claudeCodeText(cc)}`);
13967
13994
  process.exit(isReady(r, platforms) ? 0 : 1);
@@ -15857,8 +15884,11 @@ saved as it is given; \`npx ${cli} connector <name> --status\` says what is left
15857
15884
  and \`npx ${cli} connector answers <name> --use-cases "\u2026" --prerequisites "\u2026" --category "\u2026" --reviewer-instructions "\u2026"\`.
15858
15885
  6. **Test**: \`npx ${cli} connector exercise <name>\` calls every tool as the reviewer. Then
15859
15886
  \`npx ${cli} connector <name> --status\` prints the Claude Code lines: one \`claude mcp add\`, one sign-in, and one
15860
- \`claude -p '\u2026' --allowedTools 'mcp__<name>'\` per example prompt, each with what should come back. Run each, tell the user
15887
+ \`claude -p '\u2026' --allowedTools 'mcp__<name>'\` per test case and example prompt, each with what should come back. Run each, tell the user
15861
15888
  what came back, and fix a tool's description (\`npx ${cli} mcp ops set\`) when a prompt did not reach the right tool.
15889
+ \`--status\` also lists the **test cases** (what reviewers try: five that should use a tool and three that should say no
15890
+ for ChatGPT) with each one's latest result and where it ran. Those results are a pre-check, not the directories' review:
15891
+ never tell the user a case "passed in ChatGPT" or "in Claude". The user writes and runs the cases on the page's Testing tab.
15862
15892
  7. **Send**: when every check passes it writes the packet. The user submits it on claude.ai/directory/manage (and the
15863
15893
  OpenAI portal for ChatGPT).
15864
15894
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.21.75",
3
+ "version": "0.21.76",
4
4
  "description": "APIblaze CLI — Chat with your APIs, Manage your API keys, users and groups with the APIblaze serverless proxy",
5
5
  "keywords": [
6
6
  "apiblaze",