apiblaze 0.21.63 → 0.21.65
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 +150 -64
- 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.65";
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
|
|
@@ -5351,6 +5351,9 @@ function parseYesNo(flag, v) {
|
|
|
5351
5351
|
}
|
|
5352
5352
|
function directoryBodyFromFlags(f2) {
|
|
5353
5353
|
const m = {};
|
|
5354
|
+
for (const [flag, v] of [["--privacy-url", f2.privacyUrl], ["--docs-url", f2.docsUrl], ["--icon-url", f2.iconUrl]]) {
|
|
5355
|
+
if (v && !/^https:\/\//i.test(v.trim())) throw new Error(`${flag} must be an https URL (got ${v.trim()}).`);
|
|
5356
|
+
}
|
|
5354
5357
|
if (f2.privacyUrl) m.privacy_url = f2.privacyUrl;
|
|
5355
5358
|
if (f2.support) m.support_contact = f2.support;
|
|
5356
5359
|
if (f2.docsUrl) {
|
|
@@ -7069,7 +7072,7 @@ __export(agent_exports, {
|
|
|
7069
7072
|
});
|
|
7070
7073
|
async function callAgent(messages, teamId) {
|
|
7071
7074
|
const token = getAccessToken();
|
|
7072
|
-
const res = await fetch(`${
|
|
7075
|
+
const res = await fetch(`${DASHBOARD_BASE7}/api/cli/agent`, {
|
|
7073
7076
|
method: "POST",
|
|
7074
7077
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
7075
7078
|
body: JSON.stringify({ messages: messages.slice(-20), tools: toolCatalogue(), team_id: teamId })
|
|
@@ -7164,7 +7167,7 @@ async function runAgent(opts) {
|
|
|
7164
7167
|
}
|
|
7165
7168
|
console.log(import_chalk25.default.dim("\nBye."));
|
|
7166
7169
|
}
|
|
7167
|
-
var import_chalk25, import_ora9,
|
|
7170
|
+
var import_chalk25, import_ora9, DASHBOARD_BASE7, MAX_TOOL_STEPS;
|
|
7168
7171
|
var init_agent = __esm({
|
|
7169
7172
|
"src/commands/agent.ts"() {
|
|
7170
7173
|
"use strict";
|
|
@@ -7178,7 +7181,7 @@ var init_agent = __esm({
|
|
|
7178
7181
|
init_types();
|
|
7179
7182
|
init_problem();
|
|
7180
7183
|
init_brand();
|
|
7181
|
-
|
|
7184
|
+
DASHBOARD_BASE7 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
7182
7185
|
MAX_TOOL_STEPS = 6;
|
|
7183
7186
|
}
|
|
7184
7187
|
});
|
|
@@ -7716,7 +7719,7 @@ var init_exercise = __esm({
|
|
|
7716
7719
|
// src/commands/connector-exercise.ts
|
|
7717
7720
|
var connector_exercise_exports = {};
|
|
7718
7721
|
__export(connector_exercise_exports, {
|
|
7719
|
-
DASHBOARD_BASE: () =>
|
|
7722
|
+
DASHBOARD_BASE: () => DASHBOARD_BASE8,
|
|
7720
7723
|
RUN_HEADER: () => RUN_HEADER,
|
|
7721
7724
|
RUN_META_KEY: () => RUN_META_KEY,
|
|
7722
7725
|
reportLink: () => reportLink,
|
|
@@ -7724,7 +7727,7 @@ __export(connector_exercise_exports, {
|
|
|
7724
7727
|
runConnectorExercise: () => runConnectorExercise
|
|
7725
7728
|
});
|
|
7726
7729
|
function reportLink(projectId, apiVersion = "1.0.0") {
|
|
7727
|
-
return `${
|
|
7730
|
+
return `${DASHBOARD_BASE8}/directory/${encodeURIComponent(projectId)}/${encodeURIComponent(apiVersion)}`;
|
|
7728
7731
|
}
|
|
7729
7732
|
async function confirm(message, interactive2) {
|
|
7730
7733
|
if (!interactive2) return false;
|
|
@@ -7897,20 +7900,30 @@ async function runConnectorAnswers(project, opts = {}) {
|
|
|
7897
7900
|
const current = await producer(caller, { method: "POST", path: `${projectPath2(proj2)}/directory-report`, body: { probe: false }, summary: "Current answers" });
|
|
7898
7901
|
const have = current.target?.metadata?.portalAnswers ?? {};
|
|
7899
7902
|
const { default: inquirer3 } = await import("inquirer");
|
|
7903
|
+
const saveNow = async (part) => {
|
|
7904
|
+
try {
|
|
7905
|
+
await producer(caller, { method: "PATCH", path: projectPath2(proj2), body: part, summary: "Save an answer" });
|
|
7906
|
+
} catch (e) {
|
|
7907
|
+
console.log(import_chalk27.default.yellow(` not saved: ${e instanceof Error ? e.message : String(e)}`));
|
|
7908
|
+
}
|
|
7909
|
+
};
|
|
7900
7910
|
for (const q of QUESTIONS) {
|
|
7901
7911
|
if (answers[q.field] !== void 0) continue;
|
|
7902
7912
|
const existing = typeof have[q.field] === "string" ? String(have[q.field]) : "";
|
|
7903
7913
|
if (existing.length >= (q.min ?? 1)) continue;
|
|
7904
7914
|
const a = await inquirer3.prompt([{ type: "input", name: "value", message: q.message, default: existing || void 0, validate: (v) => v.trim().length >= (q.min ?? 1) ? true : `${q.min ?? 1}+ characters` }]);
|
|
7905
7915
|
answers[q.field] = a.value.trim();
|
|
7916
|
+
await saveNow({ directory_portal_answers: { [q.field]: a.value.trim() } });
|
|
7906
7917
|
}
|
|
7907
7918
|
if (answers.access === void 0 && !have.access) {
|
|
7908
7919
|
const a = await inquirer3.prompt([{ type: "list", name: "value", message: "What the tools do:", choices: ["read", "write", "both"] }]);
|
|
7909
7920
|
answers.access = a.value;
|
|
7921
|
+
await saveNow({ directory_portal_answers: { access: a.value } });
|
|
7910
7922
|
}
|
|
7911
7923
|
if (answers.categories === void 0 && !(Array.isArray(have.categories) && have.categories.length)) {
|
|
7912
7924
|
const a = await inquirer3.prompt([{ type: "input", name: "value", message: "Category suggestions (1\u20135, comma-separated; you pick the closest in the portal):", validate: (v) => v.trim() ? true : "one at least" }]);
|
|
7913
7925
|
answers.categories = a.value.split(",").map((c) => c.trim()).filter(Boolean).slice(0, 5);
|
|
7926
|
+
await saveNow({ directory_portal_answers: { categories: answers.categories } });
|
|
7914
7927
|
}
|
|
7915
7928
|
if (!meta.data_handling && !current.target?.metadata?.dataHandling) {
|
|
7916
7929
|
const a = await inquirer3.prompt([
|
|
@@ -7918,14 +7931,17 @@ async function runConnectorAnswers(project, opts = {}) {
|
|
|
7918
7931
|
{ type: "input", name: "statement", message: "The permission you hold (who granted what, and when; goes into portal step 7):", when: (ans) => ans.mode === "proxied", validate: (v) => v.trim().length >= 20 ? true : "a sentence, please" }
|
|
7919
7932
|
]);
|
|
7920
7933
|
meta.data_handling = { mode: a.mode, ...a.statement?.trim() ? { statement: a.statement.trim() } : {} };
|
|
7934
|
+
await saveNow({ directory_metadata: { data_handling: meta.data_handling } });
|
|
7921
7935
|
}
|
|
7922
7936
|
if (!meta.health_data && !current.target?.metadata?.healthData) {
|
|
7923
7937
|
const a = await inquirer3.prompt([{ type: "confirm", name: "value", message: "Do the tools handle health data?", default: false }]);
|
|
7924
7938
|
meta.health_data = a.value ? "yes" : "no";
|
|
7939
|
+
await saveNow({ directory_metadata: { health_data: meta.health_data } });
|
|
7925
7940
|
}
|
|
7926
7941
|
if (!meta.sponsored_content && !current.target?.metadata?.sponsoredContent) {
|
|
7927
7942
|
const a = await inquirer3.prompt([{ type: "confirm", name: "value", message: "Do tool results carry sponsored content?", default: false }]);
|
|
7928
7943
|
meta.sponsored_content = a.value ? "yes" : "no";
|
|
7944
|
+
await saveNow({ directory_metadata: { sponsored_content: meta.sponsored_content } });
|
|
7929
7945
|
}
|
|
7930
7946
|
}
|
|
7931
7947
|
const body = {};
|
|
@@ -7945,7 +7961,7 @@ async function runConnectorAnswers(project, opts = {}) {
|
|
|
7945
7961
|
console.log(import_chalk27.default.green(` \u2713 recorded: ${Object.keys({ ...answers, ...meta }).join(", ")}`));
|
|
7946
7962
|
console.log(import_chalk27.default.dim(` ${r.rendered.headline}`));
|
|
7947
7963
|
}
|
|
7948
|
-
var import_chalk27, import_fs6, import_os3, import_path5, import_child_process6,
|
|
7964
|
+
var import_chalk27, import_fs6, import_os3, import_path5, import_child_process6, DASHBOARD_BASE8, RUN_META_KEY, RUN_HEADER, projectPath2, QUESTIONS;
|
|
7949
7965
|
var init_connector_exercise = __esm({
|
|
7950
7966
|
"src/commands/connector-exercise.ts"() {
|
|
7951
7967
|
"use strict";
|
|
@@ -7961,7 +7977,7 @@ var init_connector_exercise = __esm({
|
|
|
7961
7977
|
init_exercise();
|
|
7962
7978
|
init_brand();
|
|
7963
7979
|
init_external_mcp();
|
|
7964
|
-
|
|
7980
|
+
DASHBOARD_BASE8 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
7965
7981
|
RUN_META_KEY = "com.apiblaze/run";
|
|
7966
7982
|
RUN_HEADER = "apiblaze-directory-run";
|
|
7967
7983
|
projectPath2 = (p) => `/projects/${encodeURIComponent(p.projectId)}/${encodeURIComponent(p.apiVersion)}`;
|
|
@@ -11575,6 +11591,31 @@ Not ready: ${lines.length} blocker${lines.length === 1 ? "" : "s"} (${r.rendered
|
|
|
11575
11591
|
process.exit(1);
|
|
11576
11592
|
}
|
|
11577
11593
|
|
|
11594
|
+
// src/lib/op-call.ts
|
|
11595
|
+
init_auth();
|
|
11596
|
+
init_trace();
|
|
11597
|
+
init_types();
|
|
11598
|
+
var DASHBOARD_BASE6 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
11599
|
+
async function opCall(call3) {
|
|
11600
|
+
const token = getAccessToken();
|
|
11601
|
+
const res = await fetch(`${DASHBOARD_BASE6}/api/cli/op`, {
|
|
11602
|
+
method: "POST",
|
|
11603
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
11604
|
+
body: JSON.stringify({ path: call3.path, method: call3.method, body: call3.body })
|
|
11605
|
+
});
|
|
11606
|
+
let data = null;
|
|
11607
|
+
try {
|
|
11608
|
+
data = await res.json();
|
|
11609
|
+
} catch {
|
|
11610
|
+
}
|
|
11611
|
+
recordCall({ method: call3.method, path: call3.path, body: call3.body, status: res.status, summary: call3.summary });
|
|
11612
|
+
if (!res.ok) {
|
|
11613
|
+
const msg = data?.details ?? data?.error ?? res.statusText;
|
|
11614
|
+
throw new ApiError(res.status, typeof msg === "string" ? msg : JSON.stringify(msg), data);
|
|
11615
|
+
}
|
|
11616
|
+
return data;
|
|
11617
|
+
}
|
|
11618
|
+
|
|
11578
11619
|
// src/commands/connector.ts
|
|
11579
11620
|
var import_fs8 = __toESM(require("fs"));
|
|
11580
11621
|
var import_path6 = __toESM(require("path"));
|
|
@@ -11794,13 +11835,17 @@ function shortenTo(text, limit) {
|
|
|
11794
11835
|
const base2 = atWord >= Math.floor(limit * 0.4) ? cut.slice(0, atWord) : cut;
|
|
11795
11836
|
return base2.replace(/[\s,;:(\-–—]+$/g, "").trim();
|
|
11796
11837
|
}
|
|
11797
|
-
async function promptForMissing(r, interactive2, defaults = { prompts: [] }, platforms = PLATFORMS) {
|
|
11838
|
+
async function promptForMissing(r, interactive2, defaults = { prompts: [] }, platforms = PLATFORMS, given = {}, save) {
|
|
11798
11839
|
const out = {};
|
|
11799
11840
|
const failing = r.report.results.filter((x) => !x.pass && !x.unverified);
|
|
11841
|
+
const answered = (k) => {
|
|
11842
|
+
const v = given[k];
|
|
11843
|
+
return Array.isArray(v) ? v.length > 0 : typeof v === "string" ? v.trim().length > 0 : v !== void 0 && v !== null && v !== false;
|
|
11844
|
+
};
|
|
11800
11845
|
const asks = /* @__PURE__ */ new Map();
|
|
11801
11846
|
for (const x of failing) {
|
|
11802
11847
|
const p = PROMPT_FOR_RULE[x.id];
|
|
11803
|
-
if (!p) continue;
|
|
11848
|
+
if (!p || answered(p.key)) continue;
|
|
11804
11849
|
const cur = asks.get(p.key);
|
|
11805
11850
|
if (!cur) {
|
|
11806
11851
|
asks.set(p.key, { ...p });
|
|
@@ -11853,7 +11898,13 @@ async function promptForMissing(r, interactive2, defaults = { prompts: [] }, pla
|
|
|
11853
11898
|
}
|
|
11854
11899
|
lines.push(line.trim());
|
|
11855
11900
|
}
|
|
11856
|
-
if (lines.length)
|
|
11901
|
+
if (lines.length) {
|
|
11902
|
+
out.prompt = lines;
|
|
11903
|
+
if (save) {
|
|
11904
|
+
const why = await save({ prompt: lines });
|
|
11905
|
+
if (why) say_(import_chalk30.default.yellow(` not saved: ${why}`));
|
|
11906
|
+
}
|
|
11907
|
+
}
|
|
11857
11908
|
continue;
|
|
11858
11909
|
}
|
|
11859
11910
|
const dk = DEFAULT_FOR_KEY[a.key];
|
|
@@ -11867,9 +11918,18 @@ async function promptForMissing(r, interactive2, defaults = { prompts: [] }, pla
|
|
|
11867
11918
|
// The privacy page is a hard portal requirement (https + 200): check it here, before the
|
|
11868
11919
|
// report has to come back red for a typo.
|
|
11869
11920
|
// Wrapped: inquirer calls validate(input, answers) and the answers object must not land in fetchFn.
|
|
11870
|
-
validate: a.key === "privacyUrl" ? (v) => validatePrivacyUrl(v) : withinLimit(a)
|
|
11921
|
+
validate: a.key === "privacyUrl" ? (v) => validatePrivacyUrl(v) : a.key === "docsUrl" ? (v) => validateHttpsUrl(v, { label: "documentation URL", required: false }) : a.key === "iconUrl" ? (v) => validateHttpsUrl(v, { label: "icon URL", required: false }) : withinLimit(a)
|
|
11871
11922
|
}]);
|
|
11872
|
-
if (value?.trim())
|
|
11923
|
+
if (value?.trim()) {
|
|
11924
|
+
out[a.key] = value.trim();
|
|
11925
|
+
if (save) {
|
|
11926
|
+
const why = await save({ [a.key]: value.trim() });
|
|
11927
|
+
if (why) {
|
|
11928
|
+
say_(import_chalk30.default.yellow(` not saved: ${why}`));
|
|
11929
|
+
delete out[a.key];
|
|
11930
|
+
}
|
|
11931
|
+
}
|
|
11932
|
+
}
|
|
11873
11933
|
}
|
|
11874
11934
|
const missingAttest = failing.filter((x) => x.id.startsWith("ATTEST_"));
|
|
11875
11935
|
if (missingAttest.length) {
|
|
@@ -11900,7 +11960,7 @@ async function askOpenMode(caller, proj2, r, opts, interactive2, say) {
|
|
|
11900
11960
|
say(import_chalk30.default.green(" \u2713 open mode: the connector takes no sign-in (public data); no reviewer account is needed."));
|
|
11901
11961
|
return true;
|
|
11902
11962
|
}
|
|
11903
|
-
async function promptListingBasics(r, interactive2, defaults, given, platforms = PLATFORMS) {
|
|
11963
|
+
async function promptListingBasics(r, interactive2, defaults, given, platforms = PLATFORMS, save) {
|
|
11904
11964
|
const meta = r.target?.metadata ?? {};
|
|
11905
11965
|
const gpt = platforms.includes("chatgpt");
|
|
11906
11966
|
const lim = { serverName: gpt ? 30 : 100, tagline: gpt ? 30 : 200, description: platforms.includes("claude") ? 2e3 : 4e3 };
|
|
@@ -11920,7 +11980,16 @@ async function promptListingBasics(r, interactive2, defaults, given, platforms =
|
|
|
11920
11980
|
const { default: inquirer3 } = await import("inquirer");
|
|
11921
11981
|
for (const w of want) {
|
|
11922
11982
|
const { value } = await inquirer3.prompt([{ type: "input", name: "value", message: w.message, default: w.def }]);
|
|
11923
|
-
if (value?.trim())
|
|
11983
|
+
if (value?.trim()) {
|
|
11984
|
+
out[w.key] = value.trim();
|
|
11985
|
+
if (save) {
|
|
11986
|
+
const why = await save({ [w.key]: value.trim() });
|
|
11987
|
+
if (why) {
|
|
11988
|
+
say_(import_chalk30.default.yellow(` not saved: ${why}`));
|
|
11989
|
+
delete out[w.key];
|
|
11990
|
+
}
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11924
11993
|
}
|
|
11925
11994
|
return out;
|
|
11926
11995
|
}
|
|
@@ -12155,9 +12224,17 @@ async function runConnector(target2, opts) {
|
|
|
12155
12224
|
if (changed) r = await fetchDirectoryReport(caller, proj2, { platforms });
|
|
12156
12225
|
}
|
|
12157
12226
|
if (await askOpenMode(caller, proj2, r, opts, interactive2, say)) r = await fetchDirectoryReport(caller, proj2, { platforms });
|
|
12158
|
-
const
|
|
12227
|
+
const saveAnswer = async (f2) => {
|
|
12228
|
+
try {
|
|
12229
|
+
await patchProject(caller, proj2, { ...directoryBodyFromFlags(f2) }, "Save an answer");
|
|
12230
|
+
return null;
|
|
12231
|
+
} catch (e) {
|
|
12232
|
+
return e instanceof Error ? e.message : String(e);
|
|
12233
|
+
}
|
|
12234
|
+
};
|
|
12235
|
+
const basics = await promptListingBasics(r, interactive2, defaults, opts, platforms, interactive2 ? saveAnswer : void 0);
|
|
12159
12236
|
if (!isReady(r, platforms) || Object.keys(basics).length) {
|
|
12160
|
-
const asked = { ...basics, ...isReady(r, platforms) ? {} : await promptForMissing(r, interactive2, defaults, platforms) };
|
|
12237
|
+
const asked = { ...basics, ...isReady(r, platforms) ? {} : await promptForMissing(r, interactive2, defaults, platforms, basics, interactive2 ? saveAnswer : void 0) };
|
|
12161
12238
|
const body = directoryBodyFromFlags(asked);
|
|
12162
12239
|
if (body.directory_metadata || body.directory_attestations || body.openai_challenge_token) {
|
|
12163
12240
|
await patchProject(caller, proj2, { ...body }, "Save listing details");
|
|
@@ -12180,21 +12257,19 @@ async function runConnector(target2, opts) {
|
|
|
12180
12257
|
}
|
|
12181
12258
|
r = await fetchDirectoryReport(caller, proj2, { platforms });
|
|
12182
12259
|
}
|
|
12183
|
-
if (
|
|
12184
|
-
|
|
12260
|
+
if (interactive2 && r.report.results.some((x) => ANSWER_RULES.includes(x.id) && !x.pass)) {
|
|
12261
|
+
const { runConnectorAnswers: runConnectorAnswers2 } = await Promise.resolve().then(() => (init_connector_exercise(), connector_exercise_exports));
|
|
12262
|
+
say(import_chalk30.default.bold(" The review answers the portal asks for (saved as you go):"));
|
|
12263
|
+
await runConnectorAnswers2(proj2.projectName, { team: opts.team, apiversion: opts.apiversion });
|
|
12264
|
+
r = await fetchDirectoryReport(caller, proj2, { platforms });
|
|
12265
|
+
}
|
|
12266
|
+
if (!readyExcept(r, platforms, [SNAPSHOT_RULE, ...EVIDENCE_RULES])) {
|
|
12185
12267
|
if (!domain2.active && domain2.hostname && !json) {
|
|
12186
12268
|
console.error(import_chalk30.default.yellow(`
|
|
12187
12269
|
${domain2.hostname} is not active yet. Once the CNAME is in place, run again: ${B.cli} connector ${proj2.projectName}`));
|
|
12188
12270
|
}
|
|
12189
|
-
|
|
12271
|
+
exitWithReport(r, proj2, platforms, json);
|
|
12190
12272
|
}
|
|
12191
|
-
r = await fetchDirectoryReport(caller, proj2, { platforms, refreshSnapshot: true, publishedUrl: r.report.project.publishedUrl ?? null });
|
|
12192
|
-
const packet = await producer(caller, { method: "GET", path: `${projectPath3(proj2)}/directory-packet`, summary: "Submission packet" });
|
|
12193
|
-
const dir = opts.out ?? process.cwd();
|
|
12194
|
-
const mdPath = import_path6.default.join(dir, `connector-packet-${proj2.projectId}.md`);
|
|
12195
|
-
const jsonPath = import_path6.default.join(dir, `connector-packet-${proj2.projectId}.json`);
|
|
12196
|
-
import_fs8.default.writeFileSync(mdPath, packet.markdown, { mode: 384 });
|
|
12197
|
-
import_fs8.default.writeFileSync(jsonPath, JSON.stringify(packet.json, null, 2) + "\n", { mode: 384 });
|
|
12198
12273
|
if (opts.exercise !== false) {
|
|
12199
12274
|
let run2 = !!opts.yes;
|
|
12200
12275
|
if (interactive2) {
|
|
@@ -12207,6 +12282,14 @@ async function runConnector(target2, opts) {
|
|
|
12207
12282
|
r = await fetchDirectoryReport(caller, proj2, { platforms, publishedUrl: r.report.project.publishedUrl ?? null });
|
|
12208
12283
|
}
|
|
12209
12284
|
}
|
|
12285
|
+
if (!readyExceptSnapshot(r, platforms)) exitWithReport(r, proj2, platforms, json);
|
|
12286
|
+
r = await fetchDirectoryReport(caller, proj2, { platforms, refreshSnapshot: true, publishedUrl: r.report.project.publishedUrl ?? null });
|
|
12287
|
+
const packet = await producer(caller, { method: "GET", path: `${projectPath3(proj2)}/directory-packet`, summary: "Submission packet" });
|
|
12288
|
+
const dir = opts.out ?? process.cwd();
|
|
12289
|
+
const mdPath = import_path6.default.join(dir, `connector-packet-${proj2.projectId}.md`);
|
|
12290
|
+
const jsonPath = import_path6.default.join(dir, `connector-packet-${proj2.projectId}.json`);
|
|
12291
|
+
import_fs8.default.writeFileSync(mdPath, packet.markdown, { mode: 384 });
|
|
12292
|
+
import_fs8.default.writeFileSync(jsonPath, JSON.stringify(packet.json, null, 2) + "\n", { mode: 384 });
|
|
12210
12293
|
if (json) {
|
|
12211
12294
|
process.stdout.write(JSON.stringify({ ready: true, project: proj2.projectId, headline: r.rendered.headline, report: r.report, packet: { markdown: mdPath, json: jsonPath }, portals: PORTALS, ...reviewer ? { reviewer } : {} }) + "\n");
|
|
12212
12295
|
return;
|
|
@@ -12225,6 +12308,23 @@ async function runConnector(target2, opts) {
|
|
|
12225
12308
|
console.log(import_chalk30.default.dim(` ${r.report.disclaimer}`));
|
|
12226
12309
|
}
|
|
12227
12310
|
var SNAPSHOT_RULE = "LISTING_SNAPSHOT_MATCH";
|
|
12311
|
+
var ANSWER_RULES = ["PORTAL_ANSWERS_COMPLETE", "HEALTH_SPONSORED_DECLARED", "API_OWNERSHIP_DOMAIN"];
|
|
12312
|
+
var EVIDENCE_RULES = ["TOOL_EXERCISED_EACH", "TOOL_ERROR_PATH_EACH", "REVIEWER_ACCOUNT_POPULATED", "TESTED_IN_CLAUDE_OR_INSPECTOR", "TESTED_FROM_CLAUDE", "EXAMPLE_PROMPTS_WORK", "OAUTH_FLOW_COMPLETED"];
|
|
12313
|
+
function exitWithReport(r, proj2, platforms, json) {
|
|
12314
|
+
if (json) {
|
|
12315
|
+
process.stdout.write(JSON.stringify({ ready: false, project: proj2.projectId, headline: r.rendered.headline, report: r.report }) + "\n");
|
|
12316
|
+
process.exit(1);
|
|
12317
|
+
}
|
|
12318
|
+
printReport(r, false);
|
|
12319
|
+
const want = platforms;
|
|
12320
|
+
const blocking = r.report.results.filter((x) => !x.pass && x.severity === "block" && !x.unverified && x.platforms.some((p) => want.includes(p)));
|
|
12321
|
+
const first = blocking.find((x) => x.id !== SNAPSHOT_RULE) ?? blocking[0];
|
|
12322
|
+
console.error(import_chalk30.default.red(`
|
|
12323
|
+
Not ready: ${blocking.length} blocker${blocking.length === 1 ? "" : "s"} (${blocking.map((x) => x.id).join(", ")}).`));
|
|
12324
|
+
if (first) console.error(` Next: ${first.fix ?? first.message ?? first.title}`);
|
|
12325
|
+
console.error(import_chalk30.default.dim(` Report page: ${DASHBOARD_BASE6}/directory/${encodeURIComponent(proj2.projectId)}/${encodeURIComponent(proj2.apiVersion)}`));
|
|
12326
|
+
process.exit(1);
|
|
12327
|
+
}
|
|
12228
12328
|
var TOOL_DESC_RULE = "TOOL_DESC_NONEMPTY_SPECIFIC";
|
|
12229
12329
|
var UTILITY_PATH = /(health|ping|status|openapi|swagger|docs|spec|whoami|version)/i;
|
|
12230
12330
|
var SPECIFIC_MIN = 12;
|
|
@@ -12284,10 +12384,13 @@ async function fixToolDescriptions(proj2, environment, interactive2, say) {
|
|
|
12284
12384
|
return true;
|
|
12285
12385
|
}
|
|
12286
12386
|
function readyExceptSnapshot(r, platforms) {
|
|
12387
|
+
return readyExcept(r, platforms, [SNAPSHOT_RULE]);
|
|
12388
|
+
}
|
|
12389
|
+
function readyExcept(r, platforms, ignore) {
|
|
12287
12390
|
if (isReady(r, platforms)) return true;
|
|
12288
12391
|
const want = platforms ?? r.report.platformsRequested ?? ["claude", "chatgpt"];
|
|
12289
12392
|
const blocking = r.report.results.filter((x) => !x.pass && x.severity === "block" && x.platforms.some((p) => want.includes(p)));
|
|
12290
|
-
return blocking.length > 0 && blocking.every((x) => x.id
|
|
12393
|
+
return blocking.length > 0 && blocking.every((x) => ignore.includes(x.id) && (x.id !== SNAPSHOT_RULE || /no listing snapshot/i.test(x.message ?? "")));
|
|
12291
12394
|
}
|
|
12292
12395
|
async function probeConventionalUrls(apexDomain, fetchFn = headStatus) {
|
|
12293
12396
|
if (!apexDomain) return {};
|
|
@@ -12309,11 +12412,19 @@ async function probeConventionalUrls(apexDomain, fetchFn = headStatus) {
|
|
|
12309
12412
|
}
|
|
12310
12413
|
return out;
|
|
12311
12414
|
}
|
|
12415
|
+
var say_ = (line) => {
|
|
12416
|
+
if (process.env.APIBLAZE_SILENT !== "1") console.log(line);
|
|
12417
|
+
};
|
|
12312
12418
|
async function validatePrivacyUrl(input, fetchFn = headStatus) {
|
|
12313
12419
|
if (typeof fetchFn !== "function") fetchFn = headStatus;
|
|
12420
|
+
if (!(input ?? "").trim()) return "A public privacy policy URL is required by both directories.";
|
|
12421
|
+
return validateHttpsUrl(input, { label: "privacy URL", required: true, fetchFn });
|
|
12422
|
+
}
|
|
12423
|
+
async function validateHttpsUrl(input, o) {
|
|
12424
|
+
const fetchFn = typeof o.fetchFn === "function" ? o.fetchFn : headStatus;
|
|
12314
12425
|
const u = (input ?? "").trim();
|
|
12315
|
-
if (!u) return
|
|
12316
|
-
if (!/^https:\/\//i.test(u)) return
|
|
12426
|
+
if (!u) return o.required ? `A ${o.label} is required.` : true;
|
|
12427
|
+
if (!/^https:\/\//i.test(u)) return `The ${o.label} must start with https://`;
|
|
12317
12428
|
const status2 = await fetchFn(u);
|
|
12318
12429
|
if (status2 === 200) return true;
|
|
12319
12430
|
return status2 === 0 ? `${u} did not answer (timeout or DNS). Publish the page, then enter its URL.` : `${u} answered ${status2}; it must answer 200.`;
|
|
@@ -14248,7 +14359,7 @@ var import_fs12 = require("fs");
|
|
|
14248
14359
|
init_admin();
|
|
14249
14360
|
init_auth();
|
|
14250
14361
|
init_resolve();
|
|
14251
|
-
var
|
|
14362
|
+
var DASHBOARD_BASE9 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
14252
14363
|
async function runExport(projectArg, versionArg, opts) {
|
|
14253
14364
|
const token = getAccessToken();
|
|
14254
14365
|
if (!token) throw new Error("Not authenticated. Run `apiblaze login` first.");
|
|
@@ -14286,7 +14397,7 @@ async function runExport(projectArg, versionArg, opts) {
|
|
|
14286
14397
|
}
|
|
14287
14398
|
process.stdout.write("\n");
|
|
14288
14399
|
const outFile = opts.out || `apiblaze-export-${projectId}-${version2}-${target2}.zip`;
|
|
14289
|
-
const res = await fetch(`${
|
|
14400
|
+
const res = await fetch(`${DASHBOARD_BASE9}/api/cli/admin/download`, {
|
|
14290
14401
|
method: "POST",
|
|
14291
14402
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
14292
14403
|
body: JSON.stringify({ path: `${statusPath}?download=1` })
|
|
@@ -16052,7 +16163,7 @@ var import_ora20 = __toESM(require("ora"));
|
|
|
16052
16163
|
init_admin();
|
|
16053
16164
|
init_resolve();
|
|
16054
16165
|
init_brand();
|
|
16055
|
-
var
|
|
16166
|
+
var DASHBOARD_BASE10 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
16056
16167
|
var TOPUP_MIN_USD = 10;
|
|
16057
16168
|
var TOPUP_MAX_USD = 1e3;
|
|
16058
16169
|
var money = (cents2) => typeof cents2 === "number" ? `$${usdStr(cents2)}` : "\u2014";
|
|
@@ -16114,7 +16225,7 @@ async function runBillingBalance(opts) {
|
|
|
16114
16225
|
console.log("");
|
|
16115
16226
|
}
|
|
16116
16227
|
function walletUrl(teamId) {
|
|
16117
|
-
return teamId ? `${
|
|
16228
|
+
return teamId ? `${DASHBOARD_BASE10}/topup?teamId=${encodeURIComponent(teamId)}` : `${DASHBOARD_BASE10}/account?section=wallet`;
|
|
16118
16229
|
}
|
|
16119
16230
|
async function runBillingTopup(amount, opts) {
|
|
16120
16231
|
const usd2 = Number(amount);
|
|
@@ -18689,7 +18800,7 @@ init_tenant_choice();
|
|
|
18689
18800
|
init_resolve();
|
|
18690
18801
|
init_types();
|
|
18691
18802
|
init_paging();
|
|
18692
|
-
var
|
|
18803
|
+
var DASHBOARD_BASE11 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
18693
18804
|
var IAM_BASE = process.env.APIBLAZE_IAM_BASE || "https://iam.apiblaze.com";
|
|
18694
18805
|
async function resolveTransport(opts) {
|
|
18695
18806
|
const producer2 = loadCredentials();
|
|
@@ -18713,7 +18824,7 @@ async function resolveTransport(opts) {
|
|
|
18713
18824
|
return {
|
|
18714
18825
|
tenant: tenant2,
|
|
18715
18826
|
call: async (path19, method = "GET", body) => {
|
|
18716
|
-
const res = await fetch(`${
|
|
18827
|
+
const res = await fetch(`${DASHBOARD_BASE11}/api/cli/iam`, {
|
|
18717
18828
|
method: "POST",
|
|
18718
18829
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
18719
18830
|
body: JSON.stringify({ tenant: tenant2, path: path19, method, body })
|
|
@@ -19589,31 +19700,6 @@ async function runOriginsRemove(origin, opts) {
|
|
|
19589
19700
|
var import_chalk77 = __toESM(require("chalk"));
|
|
19590
19701
|
init_auth();
|
|
19591
19702
|
|
|
19592
|
-
// src/lib/op-call.ts
|
|
19593
|
-
init_auth();
|
|
19594
|
-
init_trace();
|
|
19595
|
-
init_types();
|
|
19596
|
-
var DASHBOARD_BASE11 = process.env.APIBLAZE_DASHBOARD_BASE || "https://dashboard.apiblaze.com";
|
|
19597
|
-
async function opCall(call3) {
|
|
19598
|
-
const token = getAccessToken();
|
|
19599
|
-
const res = await fetch(`${DASHBOARD_BASE11}/api/cli/op`, {
|
|
19600
|
-
method: "POST",
|
|
19601
|
-
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
19602
|
-
body: JSON.stringify({ path: call3.path, method: call3.method, body: call3.body })
|
|
19603
|
-
});
|
|
19604
|
-
let data = null;
|
|
19605
|
-
try {
|
|
19606
|
-
data = await res.json();
|
|
19607
|
-
} catch {
|
|
19608
|
-
}
|
|
19609
|
-
recordCall({ method: call3.method, path: call3.path, body: call3.body, status: res.status, summary: call3.summary });
|
|
19610
|
-
if (!res.ok) {
|
|
19611
|
-
const msg = data?.details ?? data?.error ?? res.statusText;
|
|
19612
|
-
throw new ApiError(res.status, typeof msg === "string" ? msg : JSON.stringify(msg), data);
|
|
19613
|
-
}
|
|
19614
|
-
return data;
|
|
19615
|
-
}
|
|
19616
|
-
|
|
19617
19703
|
// src/commands/op-money.ts
|
|
19618
19704
|
var import_chalk70 = __toESM(require("chalk"));
|
|
19619
19705
|
init_admin();
|
|
@@ -19702,8 +19788,8 @@ function lastLedgerSendAtMs(st) {
|
|
|
19702
19788
|
const v = st.lastLedgerSendAtMs !== void 0 ? st.lastLedgerSendAtMs : st.lastFlushAtMs;
|
|
19703
19789
|
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
19704
19790
|
}
|
|
19705
|
-
var walletPage = (ba) => `${
|
|
19706
|
-
var incidentPage = () => `${
|
|
19791
|
+
var walletPage = (ba) => `${DASHBOARD_BASE6}/operator/wallets/${encodeURIComponent(ba)}`;
|
|
19792
|
+
var incidentPage = () => `${DASHBOARD_BASE6}/operator/incident`;
|
|
19707
19793
|
var WALLET_MUTATIONS = {
|
|
19708
19794
|
"freeze": "a reason (required, \u2264 500 chars). Sets frozen; epoch++ recalls every shard \u2014 serving stops within seconds.",
|
|
19709
19795
|
"unfreeze": "a reason (required, \u2264 500 chars).",
|
|
@@ -19717,7 +19803,7 @@ var WALLET_MUTATIONS = {
|
|
|
19717
19803
|
function opWalletMutation(action2, ref, opts) {
|
|
19718
19804
|
const need = WALLET_MUTATIONS[action2];
|
|
19719
19805
|
const target2 = ref ?? "<wallet>";
|
|
19720
|
-
const url = ref && !isTeamId(ref) ? walletPage(ref) : `${
|
|
19806
|
+
const url = ref && !isTeamId(ref) ? walletPage(ref) : `${DASHBOARD_BASE6}/operator/wallets`;
|
|
19721
19807
|
if (opts.json) return void console.log(JSON.stringify({ action: action2, wallet: ref ?? null, dashboard_only: true, url, requires: need ?? "a reason" }));
|
|
19722
19808
|
console.log(import_chalk70.default.yellow(`
|
|
19723
19809
|
\`op wallet ${action2}\` is dashboard-only \u2014 it writes an operator_audit row with YOUR reason before touching the root.`));
|