@ainyc/canonry 4.99.1 → 4.100.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.
Files changed (26) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +13 -1
  2. package/assets/assets/{BacklinksPage-v2RC8wlg.js → BacklinksPage-DWZdWEm3.js} +1 -1
  3. package/assets/assets/{ChartPrimitives-B74e5pqn.js → ChartPrimitives-C-ky5206.js} +1 -1
  4. package/assets/assets/{ProjectPage-BCzS7TQn.js → ProjectPage-CpbFpi6J.js} +4 -4
  5. package/assets/assets/{RunRow-BmVPjO-m.js → RunRow-Bj-D4kZe.js} +1 -1
  6. package/assets/assets/{RunsPage-CK5atXvL.js → RunsPage-GktitsAV.js} +1 -1
  7. package/assets/assets/{SettingsPage-DarPFUPl.js → SettingsPage-AsFLFDS3.js} +1 -1
  8. package/assets/assets/{TrafficPage-Ddnn_WqU.js → TrafficPage-Cf3uCkxs.js} +1 -1
  9. package/assets/assets/{TrafficSourceDetailPage-g08SKnwZ.js → TrafficSourceDetailPage-B5t7nf9C.js} +1 -1
  10. package/assets/assets/{arrow-left-D39Vxasb.js → arrow-left-CZFQuQO_.js} +1 -1
  11. package/assets/assets/{extract-error-message-BiNWqBeh.js → extract-error-message--bieZ2IX.js} +1 -1
  12. package/assets/assets/index-9hI0ODQU.css +1 -0
  13. package/assets/assets/index-Cb2h7KkD.js +210 -0
  14. package/assets/assets/{trash-2-xh6gsnap.js → trash-2-sKO0k75f.js} +1 -1
  15. package/assets/index.html +2 -2
  16. package/dist/{chunk-4Q3LBD7A.js → chunk-74SOIAIY.js} +15 -12
  17. package/dist/{chunk-JF7EXHGA.js → chunk-ADLS64PG.js} +105 -0
  18. package/dist/{chunk-YBIT5O62.js → chunk-SNHYRSUF.js} +366 -12
  19. package/dist/{chunk-IDI6LMYL.js → chunk-UVIHWF45.js} +27 -1
  20. package/dist/cli.js +110 -4
  21. package/dist/index.js +4 -4
  22. package/dist/{intelligence-service-TWCEKVKZ.js → intelligence-service-3CRNJLUZ.js} +2 -2
  23. package/dist/mcp.js +2 -2
  24. package/package.json +8 -8
  25. package/assets/assets/index-BCuWbxUj.css +0 -1
  26. package/assets/assets/index-Dd4J1VhB.js +0 -210
package/dist/cli.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  setTelemetrySource,
28
28
  showFirstRunNotice,
29
29
  trackEvent
30
- } from "./chunk-4Q3LBD7A.js";
30
+ } from "./chunk-74SOIAIY.js";
31
31
  import {
32
32
  CliError,
33
33
  EXIT_SYSTEM_ERROR,
@@ -44,7 +44,7 @@ import {
44
44
  saveConfig,
45
45
  saveConfigPatch,
46
46
  usageError
47
- } from "./chunk-IDI6LMYL.js";
47
+ } from "./chunk-UVIHWF45.js";
48
48
  import {
49
49
  apiKeys,
50
50
  createClient,
@@ -52,7 +52,7 @@ import {
52
52
  projects,
53
53
  queries,
54
54
  renderReportHtml
55
- } from "./chunk-YBIT5O62.js";
55
+ } from "./chunk-SNHYRSUF.js";
56
56
  import {
57
57
  BacklinkSources,
58
58
  CcReleaseSyncStatuses,
@@ -72,13 +72,14 @@ import {
72
72
  formatIsoDate,
73
73
  formatMicros,
74
74
  formatRatio,
75
+ formatRelativeTime,
75
76
  formatRunErrorOneLine,
76
77
  normalizeProjectAliases,
77
78
  notificationEventSchema,
78
79
  providerQuotaPolicySchema,
79
80
  resolveProviderInput,
80
81
  winnabilityClassSchema
81
- } from "./chunk-JF7EXHGA.js";
82
+ } from "./chunk-ADLS64PG.js";
82
83
 
83
84
  // src/cli.ts
84
85
  import { pathToFileURL } from "url";
@@ -9594,6 +9595,103 @@ function pct2(value) {
9594
9595
  return `${(value * 100).toFixed(1)}%`;
9595
9596
  }
9596
9597
 
