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.
- package/dist/index.js +119 -27
- 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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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 (
|
|
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,
|
|
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 ||
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
8622
|
-
const
|
|
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:
|
|
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: `
|
|
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
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
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("-"));
|