apiblaze 0.21.74 → 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 +119 -27
  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.74";
37
+ version = "0.21.76";
38
38
  }
39
39
  });
40
40
 
@@ -4243,9 +4243,9 @@ async function openServerProxy(project) {
4243
4243
  }
4244
4244
  function discoverLocalSpecs() {
4245
4245
  const cwd = process.cwd();
4246
- const known = ["openapi.yaml", "openapi.yml", "openapi.json", "swagger.yaml", "swagger.yml", "swagger.json", "api.yaml", "api.yml", "api.json"];
4246
+ const known2 = ["openapi.yaml", "openapi.yml", "openapi.json", "swagger.yaml", "swagger.yml", "swagger.json", "api.yaml", "api.yml", "api.json"];
4247
4247
  const found = [];
4248
- for (const n of known) {
4248
+ for (const n of known2) {
4249
4249
  try {
4250
4250
  if (fs9.statSync(path9.join(cwd, n)).isFile()) found.push(n);
4251
4251
  } catch {
@@ -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,12 +5676,30 @@ 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
  }
5681
5698
  function pageLinkOf(r, proj2, anchor) {
5682
5699
  const base2 = r?.progress?.pageUrl ?? `${DASHBOARD_BASE6}/directory/${encodeURIComponent(proj2.projectId)}/${encodeURIComponent(proj2.apiVersion)}`;
5683
- const page = withBrandSource(base2);
5700
+ const team = proj2.teamId && !proj2.teamId.startsWith("team_anon_") ? proj2.teamId : null;
5701
+ let page = withBrandSource(base2);
5702
+ if (team) page += `${page.includes("?") ? "&" : "?"}team=${encodeURIComponent(team)}`;
5684
5703
  return anchor ? `${page}${anchor.startsWith("#") ? anchor : `#${anchor}`}` : page;
5685
5704
  }
5686
5705
  function stepOf(r, id) {
@@ -5819,6 +5838,7 @@ function claudeCodeTests(r, proj2) {
5819
5838
  seen.add(p);
5820
5839
  cases.push({ prompt: p, line: askLine(name, p), expect, refuse });
5821
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");
5822
5842
  for (const p of t?.metadata?.examplePrompts ?? []) add(p, "it calls your tools and answers from what comes back", false);
5823
5843
  const tc = t?.metadata?.portalAnswers?.chatgpt_test_cases;
5824
5844
  for (const c of tc?.positive ?? []) add(c.prompt, c.expected_behavior || "it calls your tools and answers from what comes back", false);
@@ -5838,7 +5858,7 @@ function claudeCodeText(cc) {
5838
5858
  else lines.push(` ${n}. One line per use case:`, ...cc.cases.flatMap((c) => [` ${c.line}`, ` expect: ${c.expect}`]));
5839
5859
  return lines.join("\n");
5840
5860
  }
5841
- 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;
5842
5862
  var init_directory = __esm({
5843
5863
  "src/lib/directory.ts"() {
5844
5864
  "use strict";
@@ -5870,6 +5890,8 @@ var init_directory = __esm({
5870
5890
  AUTH_MODES = ["signin", "open"];
5871
5891
  DATA_HANDLING_MODES = ["own", "proxied", "third-party"];
5872
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" };
5873
5895
  reportPath = (proj2) => `/projects/${encodeURIComponent(proj2.projectId)}/${encodeURIComponent(proj2.apiVersion)}/directory-report`;
5874
5896
  DESCRIPTION_MIN = 300;
5875
5897
  ccServerName = (projectId) => projectId.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "app";
@@ -6658,7 +6680,31 @@ async function printDevOutcome(o, port) {
6658
6680
  }
6659
6681
  if (o.anon) printLegalNotice(" ");
6660
6682
  }
6683
+ function printListingOutcome(o) {
6684
+ const where = { tenant: o.tenant, anon: o.anon };
6685
+ const mcp = mcpUrl(o.name, o.version, o.env, where);
6686
+ const s = o.secure;
6687
+ const applied = s?.applied ?? [];
6688
+ console.log();
6689
+ console.log(` ${import_chalk20.default.green("\u2713")} ${B.thing} ${import_chalk20.default.bold(o.name)}: ${import_chalk20.default.bold(mcp)}`);
6690
+ if (applied.length && s?.enforced) console.log(` ${import_chalk20.default.green("\u2713")} Each person can only change the ${describeFamilies(applied)} they made ${import_chalk20.default.dim("(lists stay open: your backend filters them)")}`);
6691
+ else if (applied.length && s?.pending) console.log(` ${import_chalk20.default.dim("\u2013")} ${describeFamilies(applied)}: the who-can-change-what rules are being applied`);
6692
+ else console.log(` ${import_chalk20.default.dim("\u2013")} ${import_chalk20.default.dim(`Who can change what: not set yet. Later: npx ${B.cli} rule ${o.name}`)}`);
6693
+ if (o.auth.doors.includes("api_key") && o.apiKey) {
6694
+ const saved = process.stdout.isTTY ? null : saveEnvLocal(process.cwd(), {
6695
+ APIBLAZE_URL: restUrl(o.name, o.version, o.env, where),
6696
+ APIBLAZE_MCP_URL: mcp,
6697
+ APIBLAZE_SERVER_KEY: o.apiKey,
6698
+ ...o.tenant ? { APIBLAZE_TENANT: o.tenant } : {}
6699
+ });
6700
+ if (saved?.ok) console.log(` ${import_chalk20.default.green("\u2713")} Backend key saved to .env.local as APIBLAZE_SERVER_KEY`);
6701
+ else console.log(` ${import_chalk20.default.green("\u2713")} Backend key ${import_chalk20.default.dim("(shown once, save it):")} ${import_chalk20.default.bold.green(o.apiKey)}`);
6702
+ }
6703
+ if (o.claim?.claimCode || o.claim?.claimUrl) console.log(import_chalk20.default.dim(` Anonymous: it expires in 30 days unless you sign in (npx ${B.cli} login claims it).`));
6704
+ if (o.anon) printLegalNotice(" ");
6705
+ }
6661
6706
  async function printOutcome(o) {
6707
+ if (o.listing) return printListingOutcome(o);
6662
6708
  const where = { tenant: o.tenant, anon: o.anon };
6663
6709
  const mcp = mcpUrl(o.name, o.version, o.env, where);
6664
6710
  const shown = BRAND === "mcpblaze" ? mcp : B.liveUrl(o.name, o.version, o.env, where);
@@ -6752,8 +6798,11 @@ async function runCreate(opts = {}) {
6752
6798
  opts.target = void 0;
6753
6799
  }
6754
6800
  }
6755
- const creds = loadCredentials();
6801
+ const saved = loadCredentials();
6802
+ const expired = !!saved && Date.now() >= saved.expiresAt && !process.env.APIBLAZE_TOKEN?.trim();
6803
+ const creds = expired ? null : saved;
6756
6804
  if (!creds) {
6805
+ if (expired && !opts.json) console.log(import_chalk20.default.dim(`Your saved login has expired, so this is made anonymously. \`${B.cli} login\` then claims it into your team.`));
6757
6806
  await runAnonymousCreate(opts);
6758
6807
  return;
6759
6808
  }
@@ -6939,6 +6988,7 @@ Create an ${B.thing}
6939
6988
  return;
6940
6989
  }
6941
6990
  await finishSetup({
6991
+ listing: !!opts.directoryReady,
6942
6992
  name,
6943
6993
  version: version2,
6944
6994
  env: "dev",
@@ -7174,7 +7224,8 @@ Create an ${B.thing}`));
7174
7224
  });
7175
7225
  }
7176
7226
  if (name) await applyCreateToggles(name, opts);
7177
- const directory = anonProjectId ? await directoryAfterCreate(anonProjectId, version2, opts) : null;
7227
+ if (anonProjectId) opts.onCreated?.({ name: anonProjectId, version: version2, tenant, teamId: result.team_id });
7228
+ const directory = anonProjectId && !opts.skipDirectoryReport ? await directoryAfterCreate(anonProjectId, version2, opts) : null;
7178
7229
  if (opts.json) {
7179
7230
  process.stdout.write(JSON.stringify({
7180
7231
  project_id: result.project_id,
@@ -7198,6 +7249,7 @@ Create an ${B.thing}`));
7198
7249
  return;
7199
7250
  }
7200
7251
  await finishSetup({
7252
+ listing: !!opts.directoryReady,
7201
7253
  name: anonProjectId,
7202
7254
  version: version2,
7203
7255
  env: "prod",
@@ -8013,10 +8065,10 @@ function orderTools(tools) {
8013
8065
  const rank = { read: 0, create: 1, update: 2, write: 3, delete: 4 };
8014
8066
  return [...tools].sort((a, b) => rank[toolRole(a)] - rank[toolRole(b)] || a.name.localeCompare(b.name));
8015
8067
  }
8016
- function exampleValue(name, p, known = {}, given = {}) {
8068
+ function exampleValue(name, p, known2 = {}, given = {}) {
8017
8069
  if (given[name] !== void 0) return given[name];
8018
8070
  if (p.example !== void 0 && p.example !== null) return p.example;
8019
- if (known[name] !== void 0) return known[name];
8071
+ if (known2[name] !== void 0) return known2[name];
8020
8072
  if (Array.isArray(p.enum) && p.enum.length) return p.enum[0];
8021
8073
  const t = (p.type ?? "string").toLowerCase();
8022
8074
  const fmt = (p.format ?? "").toLowerCase();
@@ -8033,14 +8085,14 @@ function exampleValue(name, p, known = {}, given = {}) {
8033
8085
  if (/(^|_)(q|query|search|term|text|name|title)$/i.test(name)) return "test";
8034
8086
  return "example";
8035
8087
  }
8036
- function validArgs(t, known = {}, given = {}) {
8088
+ function validArgs(t, known2 = {}, given = {}) {
8037
8089
  const out = {};
8038
8090
  const props = t.inputProperties ?? {};
8039
8091
  const pathParams = new Set([...(t.path ?? "").matchAll(/\{([^}]+)\}/g)].map((m) => m[1]));
8040
8092
  for (const [name, p] of Object.entries(props)) {
8041
- const wanted = p.required || pathParams.has(name) || p.example !== void 0 && p.example !== null || known[name] !== void 0 || given[name] !== void 0;
8093
+ const wanted = p.required || pathParams.has(name) || p.example !== void 0 && p.example !== null || known2[name] !== void 0 || given[name] !== void 0;
8042
8094
  if (!wanted) continue;
8043
- out[name] = exampleValue(name, p, known, given);
8095
+ out[name] = exampleValue(name, p, known2, given);
8044
8096
  }
8045
8097
  return out;
8046
8098
  }
@@ -8056,11 +8108,11 @@ function candidateFromPrompts(name, p, prompts) {
8056
8108
  const quoted = text.match(/["“']([^"”']{1,80})["”']/);
8057
8109
  return quoted ? quoted[1].trim() : null;
8058
8110
  }
8059
- function invalidArgs(t, known = {}, given = {}) {
8111
+ function invalidArgs(t, known2 = {}, given = {}) {
8060
8112
  const props = t.inputProperties ?? {};
8061
8113
  const names = Object.keys(props);
8062
8114
  if (!names.length) return null;
8063
- const base2 = validArgs(t, known, given);
8115
+ const base2 = validArgs(t, known2, given);
8064
8116
  const withEnum = names.find((n) => Array.isArray(props[n].enum) && props[n].enum.length);
8065
8117
  if (withEnum) return { args: { ...base2, [withEnum]: "not-a-valid-choice" }, broke: `${withEnum}: out of enum` };
8066
8118
  const typed = names.find((n) => ["integer", "number", "boolean"].includes((props[n].type ?? "").toLowerCase()));
@@ -8618,8 +8670,12 @@ async function runConnectorExercise(project, opts = {}) {
8618
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 };
8619
8671
  const proven = opts.provenPromptNotes ?? [];
8620
8672
  const provenFor = (client) => new Map(proven.filter((n) => n.kind === "prompt" && (n.client ?? "claude") === client).map((n) => [n.prompt.trim(), n]));
8621
- const passPrompts = (opts.promptsOnly ?? target2.metadata?.examplePrompts ?? []).filter((p) => typeof p === "string" && p.trim()).slice(0, 5);
8622
- 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);
8623
8679
  const readOnly2 = readOnlyToolNames(tools);
8624
8680
  const requiredCount = (t) => Object.values(t.inputProperties ?? {}).filter((p) => p.required).length;
8625
8681
  const firstRead = [...tools].filter((t) => toolRole(t) === "read").sort((a, b) => requiredCount(a) - requiredCount(b))[0] ?? tools[0];
@@ -13764,11 +13820,10 @@ async function ensureHostedUpstream(caller, teamId, proj2, r, opts, interactive2
13764
13820
  let chosen = header;
13765
13821
  let open = !!opts.upstreamOpen;
13766
13822
  if (!chosen && !open && interactive2) {
13767
- if (shape(cur).hosts?.upstreamKind === "public" && !shape(cur).hosts?.upstreamHeader) say(import_chalk32.default.dim(" An open backend can be called around sign-in and the per-user rules; a shared secret header closes that."));
13768
13823
  const { default: inquirer3 } = await import("inquirer");
13769
- const { name } = await inquirer3.prompt([{ type: "input", name: "name", message: `Does the backend need a header to accept calls from ${B.product}, such as an API key or a shared secret? (Header name; Enter = no, it checks its own credentials)` }]);
13824
+ const { name } = await inquirer3.prompt([{ type: "input", name: "name", message: "Secret header your backend checks? (e.g. X-Api-Key; Enter if none)" }]);
13770
13825
  if (name?.trim()) {
13771
- const { value } = await inquirer3.prompt([{ type: "password", name: "value", mask: "*", message: `Value of ${name.trim()} (stored encrypted, never shown again):`, validate: (v) => (v ?? "").length > 0 ? true : "A value is needed; Ctrl-C leaves." }]);
13826
+ const { value } = await inquirer3.prompt([{ type: "password", name: "value", mask: "*", message: `Its value (stored encrypted):`, validate: (v) => (v ?? "").length > 0 ? true : "A value is needed; Ctrl-C leaves." }]);
13772
13827
  chosen = { name: name.trim(), value };
13773
13828
  } else open = true;
13774
13829
  }
@@ -13881,8 +13936,6 @@ function installInterrupt(ctx) {
13881
13936
  return () => process.off("SIGINT", handler);
13882
13937
  }
13883
13938
  async function runConnector(target2, opts) {
13884
- const caller = requireCaller();
13885
- const { teamId } = await resolveActingTeam(caller, opts.team);
13886
13939
  const json = !!opts.json;
13887
13940
  const interactive2 = !!process.stdin.isTTY && !json && !opts.yes;
13888
13941
  const say = (s) => {
@@ -13898,8 +13951,9 @@ async function runConnector(target2, opts) {
13898
13951
  const created = await createFromSpec(specSource, opts, say);
13899
13952
  projectName = created.name;
13900
13953
  version2 = created.version;
13901
- say(import_chalk32.default.green(` ${B.thing} ${import_chalk32.default.bold(created.name)} created.`));
13902
13954
  }
13955
+ const caller = requireCaller();
13956
+ const { teamId } = await resolveActingTeam(caller, opts.team);
13903
13957
  const proj2 = await resolveProjectVia(caller, teamId, projectName, version2);
13904
13958
  const flagBody = directoryBodyFromFlags(opts);
13905
13959
  const onlyAttest = !!opts.attest?.length && !flagBody.directory_metadata && !opts.full && !specSource && !only && !opts.status;
@@ -13926,12 +13980,15 @@ async function runConnector(target2, opts) {
13926
13980
  if (opts.status) {
13927
13981
  const cc = claudeCodeTests(r, proj2);
13928
13982
  if (json) {
13929
- 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 });
13930
13984
  process.exit(isReady(r, platforms) ? 0 : 1);
13931
13985
  }
13932
13986
  const card2 = scorecardText(r);
13933
13987
  if (card2) console.log(card2);
13934
13988
  else printReport(r, false);
13989
+ const tc = testCasesText(r, platforms);
13990
+ if (tc) console.log(`
13991
+ ${tc}`);
13935
13992
  if (cc) console.log(`
13936
13993
  ${claudeCodeText(cc)}`);
13937
13994
  process.exit(isReady(r, platforms) ? 0 : 1);
@@ -13947,9 +14004,23 @@ ${claudeCodeText(cc)}`);
13947
14004
  r = await fetchDirectoryReport(caller, proj2, reportOpts());
13948
14005
  }
13949
14006
  const link = pageLinkOf(r, proj2);
13950
- const sum = summaryOf(r);
13951
- if (sum) {
13952
- say(`${import_chalk32.default.bold("Finish this here or at")} ${import_chalk32.default.cyan(link)} ${import_chalk32.default.dim("\xB7")} ${import_chalk32.default.bold(sum)}`);
14007
+ if (r.progress) {
14008
+ const pct = r.progress.readiness?.percent;
14009
+ const where = platforms.map((p) => p === "claude" ? "Claude" : "ChatGPT").join(" and ");
14010
+ const rule = import_chalk32.default.dim("\u2500".repeat(64));
14011
+ say("");
14012
+ say(rule);
14013
+ say(` ${import_chalk32.default.bold(`Get it listed in ${where}`)}${typeof pct === "number" ? import_chalk32.default.dim(` \xB7 ${pct}% ready`) : ""}`);
14014
+ if (caller.mode === "anon") {
14015
+ say(` A listing needs an account (your own MCP address is billed to it). Sign in, then carry on:`);
14016
+ say(` ${import_chalk32.default.cyan(`npx ${B.cli}@latest login`)} ${import_chalk32.default.dim(`it keeps ${proj2.projectId}, moving it into your team`)}`);
14017
+ say(` ${import_chalk32.default.cyan(`npx ${B.cli}@latest connector ${proj2.projectId}`)} ${import_chalk32.default.dim("or finish on the page it links")}`);
14018
+ say(rule);
14019
+ return;
14020
+ }
14021
+ say(` ${import_chalk32.default.bold("Here:")} answer the questions below. Stop any time; every answer is kept.`);
14022
+ say(` ${import_chalk32.default.bold("Or in your browser:")} ${import_chalk32.default.cyan(link)}`);
14023
+ say(rule);
13953
14024
  const done = doneLine(r);
13954
14025
  if (done) say(import_chalk32.default.dim(` ${done}`));
13955
14026
  } else {
@@ -15813,8 +15884,11 @@ saved as it is given; \`npx ${cli} connector <name> --status\` says what is left
15813
15884
  and \`npx ${cli} connector answers <name> --use-cases "\u2026" --prerequisites "\u2026" --category "\u2026" --reviewer-instructions "\u2026"\`.
15814
15885
  6. **Test**: \`npx ${cli} connector exercise <name>\` calls every tool as the reviewer. Then
15815
15886
  \`npx ${cli} connector <name> --status\` prints the Claude Code lines: one \`claude mcp add\`, one sign-in, and one
15816
- \`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
15817
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.
15818
15892
  7. **Send**: when every check passes it writes the packet. The user submits it on claude.ai/directory/manage (and the
15819
15893
  OpenAI portal for ChatGPT).
15820
15894
 
@@ -24038,9 +24112,27 @@ but this build does not have it, your npx cache is serving an older copy \u2014
24038
24112
  return program2;
24039
24113
  }
24040
24114
 
24115
+ // src/lib/bare-create.ts
24116
+ var SPEC = /^(https?:\/\/\S+|\S+\.(ya?ml|json))$/i;
24117
+ function bareCreateArgv(args, commands) {
24118
+ if (!args.length) return args;
24119
+ for (let i = 0; i < args.length; i += 1) {
24120
+ const a = args[i];
24121
+ if (a.startsWith("-")) continue;
24122
+ const prev = args[i - 1];
24123
+ const isValue = !!prev && prev.startsWith("--") && !prev.includes("=");
24124
+ if (!isValue && commands.has(a)) return args;
24125
+ }
24126
+ if (SPEC.test(args[0])) return ["create", "--target", ...args];
24127
+ if (args.some((a) => a === "--target" || a.startsWith("--target="))) return ["create", ...args];
24128
+ return args;
24129
+ }
24130
+
24041
24131
  // src/index.ts
24042
24132
  installBrandFilter();
24043
24133
  var program = buildProgram();
24134
+ var known = new Set(program.commands.flatMap((c) => [c.name(), ...c.aliases()]).concat(["help"]));
24135
+ process.argv = [...process.argv.slice(0, 2), ...bareCreateArgv(process.argv.slice(2), known)];
24044
24136
  process.on("exit", () => renderTrace());
24045
24137
  installFetchGuard(version);
24046
24138
  var firstCommand = process.argv.slice(2).find((a) => !a.startsWith("-"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.21.74",
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",