9598
+ // src/commands/portfolio.ts
9599
+ async function showPortfolio(opts) {
9600
+ const client = createApiClient();
9601
+ const portfolio = await client.getPortfolio();
9602
+ if (isMachineFormat(opts.format)) {
9603
+ if (opts.format === "jsonl") {
9604
+ emitJsonl(portfolio.changeFeed);
9605
+ return;
9606
+ }
9607
+ console.log(JSON.stringify(portfolio, null, 2));
9608
+ return;
9609
+ }
9610
+ renderHuman2(portfolio);
9611
+ }
9612
+ function renderHuman2(p) {
9613
+ const now = p.generatedAt;
9614
+ const sweep = p.lastSweepAt ? formatRelativeTime(p.lastSweepAt, now) : "never";
9615
+ console.log(`
9616
+ Portfolio \xB7 ${p.projectCount} project${p.projectCount === 1 ? "" : "s"} \xB7 last sweep ${sweep}
9617
+ `);
9618
+ const moreLabel = p.changeFeedTotal > p.changeFeed.length ? ` (showing ${p.changeFeed.length} of ${p.changeFeedTotal})` : "";
9619
+ console.log(`What changed${moreLabel}:`);
9620
+ if (p.changeFeed.length === 0) {
9621
+ const empty = p.feedEmptyState;
9622
+ console.log(` ${empty ? `${empty.title} \u2014 ${empty.detail}` : "No changes."}`);
9623
+ } else {
9624
+ for (const c of p.changeFeed) {
9625
+ console.log(` ${changeGlyph(c.tone)} ${c.title} (${formatRelativeTime(c.occurredAt, now)})`);
9626
+ if (c.detail) console.log(` ${c.detail}`);
9627
+ }
9628
+ }
9629
+ console.log("\nRecent runs (M mentioned in answer \xB7 C cited in sources):");
9630
+ if (p.recentRuns.length === 0) {
9631
+ console.log(" Run history appears here after the first sweep.");
9632
+ } else {
9633
+ for (const r of p.recentRuns) {
9634
+ console.log(
9635
+ ` ${pad(r.projectName, 20)} ${pad(runResult(r), 20)} ${pad(runWhen(r, now), 20)} ${runDuration(r)}`
9636
+ );
9637
+ }
9638
+ }
9639
+ console.log("\nProjects:");
9640
+ for (const proj of p.projects) {
9641
+ const mentioned = `M ${proj.mentionedOfTotal.mentioned}/${proj.mentionedOfTotal.total}`;
9642
+ const cited = `C ${proj.citedOfTotal.cited}/${proj.citedOfTotal.total}`;
9643
+ console.log(
9644
+ ` ${pad(proj.projectSlug, 20)} ${String(proj.mentionScore).padStart(3)} ${pad(mentioned, 10)} ${pad(cited, 10)} ${projectDelta(proj)}`
9645
+ );
9646
+ }
9647
+ console.log();
9648
+ }
9649
+ function changeGlyph(tone) {
9650
+ switch (tone) {
9651
+ case "negative":
9652
+ return "v";
9653
+ case "positive":
9654
+ return "^";
9655
+ case "caution":
9656
+ return "!";
9657
+ case "neutral":
9658
+ return ".";
9659
+ }
9660
+ }
9661
+ function runResult(r) {
9662
+ if (r.status === "failed") return r.errorSummary ?? "failed";
9663
+ if (r.mentionedCount == null || r.citedCount == null || r.totalCount == null) return "\u2014";
9664
+ return `M ${r.mentionedCount}/${r.totalCount} \xB7 C ${r.citedCount}/${r.totalCount}`;
9665
+ }
9666
+ function runWhen(r, now) {
9667
+ const ts = r.finishedAt ?? r.startedAt ?? r.createdAt;
9668
+ const rel = formatRelativeTime(ts, now);
9669
+ if (r.status === "running") return `started ${rel}`;
9670
+ if (r.status === "queued") return `queued ${rel}`;
9671
+ return `finished ${rel}`;
9672
+ }
9673
+ function runDuration(r) {
9674
+ if (r.durationMs == null) {
9675
+ return r.status === "running" ? "running" : r.status === "queued" ? "waiting" : "\u2014";
9676
+ }
9677
+ const seconds = Math.floor(r.durationMs / 1e3);
9678
+ if (seconds < 1) return "<1s";
9679
+ if (seconds < 60) return `${seconds}s`;
9680
+ return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
9681
+ }
9682
+ function projectDelta(proj) {
9683
+ if (!proj.hasEverRun) return "never run";
9684
+ const parts = [];
9685
+ if (proj.mentionDelta.gained > 0) parts.push(`+${proj.mentionDelta.gained}`);
9686
+ if (proj.mentionDelta.lost > 0) parts.push(`-${proj.mentionDelta.lost}`);
9687
+ if (parts.length === 0) return proj.mentionDelta.comparable ? "no change" : "first sweep";
9688
+ return `${parts.join(" ")} mentioned${proj.mentionDelta.comparable ? "" : "*"}`;
9689
+ }
9690
+ function pad(value, width) {
9691
+ if (value.length >= width) return `${value.slice(0, width - 1)} `;
9692
+ return value.padEnd(width);
9693
+ }
9694
+
9597
9695
  // src/commands/search.ts
