@reddoorla/maintenance 0.88.2 → 0.89.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.
- package/dist/{announce-GKD5YJNB.js → announce-OJFAS5JT.js} +6 -6
- package/dist/{blux-DN4MI532.js → blux-EATHOHKK.js} +5 -5
- package/dist/{chunk-7UAYMAKR.js → chunk-3VQWSE3F.js} +4 -4
- package/dist/{chunk-A2UNJIKH.js → chunk-5PWB3JHJ.js} +6 -4
- package/dist/chunk-5PWB3JHJ.js.map +1 -0
- package/dist/{chunk-K6SLF6GI.js → chunk-62NYED6E.js} +6 -6
- package/dist/{chunk-B23FFWU4.js → chunk-AEXJDCJN.js} +96 -19
- package/dist/{chunk-B23FFWU4.js.map → chunk-AEXJDCJN.js.map} +1 -1
- package/dist/{chunk-7FFUBF4I.js → chunk-AX22DH6S.js} +2 -2
- package/dist/{chunk-7TMWBXX7.js → chunk-DXKF552B.js} +269 -7
- package/dist/chunk-DXKF552B.js.map +1 -0
- package/dist/{chunk-6I6L3CMX.js → chunk-KGUKL3CV.js} +2 -2
- package/dist/{chunk-ULHPALI5.js → chunk-NDCOOI3V.js} +2 -2
- package/dist/{chunk-GQDDWYU2.js → chunk-QBAAZY7W.js} +1 -1
- package/dist/{chunk-GQDDWYU2.js.map → chunk-QBAAZY7W.js.map} +1 -1
- package/dist/{chunk-KMCZA7CH.js → chunk-QLIUDTY6.js} +2 -2
- package/dist/{chunk-XP5WM2LV.js → chunk-SKI23ZZH.js} +4 -4
- package/dist/chunk-SVAAONYB.js +21 -0
- package/dist/chunk-SVAAONYB.js.map +1 -0
- package/dist/{chunk-DGZWFI2G.js → chunk-VBEKL445.js} +17 -8
- package/dist/chunk-VBEKL445.js.map +1 -0
- package/dist/{chunk-ANJNTAMM.js → chunk-ZOCJBJQV.js} +4 -2
- package/dist/{chunk-J3WEZGIN.js → chunk-ZRI5VRPG.js} +4 -4
- package/dist/cli/bin.js +27 -18
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.js +5 -5
- package/dist/{db-V6UIS433.js → db-DAJX7NNW.js} +51 -10
- package/dist/db-DAJX7NNW.js.map +1 -0
- package/dist/{digest-2JEAEJK6.js → digest-T6TAZNLF.js} +73 -16
- package/dist/digest-T6TAZNLF.js.map +1 -0
- package/dist/digest-collectors-NI2M3UTC.js +50 -0
- package/dist/digest-state-3KHZF7GD.js +50 -0
- package/dist/digest-state-3KHZF7GD.js.map +1 -0
- package/dist/{dump-EPL7AZFR.js → dump-QK7LNOGC.js} +14 -1
- package/dist/{dump-EPL7AZFR.js.map → dump-QK7LNOGC.js.map} +1 -1
- package/dist/{email-SL7464YI.js → email-LJQT5J7F.js} +6 -7
- package/dist/{email-SL7464YI.js.map → email-LJQT5J7F.js.map} +1 -1
- package/dist/{ensure-site-FU6527OU.js → ensure-site-NSNY2QHN.js} +2 -2
- package/dist/{fleet-state-R5LU7IC3.js → fleet-state-3LQUQHYD.js} +2 -2
- package/dist/{forms-notify-target-SGDGXXK5.js → forms-notify-target-LYSKME5L.js} +2 -2
- package/dist/freeze-A6MUCZU4.js +9 -0
- package/dist/{github-signals-GWGCKEE2.js → github-signals-4YML6NY5.js} +4 -4
- package/dist/{health-mirror-GCDN7BJL.js → health-mirror-7LKC7Q5Z.js} +5 -5
- package/dist/index.d.ts +19 -4
- package/dist/index.js +29 -28
- package/dist/index.js.map +1 -1
- package/dist/{init-FGTYNGUI.js → init-NHKADHB6.js} +7 -7
- package/dist/{launch-5H7LPEGP.js → launch-VQJ4Z35C.js} +6 -6
- package/dist/{orchestrate-JNKCWU5K.js → orchestrate-6HROYTM6.js} +4 -4
- package/dist/{parity-NBYZUBFU.js → parity-623WNFZG.js} +3 -3
- package/dist/{pipeline-WYTXSLHX.js → pipeline-MQJD4CKN.js} +6 -2
- package/dist/{preflight-IMTYDDD4.js → preflight-LIN5NCYU.js} +5 -5
- package/dist/{prismic-ci-MY2U6NN7.js → prismic-ci-PZ5LCPWT.js} +4 -4
- package/dist/{prismic-models-NJN5JORF.js → prismic-models-6OYYZUR5.js} +3 -3
- package/dist/prospect/types.d.ts +27 -0
- package/dist/{prospect-audit-JMBRVXSG.js → prospect-audit-DBBXL7EG.js} +8 -6
- package/dist/prospect-audit-DBBXL7EG.js.map +1 -0
- package/dist/recipes/sync-configs.js +2 -2
- package/dist/{render-VX72AESY.js → render-P3SBUFVB.js} +3 -3
- package/dist/{render-from-row-DOYJDO2L.js → render-from-row-P5CWM3MQ.js} +3 -3
- package/dist/render-from-row-P5CWM3MQ.js.map +1 -0
- package/dist/{report-TALY5P3L.js → report-2N4PXO3L.js} +33 -17
- package/dist/report-2N4PXO3L.js.map +1 -0
- package/dist/{report-mirror-AAK3MXHY.js → report-mirror-3ENU6OOK.js} +5 -5
- package/dist/{selftest-NZTR4SM2.js → selftest-CUX2FIQD.js} +7 -7
- package/dist/{site-mirror-Q763PLGG.js → site-mirror-RQTEAID5.js} +5 -5
- package/dist/{sync-GBFV45WX.js → sync-ESP5ZQUU.js} +3 -3
- package/dist/{sync-configs-34JIA6KZ.js → sync-configs-LVBITPLU.js} +3 -3
- package/dist/usage-UHKU76VK.js +147 -0
- package/dist/usage-UHKU76VK.js.map +1 -0
- package/dist/{write-audits-to-airtable-OBHGR7DQ.js → write-audits-to-airtable-K352LZQY.js} +3 -3
- package/dist/write-audits-to-airtable-K352LZQY.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-7TMWBXX7.js.map +0 -1
- package/dist/chunk-A2UNJIKH.js.map +0 -1
- package/dist/chunk-DGZWFI2G.js.map +0 -1
- package/dist/chunk-RUPPWAD6.js +0 -7
- package/dist/chunk-RUPPWAD6.js.map +0 -1
- package/dist/db-V6UIS433.js.map +0 -1
- package/dist/digest-2JEAEJK6.js.map +0 -1
- package/dist/digest-state-CRZRNGDI.js +0 -25
- package/dist/digest-state-CRZRNGDI.js.map +0 -1
- package/dist/prospect-audit-JMBRVXSG.js.map +0 -1
- package/dist/report-TALY5P3L.js.map +0 -1
- /package/dist/{announce-GKD5YJNB.js.map → announce-OJFAS5JT.js.map} +0 -0
- /package/dist/{blux-DN4MI532.js.map → blux-EATHOHKK.js.map} +0 -0
- /package/dist/{chunk-7UAYMAKR.js.map → chunk-3VQWSE3F.js.map} +0 -0
- /package/dist/{chunk-K6SLF6GI.js.map → chunk-62NYED6E.js.map} +0 -0
- /package/dist/{chunk-7FFUBF4I.js.map → chunk-AX22DH6S.js.map} +0 -0
- /package/dist/{chunk-6I6L3CMX.js.map → chunk-KGUKL3CV.js.map} +0 -0
- /package/dist/{chunk-ULHPALI5.js.map → chunk-NDCOOI3V.js.map} +0 -0
- /package/dist/{chunk-KMCZA7CH.js.map → chunk-QLIUDTY6.js.map} +0 -0
- /package/dist/{chunk-XP5WM2LV.js.map → chunk-SKI23ZZH.js.map} +0 -0
- /package/dist/{chunk-ANJNTAMM.js.map → chunk-ZOCJBJQV.js.map} +0 -0
- /package/dist/{chunk-J3WEZGIN.js.map → chunk-ZRI5VRPG.js.map} +0 -0
- /package/dist/{fleet-state-R5LU7IC3.js.map → digest-collectors-NI2M3UTC.js.map} +0 -0
- /package/dist/{ensure-site-FU6527OU.js.map → ensure-site-NSNY2QHN.js.map} +0 -0
- /package/dist/{orchestrate-JNKCWU5K.js.map → fleet-state-3LQUQHYD.js.map} +0 -0
- /package/dist/{forms-notify-target-SGDGXXK5.js.map → forms-notify-target-LYSKME5L.js.map} +0 -0
- /package/dist/{parity-NBYZUBFU.js.map → freeze-A6MUCZU4.js.map} +0 -0
- /package/dist/{github-signals-GWGCKEE2.js.map → github-signals-4YML6NY5.js.map} +0 -0
- /package/dist/{health-mirror-GCDN7BJL.js.map → health-mirror-7LKC7Q5Z.js.map} +0 -0
- /package/dist/{init-FGTYNGUI.js.map → init-NHKADHB6.js.map} +0 -0
- /package/dist/{launch-5H7LPEGP.js.map → launch-VQJ4Z35C.js.map} +0 -0
- /package/dist/{pipeline-WYTXSLHX.js.map → orchestrate-6HROYTM6.js.map} +0 -0
- /package/dist/{render-VX72AESY.js.map → parity-623WNFZG.js.map} +0 -0
- /package/dist/{render-from-row-DOYJDO2L.js.map → pipeline-MQJD4CKN.js.map} +0 -0
- /package/dist/{preflight-IMTYDDD4.js.map → preflight-LIN5NCYU.js.map} +0 -0
- /package/dist/{prismic-ci-MY2U6NN7.js.map → prismic-ci-PZ5LCPWT.js.map} +0 -0
- /package/dist/{prismic-models-NJN5JORF.js.map → prismic-models-6OYYZUR5.js.map} +0 -0
- /package/dist/{write-audits-to-airtable-OBHGR7DQ.js.map → render-P3SBUFVB.js.map} +0 -0
- /package/dist/{report-mirror-AAK3MXHY.js.map → report-mirror-3ENU6OOK.js.map} +0 -0
- /package/dist/{selftest-NZTR4SM2.js.map → selftest-CUX2FIQD.js.map} +0 -0
- /package/dist/{site-mirror-Q763PLGG.js.map → site-mirror-RQTEAID5.js.map} +0 -0
- /package/dist/{sync-GBFV45WX.js.map → sync-ESP5ZQUU.js.map} +0 -0
- /package/dist/{sync-configs-34JIA6KZ.js.map → sync-configs-LVBITPLU.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
REPORT_LIST_COLUMNS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QBAAZY7W.js";
|
|
4
4
|
import {
|
|
5
5
|
mapReportRecord,
|
|
6
6
|
mapWebsiteRecord
|
|
@@ -129,4 +129,4 @@ export {
|
|
|
129
129
|
checkFleetParity,
|
|
130
130
|
formatParityResult
|
|
131
131
|
};
|
|
132
|
-
//# sourceMappingURL=chunk-
|
|
132
|
+
//# sourceMappingURL=chunk-AX22DH6S.js.map
|
|
@@ -950,6 +950,12 @@ async function analyzeSite(url, crawl, checks, deps = defaultAnalyzeDeps()) {
|
|
|
950
950
|
return verifyEvidence(parsed, crawl);
|
|
951
951
|
}
|
|
952
952
|
|
|
953
|
+
// src/prospect/claude-code.ts
|
|
954
|
+
import { spawn } from "child_process";
|
|
955
|
+
import os from "os";
|
|
956
|
+
import { StringDecoder } from "string_decoder";
|
|
957
|
+
import { z as z2 } from "zod";
|
|
958
|
+
|
|
953
959
|
// src/prospect/probes.ts
|
|
954
960
|
var MAX_QUERIES = 9;
|
|
955
961
|
var SNIPPET_CHARS = 300;
|
|
@@ -1115,11 +1121,15 @@ async function runVisibilityProbes(input, engines, opts = {}) {
|
|
|
1115
1121
|
const nameIsDistinctive = isDistinctiveName(brand);
|
|
1116
1122
|
const answers = [];
|
|
1117
1123
|
const competitorCounts = /* @__PURE__ */ new Map();
|
|
1124
|
+
const perEngine = /* @__PURE__ */ new Map();
|
|
1118
1125
|
for (const engine of engines) {
|
|
1126
|
+
const tally = { categoryAttempted: 0, answeredAny: false };
|
|
1127
|
+
perEngine.set(engine.name, tally);
|
|
1119
1128
|
await pacedEach(
|
|
1120
1129
|
queries,
|
|
1121
1130
|
delayMs,
|
|
1122
1131
|
async ({ query, kind }) => {
|
|
1132
|
+
if (kind === "category") tally.categoryAttempted += 1;
|
|
1123
1133
|
let reply;
|
|
1124
1134
|
try {
|
|
1125
1135
|
reply = await engine.ask(query);
|
|
@@ -1132,6 +1142,7 @@ async function runVisibilityProbes(input, engines, opts = {}) {
|
|
|
1132
1142
|
return;
|
|
1133
1143
|
}
|
|
1134
1144
|
}
|
|
1145
|
+
tally.answeredAny = true;
|
|
1135
1146
|
const citedDomains = reply.citedDomains.map(domainOf);
|
|
1136
1147
|
const domainCited = citedDomains.some((d) => isSameSite(d, prospect));
|
|
1137
1148
|
const brandMentioned = mentionsBrand(reply.answer.toLowerCase(), brand);
|
|
@@ -1161,13 +1172,15 @@ async function runVisibilityProbes(input, engines, opts = {}) {
|
|
|
1161
1172
|
}
|
|
1162
1173
|
const categoryAnswers = answers.filter((a) => a.kind === "category");
|
|
1163
1174
|
const visibleCategory = categoryAnswers.filter((a) => a.countedAsVisible).length;
|
|
1164
|
-
const
|
|
1175
|
+
const categoryAttempted = [...perEngine.values()].filter((t) => t.answeredAny).reduce((n, t) => n + t.categoryAttempted, 0);
|
|
1176
|
+
const visibilityScore = categoryAttempted === 0 || categoryAnswers.length === 0 ? null : Math.round(visibleCategory / categoryAttempted * 100);
|
|
1165
1177
|
const brandedRecognized = answers.some((a) => a.kind === "branded" && a.domainCited);
|
|
1166
1178
|
return {
|
|
1167
1179
|
answers,
|
|
1168
1180
|
visibilityScore,
|
|
1169
1181
|
brandedRecognized,
|
|
1170
|
-
competitorsSeen: [...competitorCounts.entries()].map(([domain, count]) => ({ domain, count })).sort((a, b) => b.count - a.count).slice(0, 8)
|
|
1182
|
+
competitorsSeen: [...competitorCounts.entries()].map(([domain, count]) => ({ domain, count })).sort((a, b) => b.count - a.count).slice(0, 8),
|
|
1183
|
+
categoryProbes: { attempted: categoryAttempted, answered: categoryAnswers.length }
|
|
1171
1184
|
};
|
|
1172
1185
|
}
|
|
1173
1186
|
function perplexityEngine(apiKey, fetchImpl = fetch) {
|
|
@@ -1233,14 +1246,250 @@ function claudeWebSearchEngine(createMessage) {
|
|
|
1233
1246
|
}
|
|
1234
1247
|
};
|
|
1235
1248
|
}
|
|
1236
|
-
function defaultEngines() {
|
|
1249
|
+
function defaultEngines(claude = claudeWebSearchEngine()) {
|
|
1237
1250
|
const engines = [];
|
|
1238
1251
|
const key = process.env.PERPLEXITY_API_KEY?.trim();
|
|
1239
1252
|
if (key) engines.push(perplexityEngine(key));
|
|
1240
|
-
engines.push(
|
|
1253
|
+
engines.push(claude);
|
|
1241
1254
|
return engines;
|
|
1242
1255
|
}
|
|
1243
1256
|
|
|
1257
|
+
// src/prospect/claude-code.ts
|
|
1258
|
+
function llmAuthMode(env = process.env) {
|
|
1259
|
+
const raw = (env.PROSPECT_LLM_AUTH ?? "").trim();
|
|
1260
|
+
if (raw === "" || raw === "api") return "api";
|
|
1261
|
+
if (raw === "subscription") return "subscription";
|
|
1262
|
+
throw new Error(`PROSPECT_LLM_AUTH must be "api" or "subscription", got "${raw}"`);
|
|
1263
|
+
}
|
|
1264
|
+
function childEnv(env = process.env) {
|
|
1265
|
+
const out = { ...env };
|
|
1266
|
+
delete out.ANTHROPIC_API_KEY;
|
|
1267
|
+
delete out.ANTHROPIC_AUTH_TOKEN;
|
|
1268
|
+
delete out.CLAUDE_CODE_USE_BEDROCK;
|
|
1269
|
+
delete out.CLAUDE_CODE_USE_VERTEX;
|
|
1270
|
+
delete out.ANTHROPIC_BASE_URL;
|
|
1271
|
+
if (!out.CLAUDE_CODE_OAUTH_TOKEN && env.CLAUDE_OAUTH) {
|
|
1272
|
+
out.CLAUDE_CODE_OAUTH_TOKEN = env.CLAUDE_OAUTH;
|
|
1273
|
+
}
|
|
1274
|
+
return out;
|
|
1275
|
+
}
|
|
1276
|
+
var BASE_DISALLOWED = "Bash,Edit,Write,Read,Glob,Grep,Task,TodoWrite,NotebookEdit,WebFetch,Skill,SlashCommand";
|
|
1277
|
+
var ANALYZE_DISALLOWED = `${BASE_DISALLOWED},WebSearch`;
|
|
1278
|
+
var ISOLATION_ARGS = ["--setting-sources", "project", "--strict-mcp-config"];
|
|
1279
|
+
var PROBE_SYSTEM_PROMPT = "You are an answer engine. Answer the user's question directly and concisely, searching the web when it helps.";
|
|
1280
|
+
var ANALYZE_TIMEOUT_MS = 10 * 6e4;
|
|
1281
|
+
var PROBE_TIMEOUT_MS = 4 * 6e4;
|
|
1282
|
+
var MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
|
|
1283
|
+
function makeClaudeCodeRun(binary = "claude") {
|
|
1284
|
+
return ({ args, stdin, env, timeoutMs }) => new Promise((resolve, reject) => {
|
|
1285
|
+
const child = spawn(binary, args, { env, cwd: os.tmpdir(), stdio: ["pipe", "pipe", "pipe"] });
|
|
1286
|
+
const outDecoder = new StringDecoder("utf8");
|
|
1287
|
+
const errDecoder = new StringDecoder("utf8");
|
|
1288
|
+
let stdout = "";
|
|
1289
|
+
let stderr = "";
|
|
1290
|
+
let settled = false;
|
|
1291
|
+
const timer = setTimeout(() => {
|
|
1292
|
+
settled = true;
|
|
1293
|
+
child.kill("SIGKILL");
|
|
1294
|
+
reject(new Error(`claude -p timed out after ${timeoutMs}ms`));
|
|
1295
|
+
}, timeoutMs);
|
|
1296
|
+
const guard = () => {
|
|
1297
|
+
if (stdout.length + stderr.length <= MAX_OUTPUT_BYTES) return;
|
|
1298
|
+
settled = true;
|
|
1299
|
+
clearTimeout(timer);
|
|
1300
|
+
child.kill("SIGKILL");
|
|
1301
|
+
reject(new Error("claude -p produced more output than any real run should"));
|
|
1302
|
+
};
|
|
1303
|
+
child.stdout.on("data", (d) => {
|
|
1304
|
+
stdout += outDecoder.write(d);
|
|
1305
|
+
guard();
|
|
1306
|
+
});
|
|
1307
|
+
child.stderr.on("data", (d) => {
|
|
1308
|
+
stderr += errDecoder.write(d);
|
|
1309
|
+
guard();
|
|
1310
|
+
});
|
|
1311
|
+
child.stdin.on("error", () => {
|
|
1312
|
+
});
|
|
1313
|
+
child.on("error", (err) => {
|
|
1314
|
+
if (settled) return;
|
|
1315
|
+
settled = true;
|
|
1316
|
+
clearTimeout(timer);
|
|
1317
|
+
reject(err);
|
|
1318
|
+
});
|
|
1319
|
+
child.on("close", (code) => {
|
|
1320
|
+
if (settled) return;
|
|
1321
|
+
settled = true;
|
|
1322
|
+
clearTimeout(timer);
|
|
1323
|
+
resolve({ stdout: stdout + outDecoder.end(), stderr: stderr + errDecoder.end(), code });
|
|
1324
|
+
});
|
|
1325
|
+
child.stdin.end(stdin);
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
var defaultClaudeCodeRun = makeClaudeCodeRun();
|
|
1329
|
+
function contentBlocks(ev) {
|
|
1330
|
+
const content = ev.message?.content;
|
|
1331
|
+
if (!Array.isArray(content)) return [];
|
|
1332
|
+
return content.filter((b) => typeof b === "object" && b !== null);
|
|
1333
|
+
}
|
|
1334
|
+
function analyzeJsonSchema() {
|
|
1335
|
+
const { $schema: _meta, ...schema } = z2.toJSONSchema(AnalyzeSchema);
|
|
1336
|
+
return JSON.stringify(schema);
|
|
1337
|
+
}
|
|
1338
|
+
function claudeCodeAnalyzeDeps(run = defaultClaudeCodeRun) {
|
|
1339
|
+
return {
|
|
1340
|
+
async run({ system, user }) {
|
|
1341
|
+
const args = [
|
|
1342
|
+
"-p",
|
|
1343
|
+
"--output-format",
|
|
1344
|
+
"json",
|
|
1345
|
+
"--json-schema",
|
|
1346
|
+
analyzeJsonSchema(),
|
|
1347
|
+
"--system-prompt",
|
|
1348
|
+
system,
|
|
1349
|
+
"--model",
|
|
1350
|
+
"claude-opus-5",
|
|
1351
|
+
"--no-session-persistence",
|
|
1352
|
+
"--disallowedTools",
|
|
1353
|
+
ANALYZE_DISALLOWED,
|
|
1354
|
+
...ISOLATION_ARGS,
|
|
1355
|
+
// Spend bound: a real analyze measured ~$0.20-equivalent; this is a
|
|
1356
|
+
// runaway backstop, not a working ceiling.
|
|
1357
|
+
"--max-budget-usd",
|
|
1358
|
+
"5"
|
|
1359
|
+
];
|
|
1360
|
+
const res = await run({ args, stdin: user, env: childEnv(), timeoutMs: ANALYZE_TIMEOUT_MS });
|
|
1361
|
+
if (res.code !== 0) {
|
|
1362
|
+
throw new Error(`claude -p (analyze) exited ${res.code}: ${res.stderr.slice(0, 400)}`);
|
|
1363
|
+
}
|
|
1364
|
+
let envelope;
|
|
1365
|
+
try {
|
|
1366
|
+
envelope = JSON.parse(res.stdout);
|
|
1367
|
+
} catch {
|
|
1368
|
+
throw new Error(
|
|
1369
|
+
`claude -p (analyze) printed something other than the JSON envelope: ${res.stdout.slice(0, 200)}`
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
1372
|
+
if (envelope.is_error || envelope.subtype !== "success") {
|
|
1373
|
+
throw new Error(
|
|
1374
|
+
`claude -p (analyze) failed (${envelope.subtype ?? "unknown"}): ${String(envelope.result ?? "").slice(0, 400)}`
|
|
1375
|
+
);
|
|
1376
|
+
}
|
|
1377
|
+
if (envelope.structured_output === void 0) {
|
|
1378
|
+
throw new Error("claude -p (analyze) returned no structured_output");
|
|
1379
|
+
}
|
|
1380
|
+
return envelope.structured_output;
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
function extractLinksArray(text) {
|
|
1385
|
+
const at = text.indexOf("Links:");
|
|
1386
|
+
if (at < 0) return null;
|
|
1387
|
+
const start = text.indexOf("[", at);
|
|
1388
|
+
if (start < 0) return null;
|
|
1389
|
+
let depth = 0;
|
|
1390
|
+
let inString = false;
|
|
1391
|
+
let escaped = false;
|
|
1392
|
+
for (let i = start; i < text.length; i++) {
|
|
1393
|
+
const ch = text[i];
|
|
1394
|
+
if (escaped) {
|
|
1395
|
+
escaped = false;
|
|
1396
|
+
continue;
|
|
1397
|
+
}
|
|
1398
|
+
if (ch === "\\") {
|
|
1399
|
+
escaped = true;
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
if (ch === '"') {
|
|
1403
|
+
inString = !inString;
|
|
1404
|
+
continue;
|
|
1405
|
+
}
|
|
1406
|
+
if (inString) continue;
|
|
1407
|
+
if (ch === "[") depth++;
|
|
1408
|
+
else if (ch === "]" && --depth === 0) {
|
|
1409
|
+
try {
|
|
1410
|
+
const parsed = JSON.parse(text.slice(start, i + 1));
|
|
1411
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
1412
|
+
} catch {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
return null;
|
|
1418
|
+
}
|
|
1419
|
+
function urlsFromSearchResult(text) {
|
|
1420
|
+
const links = extractLinksArray(text);
|
|
1421
|
+
if (links) {
|
|
1422
|
+
return links.map((l) => l.url).filter((u) => typeof u === "string");
|
|
1423
|
+
}
|
|
1424
|
+
return [...text.matchAll(/https?:\/\/[^\s"'<>\])]+/g)].map((m) => m[0]);
|
|
1425
|
+
}
|
|
1426
|
+
function claudeCodeEngine(run = defaultClaudeCodeRun) {
|
|
1427
|
+
return {
|
|
1428
|
+
name: "claude-code",
|
|
1429
|
+
async ask(query) {
|
|
1430
|
+
const args = [
|
|
1431
|
+
"-p",
|
|
1432
|
+
// stream-json is refused in print mode without --verbose.
|
|
1433
|
+
"--verbose",
|
|
1434
|
+
"--output-format",
|
|
1435
|
+
"stream-json",
|
|
1436
|
+
"--allowedTools",
|
|
1437
|
+
"WebSearch",
|
|
1438
|
+
"--disallowedTools",
|
|
1439
|
+
BASE_DISALLOWED,
|
|
1440
|
+
"--model",
|
|
1441
|
+
PROBE_MODEL,
|
|
1442
|
+
"--no-session-persistence",
|
|
1443
|
+
"--system-prompt",
|
|
1444
|
+
PROBE_SYSTEM_PROMPT,
|
|
1445
|
+
...ISOLATION_ARGS,
|
|
1446
|
+
// The API engine bounds its loop (4 turns, 4 searches); the CLI has no
|
|
1447
|
+
// turn flag on this build, so bound by computed spend instead — a real
|
|
1448
|
+
// probe measured ~$0.40-equivalent.
|
|
1449
|
+
"--max-budget-usd",
|
|
1450
|
+
"2"
|
|
1451
|
+
];
|
|
1452
|
+
const res = await run({ args, stdin: query, env: childEnv(), timeoutMs: PROBE_TIMEOUT_MS });
|
|
1453
|
+
if (res.code !== 0) {
|
|
1454
|
+
throw new Error(`claude -p (probe) exited ${res.code}: ${res.stderr.slice(0, 400)}`);
|
|
1455
|
+
}
|
|
1456
|
+
const events = res.stdout.split("\n").filter(Boolean).flatMap((line) => {
|
|
1457
|
+
try {
|
|
1458
|
+
return [JSON.parse(line)];
|
|
1459
|
+
} catch {
|
|
1460
|
+
return [];
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
const searchIds = /* @__PURE__ */ new Set();
|
|
1464
|
+
for (const ev of events) {
|
|
1465
|
+
if (ev.type !== "assistant") continue;
|
|
1466
|
+
for (const block of contentBlocks(ev)) {
|
|
1467
|
+
if (block.type === "tool_use" && block.name === "WebSearch") searchIds.add(block.id);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
const citedDomains = [];
|
|
1471
|
+
for (const ev of events) {
|
|
1472
|
+
if (ev.type !== "user") continue;
|
|
1473
|
+
for (const block of contentBlocks(ev)) {
|
|
1474
|
+
if (block.type !== "tool_result" || typeof block.content !== "string") continue;
|
|
1475
|
+
if (!searchIds.has(block.tool_use_id) || block.is_error === true) continue;
|
|
1476
|
+
citedDomains.push(...urlsFromSearchResult(block.content).map(domainOf));
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
const result = events.find((ev) => ev.type === "result");
|
|
1480
|
+
if (!result) {
|
|
1481
|
+
throw new Error("claude -p (probe) produced no result event");
|
|
1482
|
+
}
|
|
1483
|
+
if (result.is_error || result.subtype !== "success") {
|
|
1484
|
+
throw new Error(
|
|
1485
|
+
`claude -p (probe) failed (${result.subtype ?? "unknown"}): ${String(result.result ?? "").slice(0, 400)}`
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
return { answer: typeof result.result === "string" ? result.result : "", citedDomains };
|
|
1489
|
+
}
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1244
1493
|
// src/prospect/lighthouse.ts
|
|
1245
1494
|
function defaultLighthouseDeps() {
|
|
1246
1495
|
return {
|
|
@@ -1275,6 +1524,15 @@ async function runLighthouse(url, deps = defaultLighthouseDeps()) {
|
|
|
1275
1524
|
}
|
|
1276
1525
|
|
|
1277
1526
|
// src/prospect/pipeline.ts
|
|
1527
|
+
function envAnalyzeDeps(factories = {
|
|
1528
|
+
api: defaultAnalyzeDeps,
|
|
1529
|
+
subscription: claudeCodeAnalyzeDeps
|
|
1530
|
+
}) {
|
|
1531
|
+
return llmAuthMode() === "subscription" ? factories.subscription() : factories.api();
|
|
1532
|
+
}
|
|
1533
|
+
function envEngines() {
|
|
1534
|
+
return llmAuthMode() === "subscription" ? defaultEngines(claudeCodeEngine()) : defaultEngines();
|
|
1535
|
+
}
|
|
1278
1536
|
var PROBES_SKIPPED = "skipped (--no-probes)";
|
|
1279
1537
|
var ANALYZE_SKIPPED = "skipped \u2014 the checks stage failed";
|
|
1280
1538
|
async function stage(name, deps, fn) {
|
|
@@ -1290,6 +1548,7 @@ async function stage(name, deps, fn) {
|
|
|
1290
1548
|
}
|
|
1291
1549
|
}
|
|
1292
1550
|
async function runProspectAudit(url, opts, deps = {}) {
|
|
1551
|
+
const llmAuth = llmAuthMode();
|
|
1293
1552
|
const crawlDeps = deps.crawl ?? defaultCrawlDeps();
|
|
1294
1553
|
deps.onStage?.("crawl", "start");
|
|
1295
1554
|
let crawlData;
|
|
@@ -1315,7 +1574,7 @@ async function runProspectAudit(url, opts, deps = {}) {
|
|
|
1315
1574
|
const analyze = checks.ok ? await stage(
|
|
1316
1575
|
"analyze",
|
|
1317
1576
|
deps,
|
|
1318
|
-
async () => analyzeSite(url, crawlData, checks.data, deps.analyze ??
|
|
1577
|
+
async () => analyzeSite(url, crawlData, checks.data, deps.analyze ?? envAnalyzeDeps())
|
|
1319
1578
|
) : { ok: false, error: ANALYZE_SKIPPED };
|
|
1320
1579
|
const businessName = opts.business?.trim() || (analyze.ok ? analyze.data.businessName : "") || null;
|
|
1321
1580
|
const probeOpts = {
|
|
@@ -1336,7 +1595,7 @@ async function runProspectAudit(url, opts, deps = {}) {
|
|
|
1336
1595
|
categoryQueries: analyze.ok ? analyze.data.categoryQueries : [],
|
|
1337
1596
|
competitors: opts.competitors ?? []
|
|
1338
1597
|
},
|
|
1339
|
-
deps.engines ??
|
|
1598
|
+
deps.engines ?? envEngines(),
|
|
1340
1599
|
probeOpts
|
|
1341
1600
|
)
|
|
1342
1601
|
);
|
|
@@ -1344,6 +1603,7 @@ async function runProspectAudit(url, opts, deps = {}) {
|
|
|
1344
1603
|
return {
|
|
1345
1604
|
url,
|
|
1346
1605
|
businessName,
|
|
1606
|
+
llmAuth,
|
|
1347
1607
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1348
1608
|
scores: computeScores({
|
|
1349
1609
|
checks: checks.ok ? checks.data : null,
|
|
@@ -1361,8 +1621,10 @@ async function runProspectAudit(url, opts, deps = {}) {
|
|
|
1361
1621
|
|
|
1362
1622
|
export {
|
|
1363
1623
|
resolveBusinessName,
|
|
1624
|
+
envAnalyzeDeps,
|
|
1625
|
+
envEngines,
|
|
1364
1626
|
PROBES_SKIPPED,
|
|
1365
1627
|
ANALYZE_SKIPPED,
|
|
1366
1628
|
runProspectAudit
|
|
1367
1629
|
};
|
|
1368
|
-
//# sourceMappingURL=chunk-
|
|
1630
|
+
//# sourceMappingURL=chunk-DXKF552B.js.map
|