@ainyc/canonry 1.39.5 → 1.40.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/{chunk-FQEUZHFU.js → chunk-FXHVGU5S.js} +4 -7
- package/dist/cli.js +161 -55
- package/dist/index.js +1 -1
- package/package.json +5 -5
|
@@ -13620,7 +13620,8 @@ var Notifier = class {
|
|
|
13620
13620
|
if (lostTransitions.length > 0) events.push("citation.lost");
|
|
13621
13621
|
if (gainedTransitions.length > 0) events.push("citation.gained");
|
|
13622
13622
|
for (const notif of notifs) {
|
|
13623
|
-
const config =
|
|
13623
|
+
const config = parseJsonColumn(notif.config, { url: "", events: [] });
|
|
13624
|
+
if (!config.url) continue;
|
|
13624
13625
|
const subscribedEvents = config.events;
|
|
13625
13626
|
const matchingEvents = events.filter((e) => subscribedEvents.includes(e));
|
|
13626
13627
|
log5.info("notification.match", { notificationId: notif.id, subscribedEvents, matchedEvents: matchingEvents });
|
|
@@ -14971,12 +14972,8 @@ async function createServer(opts) {
|
|
|
14971
14972
|
after: afterConfig
|
|
14972
14973
|
});
|
|
14973
14974
|
const affectedProjectIds = opts.db.select({ id: projects.id, providers: projects.providers }).from(projects).all().filter((project) => {
|
|
14974
|
-
|
|
14975
|
-
|
|
14976
|
-
return configuredProviders.length === 0 || configuredProviders.includes(name);
|
|
14977
|
-
} catch {
|
|
14978
|
-
return false;
|
|
14979
|
-
}
|
|
14975
|
+
const configuredProviders = parseJsonColumn(project.providers, []);
|
|
14976
|
+
return configuredProviders.length === 0 || configuredProviders.includes(name);
|
|
14980
14977
|
}).map((project) => project.id);
|
|
14981
14978
|
const targetProjectIds = affectedProjectIds.length > 0 ? affectedProjectIds : [null];
|
|
14982
14979
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
package/dist/cli.js
CHANGED
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
setGoogleAuthConfig,
|
|
29
29
|
showFirstRunNotice,
|
|
30
30
|
trackEvent
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-FXHVGU5S.js";
|
|
32
32
|
import {
|
|
33
33
|
apiKeys,
|
|
34
34
|
competitors,
|
|
@@ -118,9 +118,9 @@ import { parseArgs } from "util";
|
|
|
118
118
|
function commandId(spec) {
|
|
119
119
|
return spec.path.join(".");
|
|
120
120
|
}
|
|
121
|
-
function matchesPath(args,
|
|
122
|
-
if (args.length <
|
|
123
|
-
return
|
|
121
|
+
function matchesPath(args, path6) {
|
|
122
|
+
if (args.length < path6.length) return false;
|
|
123
|
+
return path6.every((segment, index) => args[index] === segment);
|
|
124
124
|
}
|
|
125
125
|
function withFormatOption(options) {
|
|
126
126
|
if (!options) {
|
|
@@ -613,9 +613,9 @@ var ApiClient = class {
|
|
|
613
613
|
}
|
|
614
614
|
return this.probePromise;
|
|
615
615
|
}
|
|
616
|
-
async request(method,
|
|
616
|
+
async request(method, path6, body) {
|
|
617
617
|
await this.probeBasePath();
|
|
618
|
-
const url = `${this.baseUrl}${
|
|
618
|
+
const url = `${this.baseUrl}${path6}`;
|
|
619
619
|
const serializedBody = body != null ? JSON.stringify(body) : void 0;
|
|
620
620
|
const headers = {
|
|
621
621
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
@@ -1641,9 +1641,9 @@ async function gaConnect(project, opts) {
|
|
|
1641
1641
|
propertyId: opts.propertyId
|
|
1642
1642
|
};
|
|
1643
1643
|
if (opts.keyFile) {
|
|
1644
|
-
const
|
|
1644
|
+
const fs8 = await import("fs");
|
|
1645
1645
|
try {
|
|
1646
|
-
const content =
|
|
1646
|
+
const content = fs8.readFileSync(opts.keyFile, "utf-8");
|
|
1647
1647
|
JSON.parse(content);
|
|
1648
1648
|
body.keyJson = content;
|
|
1649
1649
|
} catch (e) {
|
|
@@ -4657,6 +4657,10 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
4657
4657
|
}
|
|
4658
4658
|
];
|
|
4659
4659
|
|
|
4660
|
+
// src/commands/snapshot.ts
|
|
4661
|
+
import fs4 from "fs";
|
|
4662
|
+
import path2 from "path";
|
|
4663
|
+
|
|
4660
4664
|
// src/snapshot-pdf.ts
|
|
4661
4665
|
import fs3 from "fs";
|
|
4662
4666
|
import path from "path";
|
|
@@ -4988,6 +4992,13 @@ function wrapText(font, text, size, maxWidth) {
|
|
|
4988
4992
|
function getClient16() {
|
|
4989
4993
|
return createApiClient();
|
|
4990
4994
|
}
|
|
4995
|
+
function slugify(value) {
|
|
4996
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
4997
|
+
}
|
|
4998
|
+
function autoOutputPath(companyName, ext) {
|
|
4999
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5000
|
+
return `${slugify(companyName)}-snapshot-${date}.${ext}`;
|
|
5001
|
+
}
|
|
4991
5002
|
async function createSnapshotReport(companyName, opts) {
|
|
4992
5003
|
const client = getClient16();
|
|
4993
5004
|
const report = await client.createSnapshot({
|
|
@@ -4996,23 +5007,110 @@ async function createSnapshotReport(companyName, opts) {
|
|
|
4996
5007
|
...opts.phrases && opts.phrases.length > 0 ? { phrases: opts.phrases } : {},
|
|
4997
5008
|
...opts.competitors && opts.competitors.length > 0 ? { competitors: opts.competitors } : {}
|
|
4998
5009
|
});
|
|
5010
|
+
let savedMdPath;
|
|
5011
|
+
if (opts.md) {
|
|
5012
|
+
const mdPath = opts.outputPath ?? autoOutputPath(companyName, "md");
|
|
5013
|
+
savedMdPath = writeSnapshotMarkdown(report, mdPath);
|
|
5014
|
+
}
|
|
4999
5015
|
let savedPdfPath;
|
|
5000
5016
|
if (opts.pdf) {
|
|
5001
|
-
|
|
5017
|
+
const pdfPath = opts.outputPath && !opts.md ? opts.outputPath : autoOutputPath(companyName, "pdf");
|
|
5018
|
+
savedPdfPath = await writeSnapshotPdf(report, pdfPath);
|
|
5002
5019
|
}
|
|
5003
5020
|
if (opts.format === "json") {
|
|
5004
5021
|
console.log(JSON.stringify(report, null, 2));
|
|
5005
|
-
if (
|
|
5006
|
-
|
|
5022
|
+
if (savedMdPath) process.stderr.write(`Saved markdown: ${savedMdPath}
|
|
5023
|
+
`);
|
|
5024
|
+
if (savedPdfPath) process.stderr.write(`Saved PDF: ${savedPdfPath}
|
|
5007
5025
|
`);
|
|
5008
|
-
}
|
|
5009
5026
|
return;
|
|
5010
5027
|
}
|
|
5011
5028
|
console.log(formatSnapshotText(report));
|
|
5012
|
-
if (
|
|
5013
|
-
|
|
5029
|
+
if (savedMdPath) console.log(`
|
|
5030
|
+
Markdown saved: ${savedMdPath}`);
|
|
5031
|
+
if (savedPdfPath) console.log(`
|
|
5014
5032
|
PDF saved: ${savedPdfPath}`);
|
|
5033
|
+
}
|
|
5034
|
+
function writeSnapshotMarkdown(report, outputPath) {
|
|
5035
|
+
const resolvedPath = path2.resolve(outputPath);
|
|
5036
|
+
fs4.mkdirSync(path2.dirname(resolvedPath), { recursive: true });
|
|
5037
|
+
fs4.writeFileSync(resolvedPath, formatSnapshotMarkdown(report), "utf-8");
|
|
5038
|
+
return resolvedPath;
|
|
5039
|
+
}
|
|
5040
|
+
function formatSnapshotMarkdown(report) {
|
|
5041
|
+
const lines = [];
|
|
5042
|
+
lines.push(`# AI Perception Snapshot: ${report.companyName}`);
|
|
5043
|
+
lines.push("");
|
|
5044
|
+
lines.push(`**Domain:** ${report.domain}`);
|
|
5045
|
+
lines.push(`**Generated:** ${new Date(report.generatedAt).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "2-digit" })}`);
|
|
5046
|
+
lines.push(`**AEO Audit Score:** ${report.audit.overallScore}/100 (${report.audit.overallGrade})`);
|
|
5047
|
+
lines.push("");
|
|
5048
|
+
lines.push("## Visibility Gap");
|
|
5049
|
+
lines.push("");
|
|
5050
|
+
lines.push(report.summary.visibilityGap);
|
|
5051
|
+
lines.push("");
|
|
5052
|
+
if (report.summary.whatThisMeans.length > 0) {
|
|
5053
|
+
lines.push("## What This Means");
|
|
5054
|
+
lines.push("");
|
|
5055
|
+
for (const item of report.summary.whatThisMeans) {
|
|
5056
|
+
lines.push(`- ${item}`);
|
|
5057
|
+
}
|
|
5058
|
+
lines.push("");
|
|
5015
5059
|
}
|
|
5060
|
+
if (report.summary.recommendedActions.length > 0) {
|
|
5061
|
+
lines.push("## Recommended Actions");
|
|
5062
|
+
lines.push("");
|
|
5063
|
+
for (const action of report.summary.recommendedActions) {
|
|
5064
|
+
lines.push(`- ${action}`);
|
|
5065
|
+
}
|
|
5066
|
+
lines.push("");
|
|
5067
|
+
}
|
|
5068
|
+
if (report.summary.topCompetitors.length > 0) {
|
|
5069
|
+
lines.push("## Competitors AI Recommends Instead");
|
|
5070
|
+
lines.push("");
|
|
5071
|
+
lines.push("| Competitor | Mentions |");
|
|
5072
|
+
lines.push("|------------|----------|");
|
|
5073
|
+
for (const entry of report.summary.topCompetitors) {
|
|
5074
|
+
lines.push(`| ${entry.name} | ${entry.count} |`);
|
|
5075
|
+
}
|
|
5076
|
+
lines.push("");
|
|
5077
|
+
}
|
|
5078
|
+
lines.push("## Provider Comparison");
|
|
5079
|
+
lines.push("");
|
|
5080
|
+
for (const query of report.queryResults) {
|
|
5081
|
+
lines.push(`### "${query.phrase}"`);
|
|
5082
|
+
lines.push("");
|
|
5083
|
+
lines.push("| Provider | Mentioned | Cited | Accuracy | Competitors Recommended |");
|
|
5084
|
+
lines.push("|----------|-----------|-------|----------|------------------------|");
|
|
5085
|
+
for (const result of query.providerResults) {
|
|
5086
|
+
if (result.error) {
|
|
5087
|
+
lines.push(`| ${result.displayName} | ERROR | - | - | ${result.error} |`);
|
|
5088
|
+
continue;
|
|
5089
|
+
}
|
|
5090
|
+
const mentioned = result.mentioned ? "Yes" : "No";
|
|
5091
|
+
const cited = result.cited ? "Yes" : "No";
|
|
5092
|
+
const accuracy = result.describedAccurately === "not-mentioned" ? "-" : result.describedAccurately;
|
|
5093
|
+
const competitors2 = result.recommendedCompetitors.length > 0 ? result.recommendedCompetitors.join(", ") : "-";
|
|
5094
|
+
lines.push(`| ${result.displayName} | ${mentioned} | ${cited} | ${accuracy} | ${competitors2} |`);
|
|
5095
|
+
}
|
|
5096
|
+
lines.push("");
|
|
5097
|
+
}
|
|
5098
|
+
if (report.audit.factors.length > 0) {
|
|
5099
|
+
lines.push("## Audit Factors");
|
|
5100
|
+
lines.push("");
|
|
5101
|
+
lines.push(report.audit.summary);
|
|
5102
|
+
lines.push("");
|
|
5103
|
+
lines.push("| Factor | Score | Weight | Status |");
|
|
5104
|
+
lines.push("|--------|-------|--------|--------|");
|
|
5105
|
+
const sorted = [...report.audit.factors].sort((a, b) => a.score - b.score);
|
|
5106
|
+
for (const factor of sorted) {
|
|
5107
|
+
lines.push(`| ${factor.name} | ${factor.score} | ${factor.weight} | ${factor.status} |`);
|
|
5108
|
+
}
|
|
5109
|
+
lines.push("");
|
|
5110
|
+
}
|
|
5111
|
+
lines.push("---");
|
|
5112
|
+
lines.push(`*Generated by [Canonry](https://github.com/AINYC/canonry)*`);
|
|
5113
|
+
return lines.join("\n");
|
|
5016
5114
|
}
|
|
5017
5115
|
function formatSnapshotText(report) {
|
|
5018
5116
|
const lines = [];
|
|
@@ -5080,15 +5178,17 @@ function parseCsvOption(value) {
|
|
|
5080
5178
|
var SNAPSHOT_CLI_COMMANDS = [
|
|
5081
5179
|
{
|
|
5082
5180
|
path: ["snapshot"],
|
|
5083
|
-
usage: 'canonry snapshot <company-name> --domain <domain> [--phrases "a,b"] [--competitors "x,y"] [--
|
|
5181
|
+
usage: 'canonry snapshot <company-name> --domain <domain> [--phrases "a,b"] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]',
|
|
5084
5182
|
options: {
|
|
5085
5183
|
domain: stringOption(),
|
|
5086
5184
|
phrases: stringOption(),
|
|
5087
5185
|
competitors: stringOption(),
|
|
5088
|
-
|
|
5186
|
+
md: { type: "boolean" },
|
|
5187
|
+
pdf: { type: "boolean" },
|
|
5188
|
+
output: stringOption()
|
|
5089
5189
|
},
|
|
5090
5190
|
run: async (input) => {
|
|
5091
|
-
const usage = 'canonry snapshot <company-name> --domain <domain> [--phrases "a,b"] [--competitors "x,y"] [--
|
|
5191
|
+
const usage = 'canonry snapshot <company-name> --domain <domain> [--phrases "a,b"] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]';
|
|
5092
5192
|
const companyName = requirePositional(input, 0, {
|
|
5093
5193
|
command: "snapshot",
|
|
5094
5194
|
usage,
|
|
@@ -5099,11 +5199,17 @@ var SNAPSHOT_CLI_COMMANDS = [
|
|
|
5099
5199
|
usage,
|
|
5100
5200
|
message: "--domain is required"
|
|
5101
5201
|
});
|
|
5202
|
+
const outputPath = getString(input.values, "output");
|
|
5203
|
+
const explicitMd = getBoolean(input.values, "md");
|
|
5204
|
+
const wantsPdf = getBoolean(input.values, "pdf");
|
|
5205
|
+
const wantsMd = explicitMd || !!outputPath && !wantsPdf;
|
|
5102
5206
|
await createSnapshotReport(companyName, {
|
|
5103
5207
|
domain,
|
|
5104
5208
|
phrases: parseCsvOption(getString(input.values, "phrases")),
|
|
5105
5209
|
competitors: parseCsvOption(getString(input.values, "competitors")),
|
|
5106
|
-
|
|
5210
|
+
md: wantsMd,
|
|
5211
|
+
pdf: wantsPdf,
|
|
5212
|
+
outputPath,
|
|
5107
5213
|
format: input.format
|
|
5108
5214
|
});
|
|
5109
5215
|
}
|
|
@@ -5232,7 +5338,7 @@ var INTELLIGENCE_CLI_COMMANDS = [
|
|
|
5232
5338
|
|
|
5233
5339
|
// src/commands/bootstrap.ts
|
|
5234
5340
|
import crypto from "crypto";
|
|
5235
|
-
import
|
|
5341
|
+
import path3 from "path";
|
|
5236
5342
|
import { eq as eq2 } from "drizzle-orm";
|
|
5237
5343
|
|
|
5238
5344
|
// ../config/src/index.ts
|
|
@@ -5379,7 +5485,7 @@ async function bootstrapCommand(_opts) {
|
|
|
5379
5485
|
);
|
|
5380
5486
|
}
|
|
5381
5487
|
const configDir = getConfigDir();
|
|
5382
|
-
const databasePath = env.databasePath ||
|
|
5488
|
+
const databasePath = env.databasePath || path3.join(configDir, "data.db");
|
|
5383
5489
|
const existing = configExists();
|
|
5384
5490
|
const existingConfig = existing ? loadConfig() : void 0;
|
|
5385
5491
|
let rawApiKey;
|
|
@@ -5449,10 +5555,10 @@ async function bootstrapCommand(_opts) {
|
|
|
5449
5555
|
|
|
5450
5556
|
// src/commands/daemon.ts
|
|
5451
5557
|
import { spawn } from "child_process";
|
|
5452
|
-
import
|
|
5453
|
-
import
|
|
5558
|
+
import fs5 from "fs";
|
|
5559
|
+
import path4 from "path";
|
|
5454
5560
|
function getPidPath() {
|
|
5455
|
-
return
|
|
5561
|
+
return path4.join(getConfigDir(), "canonry.pid");
|
|
5456
5562
|
}
|
|
5457
5563
|
function isProcessAlive(pid) {
|
|
5458
5564
|
try {
|
|
@@ -5479,8 +5585,8 @@ async function waitForReady(host, port, maxMs = 1e4) {
|
|
|
5479
5585
|
async function startDaemon(opts) {
|
|
5480
5586
|
const pidPath = getPidPath();
|
|
5481
5587
|
const format = opts.format ?? "text";
|
|
5482
|
-
if (
|
|
5483
|
-
const existingPid = parseInt(
|
|
5588
|
+
if (fs5.existsSync(pidPath)) {
|
|
5589
|
+
const existingPid = parseInt(fs5.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
5484
5590
|
if (!isNaN(existingPid) && isProcessAlive(existingPid)) {
|
|
5485
5591
|
throw new CliError({
|
|
5486
5592
|
code: "DAEMON_ALREADY_RUNNING",
|
|
@@ -5491,9 +5597,9 @@ async function startDaemon(opts) {
|
|
|
5491
5597
|
}
|
|
5492
5598
|
});
|
|
5493
5599
|
}
|
|
5494
|
-
|
|
5600
|
+
fs5.unlinkSync(pidPath);
|
|
5495
5601
|
}
|
|
5496
|
-
const cliPath =
|
|
5602
|
+
const cliPath = path4.resolve(new URL(import.meta.url).pathname);
|
|
5497
5603
|
const inSourceMode = new URL(import.meta.url).pathname.endsWith(".ts");
|
|
5498
5604
|
const args = inSourceMode ? ["--import", "tsx", cliPath, "serve"] : [cliPath, "serve"];
|
|
5499
5605
|
if (opts.port) args.push("--port", opts.port);
|
|
@@ -5512,10 +5618,10 @@ async function startDaemon(opts) {
|
|
|
5512
5618
|
});
|
|
5513
5619
|
}
|
|
5514
5620
|
const configDir = getConfigDir();
|
|
5515
|
-
if (!
|
|
5516
|
-
|
|
5621
|
+
if (!fs5.existsSync(configDir)) {
|
|
5622
|
+
fs5.mkdirSync(configDir, { recursive: true });
|
|
5517
5623
|
}
|
|
5518
|
-
|
|
5624
|
+
fs5.writeFileSync(pidPath, String(child.pid), "utf-8");
|
|
5519
5625
|
const port = opts.port ?? "4100";
|
|
5520
5626
|
const host = opts.host ?? "127.0.0.1";
|
|
5521
5627
|
if (format !== "json") {
|
|
@@ -5524,7 +5630,7 @@ async function startDaemon(opts) {
|
|
|
5524
5630
|
const ready = await waitForReady(host, port);
|
|
5525
5631
|
if (!ready) {
|
|
5526
5632
|
try {
|
|
5527
|
-
|
|
5633
|
+
fs5.unlinkSync(pidPath);
|
|
5528
5634
|
} catch {
|
|
5529
5635
|
}
|
|
5530
5636
|
throw new CliError({
|
|
@@ -5556,7 +5662,7 @@ async function startDaemon(opts) {
|
|
|
5556
5662
|
}
|
|
5557
5663
|
function stopDaemon(format = "text") {
|
|
5558
5664
|
const pidPath = getPidPath();
|
|
5559
|
-
if (!
|
|
5665
|
+
if (!fs5.existsSync(pidPath)) {
|
|
5560
5666
|
if (format === "json") {
|
|
5561
5667
|
console.log(JSON.stringify({
|
|
5562
5668
|
stopped: false,
|
|
@@ -5567,7 +5673,7 @@ function stopDaemon(format = "text") {
|
|
|
5567
5673
|
console.log("Canonry is not running (no PID file found)");
|
|
5568
5674
|
return;
|
|
5569
5675
|
}
|
|
5570
|
-
const pid = parseInt(
|
|
5676
|
+
const pid = parseInt(fs5.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
5571
5677
|
if (isNaN(pid)) {
|
|
5572
5678
|
if (format === "json") {
|
|
5573
5679
|
console.log(JSON.stringify({
|
|
@@ -5578,7 +5684,7 @@ function stopDaemon(format = "text") {
|
|
|
5578
5684
|
} else {
|
|
5579
5685
|
console.error("Invalid PID file. Removing it.");
|
|
5580
5686
|
}
|
|
5581
|
-
|
|
5687
|
+
fs5.unlinkSync(pidPath);
|
|
5582
5688
|
return;
|
|
5583
5689
|
}
|
|
5584
5690
|
if (!isProcessAlive(pid)) {
|
|
@@ -5592,12 +5698,12 @@ function stopDaemon(format = "text") {
|
|
|
5592
5698
|
} else {
|
|
5593
5699
|
console.log(`Canonry is not running (stale PID: ${pid}). Cleaning up.`);
|
|
5594
5700
|
}
|
|
5595
|
-
|
|
5701
|
+
fs5.unlinkSync(pidPath);
|
|
5596
5702
|
return;
|
|
5597
5703
|
}
|
|
5598
5704
|
try {
|
|
5599
5705
|
process.kill(pid, "SIGTERM");
|
|
5600
|
-
|
|
5706
|
+
fs5.unlinkSync(pidPath);
|
|
5601
5707
|
if (format === "json") {
|
|
5602
5708
|
console.log(JSON.stringify({
|
|
5603
5709
|
stopped: true,
|
|
@@ -5621,9 +5727,9 @@ function stopDaemon(format = "text") {
|
|
|
5621
5727
|
|
|
5622
5728
|
// src/commands/init.ts
|
|
5623
5729
|
import crypto2 from "crypto";
|
|
5624
|
-
import
|
|
5730
|
+
import fs6 from "fs";
|
|
5625
5731
|
import readline from "readline";
|
|
5626
|
-
import
|
|
5732
|
+
import path5 from "path";
|
|
5627
5733
|
function prompt(question) {
|
|
5628
5734
|
const rl = readline.createInterface({
|
|
5629
5735
|
input: process.stdin,
|
|
@@ -5660,8 +5766,8 @@ async function initCommand(opts) {
|
|
|
5660
5766
|
return;
|
|
5661
5767
|
}
|
|
5662
5768
|
const configDir = getConfigDir();
|
|
5663
|
-
if (!
|
|
5664
|
-
|
|
5769
|
+
if (!fs6.existsSync(configDir)) {
|
|
5770
|
+
fs6.mkdirSync(configDir, { recursive: true });
|
|
5665
5771
|
}
|
|
5666
5772
|
const bootstrapEnv = getBootstrapEnv(process.env, {
|
|
5667
5773
|
GEMINI_API_KEY: opts?.geminiKey,
|
|
@@ -5776,7 +5882,7 @@ async function initCommand(opts) {
|
|
|
5776
5882
|
const rawApiKey = `cnry_${crypto2.randomBytes(16).toString("hex")}`;
|
|
5777
5883
|
const keyHash = crypto2.createHash("sha256").update(rawApiKey).digest("hex");
|
|
5778
5884
|
const keyPrefix = rawApiKey.slice(0, 9);
|
|
5779
|
-
const databasePath =
|
|
5885
|
+
const databasePath = path5.join(configDir, "data.db");
|
|
5780
5886
|
const db = createClient(databasePath);
|
|
5781
5887
|
migrate(db);
|
|
5782
5888
|
db.insert(apiKeys).values({
|
|
@@ -6138,7 +6244,7 @@ var SYSTEM_CLI_COMMANDS = [
|
|
|
6138
6244
|
];
|
|
6139
6245
|
|
|
6140
6246
|
// src/cli-commands/wordpress.ts
|
|
6141
|
-
import
|
|
6247
|
+
import fs7 from "fs";
|
|
6142
6248
|
|
|
6143
6249
|
// src/commands/wordpress.ts
|
|
6144
6250
|
function getClient17() {
|
|
@@ -6374,12 +6480,12 @@ async function wordpressSetMeta(project, body) {
|
|
|
6374
6480
|
printPageDetail(result);
|
|
6375
6481
|
}
|
|
6376
6482
|
async function wordpressBulkSetMeta(project, opts) {
|
|
6377
|
-
const
|
|
6378
|
-
const
|
|
6379
|
-
const filePath =
|
|
6483
|
+
const fs8 = await import("fs/promises");
|
|
6484
|
+
const path6 = await import("path");
|
|
6485
|
+
const filePath = path6.resolve(opts.from);
|
|
6380
6486
|
let raw;
|
|
6381
6487
|
try {
|
|
6382
|
-
raw = await
|
|
6488
|
+
raw = await fs8.readFile(filePath, "utf8");
|
|
6383
6489
|
} catch {
|
|
6384
6490
|
throw new CliError({
|
|
6385
6491
|
code: "FILE_READ_ERROR",
|
|
@@ -6476,13 +6582,13 @@ async function wordpressSetSchema(project, body) {
|
|
|
6476
6582
|
printManualAssist(`Schema update for "${body.slug}"`, result);
|
|
6477
6583
|
}
|
|
6478
6584
|
async function wordpressSchemaDeploy(project, opts) {
|
|
6479
|
-
const
|
|
6480
|
-
const
|
|
6585
|
+
const fs8 = await import("fs/promises");
|
|
6586
|
+
const path6 = await import("path");
|
|
6481
6587
|
const yaml = await import("yaml").catch(() => null);
|
|
6482
|
-
const filePath =
|
|
6588
|
+
const filePath = path6.resolve(opts.profile);
|
|
6483
6589
|
let raw;
|
|
6484
6590
|
try {
|
|
6485
|
-
raw = await
|
|
6591
|
+
raw = await fs8.readFile(filePath, "utf8");
|
|
6486
6592
|
} catch {
|
|
6487
6593
|
throw new CliError({
|
|
6488
6594
|
code: "FILE_READ_ERROR",
|
|
@@ -6587,13 +6693,13 @@ async function wordpressOnboard(project, opts) {
|
|
|
6587
6693
|
}
|
|
6588
6694
|
let profileData;
|
|
6589
6695
|
if (opts.profile) {
|
|
6590
|
-
const
|
|
6591
|
-
const
|
|
6696
|
+
const fs8 = await import("fs/promises");
|
|
6697
|
+
const path6 = await import("path");
|
|
6592
6698
|
const yaml = await import("yaml").catch(() => null);
|
|
6593
|
-
const filePath =
|
|
6699
|
+
const filePath = path6.resolve(opts.profile);
|
|
6594
6700
|
let raw;
|
|
6595
6701
|
try {
|
|
6596
|
-
raw = await
|
|
6702
|
+
raw = await fs8.readFile(filePath, "utf8");
|
|
6597
6703
|
} catch {
|
|
6598
6704
|
throw new CliError({
|
|
6599
6705
|
code: "FILE_READ_ERROR",
|
|
@@ -6742,7 +6848,7 @@ function resolveContent(input, command, usage, options) {
|
|
|
6742
6848
|
}
|
|
6743
6849
|
if (contentFile) {
|
|
6744
6850
|
try {
|
|
6745
|
-
return
|
|
6851
|
+
return fs7.readFileSync(contentFile, "utf-8");
|
|
6746
6852
|
} catch (error) {
|
|
6747
6853
|
const message = error instanceof Error ? error.message : String(error);
|
|
6748
6854
|
throw usageError(`Error: could not read --content-file "${contentFile}": ${message}`, {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.40.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The ultimate open-source AEO monitoring tool - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -54,17 +54,17 @@
|
|
|
54
54
|
"@types/node-cron": "^3.0.11",
|
|
55
55
|
"tsup": "^8.5.1",
|
|
56
56
|
"tsx": "^4.19.0",
|
|
57
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
58
57
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
59
58
|
"@ainyc/canonry-db": "0.0.0",
|
|
60
59
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
61
60
|
"@ainyc/canonry-config": "0.0.0",
|
|
61
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
62
62
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
63
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
64
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
63
65
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
64
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
65
66
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
66
|
-
"@ainyc/canonry-provider-
|
|
67
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
67
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
68
68
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
69
69
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
70
70
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|