9598
9696
  async function searchProject(project, opts) {
9599
9697
  const client = createApiClient();
@@ -9793,6 +9891,14 @@ var INTELLIGENCE_CLI_COMMANDS = [
9793
9891
  await showOverview(project, { format: input.format, location, since });
9794
9892
  }
9795
9893
  },
9894
+ {
9895
+ path: ["portfolio"],
9896
+ usage: "canonry portfolio [--format json|jsonl]",
9897
+ options: {},
9898
+ run: async (input) => {
9899
+ await showPortfolio({ format: input.format });
9900
+ }
9901
+ },
9796
9902
  {
9797
9903
  path: ["search"],
9798
9904
  usage: "canonry search <project> <query> [--limit <n>] [--format json]",
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-4Q3LBD7A.js";
3
+ } from "./chunk-74SOIAIY.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-IDI6LMYL.js";
7
- import "./chunk-YBIT5O62.js";
8
- import "./chunk-JF7EXHGA.js";
6
+ } from "./chunk-UVIHWF45.js";
7
+ import "./chunk-SNHYRSUF.js";
8
+ import "./chunk-ADLS64PG.js";
9
9
  export {
10
10
  createServer,
11
11
  loadConfig
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-YBIT5O62.js";
4
- import "./chunk-JF7EXHGA.js";
3
+ } from "./chunk-SNHYRSUF.js";
4
+ import "./chunk-ADLS64PG.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -3,10 +3,10 @@ import {
3
3
  PACKAGE_VERSION,
4
4
  canonryMcpTools,
5
5
  createApiClient
6
- } from "./chunk-IDI6LMYL.js";
6
+ } from "./chunk-UVIHWF45.js";
7
7
  import {
8
8
  isReadOnlyKey
9
- } from "./chunk-JF7EXHGA.js";
9
+ } from "./chunk-ADLS64PG.js";
10
10
 
11
11
  // src/mcp/cli.ts
12
12
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "4.99.1",
3
+ "version": "4.100.0",
4
4
  "type": "module",
5
5
  "description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -62,25 +62,25 @@
62
62
  "@types/node-cron": "^3.0.11",
63
63
  "tsup": "^8.5.1",
64
64
  "tsx": "^4.19.0",
65
- "@ainyc/canonry-api-routes": "0.0.0",
66
65
  "@ainyc/canonry-api-client": "0.0.0",
66
+ "@ainyc/canonry-api-routes": "0.0.0",
67
+ "@ainyc/canonry-contracts": "0.0.0",
67
68
  "@ainyc/canonry-db": "0.0.0",
68
69
  "@ainyc/canonry-integration-bing": "0.0.0",
69
- "@ainyc/canonry-integration-openai-ads": "0.0.0",
70
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
71
70
  "@ainyc/canonry-config": "0.0.0",
71
+ "@ainyc/canonry-integration-openai-ads": "0.0.0",
72
72
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
73
73
  "@ainyc/canonry-integration-google": "0.0.0",
74
74
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
75
- "@ainyc/canonry-contracts": "0.0.0",
76
- "@ainyc/canonry-integration-traffic": "0.0.0",
77
- "@ainyc/canonry-intelligence": "0.0.0",
75
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
78
76
  "@ainyc/canonry-integration-google-places": "0.0.0",
77
+ "@ainyc/canonry-integration-traffic": "0.0.0",
79
78
  "@ainyc/canonry-integration-wordpress": "0.0.0",
80
79
  "@ainyc/canonry-provider-cdp": "0.0.0",
80
+ "@ainyc/canonry-intelligence": "0.0.0",
81
81
  "@ainyc/canonry-provider-claude": "0.0.0",
82
- "@ainyc/canonry-provider-gemini": "0.0.0",
83
82
  "@ainyc/canonry-provider-local": "0.0.0",
83
+ "@ainyc/canonry-provider-gemini": "0.0.0",
84
84
  "@ainyc/canonry-provider-perplexity": "0.0.0",
85
85
  "@ainyc/canonry-provider-openai": "0.0.0"
86
86
  },