@ainyc/canonry 4.51.4 → 4.53.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 (24) hide show
  1. package/assets/assets/{BacklinksPage-9TlM08Wf.js → BacklinksPage-DELb5ok3.js} +1 -1
  2. package/assets/assets/ProjectPage-CM_uQa2L.js +6 -0
  3. package/assets/assets/{RunRow-D7qdWWRl.js → RunRow-aqJEr7XJ.js} +1 -1
  4. package/assets/assets/{RunsPage-CvewepfU.js → RunsPage-Dhuj1w72.js} +1 -1
  5. package/assets/assets/{SettingsPage-C7BvAhiB.js → SettingsPage-B2_vxr4y.js} +1 -1
  6. package/assets/assets/{TrafficPage-DC3NhFOh.js → TrafficPage-BKaiZRIH.js} +1 -1
  7. package/assets/assets/TrafficSourceDetailPage-DXIQ4g9S.js +1 -0
  8. package/assets/assets/{arrow-left-Agb02DMK.js → arrow-left-CYjzP3M3.js} +1 -1
  9. package/assets/assets/{index-DTCZ93Ne.js → index-BStwmAg6.js} +55 -55
  10. package/assets/assets/{index-DeGyEwik.css → index-Bm3JQsW0.css} +1 -1
  11. package/assets/assets/{server-traffic-C-0Ndjpw.js → server-traffic-D_1gSi-b.js} +1 -1
  12. package/assets/assets/{trash-2-lkrXVRRm.js → trash-2-8JiADnUJ.js} +1 -1
  13. package/assets/index.html +2 -2
  14. package/dist/{chunk-HMZKIOLG.js → chunk-J7MX3YOH.js} +1 -1
  15. package/dist/{chunk-QZ5XSM6C.js → chunk-JHAHNKSN.js} +103 -1
  16. package/dist/{chunk-WBO5S3IX.js → chunk-KVE7RLBI.js} +452 -63
  17. package/dist/{chunk-FYGBW3SM.js → chunk-VZPDBHBW.js} +29 -1
  18. package/dist/cli.js +40 -27
  19. package/dist/index.js +4 -4
  20. package/dist/{intelligence-service-2XL2M7QP.js → intelligence-service-OCREQUCQ.js} +2 -2
  21. package/dist/mcp.js +2 -2
  22. package/package.json +10 -10
  23. package/assets/assets/ProjectPage-CD591qDz.js +0 -6
  24. package/assets/assets/TrafficSourceDetailPage-BvtTA6rs.js +0 -1
@@ -1 +1 @@
1
- import{c as d,j as a,bC as S,by as l,bD as v,aj as y,l as t,bE as m,bz as i,bF as T,bG as h,bH as p,bI as b}from"./index-DTCZ93Ne.js";import{u as s,r as C,n as c,o as u}from"./vendor-tanstack-Dq7p98wZ.js";const g=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],F=d("refresh-cw",g);function M(e){switch(e){case i.connected:return"positive";case i.paused:return"caution";case i.error:return"negative";case i.archived:return"neutral"}}function w(e){const r={};return e.kind&&e.kind!=="all"&&(r.kind=e.kind),e.sourceId&&(r.sourceId=e.sourceId),e.sinceMinutes!==void 0&&(r.since=new Date(Date.now()-e.sinceMinutes*6e4).toISOString()),e.limit!==void 0&&(r.limit=String(e.limit)),r}function o(e){e.invalidateQueries({predicate:r=>{const n=r.queryKey[0];return typeof n?._id=="string"&&n._id.startsWith("getApiV1ProjectsByNameTraffic")}})}function P(e){return s({...S({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function k(e){return s({...b({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function E(e,r){return s({...l({client:t,path:{name:e??"",id:r??""}}),enabled:!!(e&&r),staleTime:a})}function V(e,r){const n=C.useMemo(()=>w(r),[r.kind,r.sourceId,r.sinceMinutes,r.limit]);return s({...v({client:t,path:{name:e??""},query:n}),enabled:!!e,staleTime:a})}function A(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Cloud Run source");return p(e,n)},onSuccess:()=>{e&&o(r)}})}function I(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a WordPress source");return T(e,n)},onSuccess:()=>{e&&o(r)}})}function Q(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Vercel source");return h(e,n)},onSuccess:()=>{e&&o(r)}})}function R(e,r){const n=c();return u({mutationFn:f=>{if(!e||!r)throw new Error("Project and sourceId are required to sync");return m(e,r,f??void 0)},onSuccess:()=>{e&&(o(n),n.invalidateQueries({queryKey:y({client:t})}))}})}export{F as R,I as a,Q as b,A as c,P as d,E as e,V as f,R as g,M as t,k as u};
1
+ import{c as d,j as a,bC as S,by as l,bD as v,aj as y,l as t,bE as m,bz as i,bF as T,bG as h,bH as p,bI as b}from"./index-BStwmAg6.js";import{u as s,r as C,n as c,o as u}from"./vendor-tanstack-Dq7p98wZ.js";const g=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],F=d("refresh-cw",g);function M(e){switch(e){case i.connected:return"positive";case i.paused:return"caution";case i.error:return"negative";case i.archived:return"neutral"}}function w(e){const r={};return e.kind&&e.kind!=="all"&&(r.kind=e.kind),e.sourceId&&(r.sourceId=e.sourceId),e.sinceMinutes!==void 0&&(r.since=new Date(Date.now()-e.sinceMinutes*6e4).toISOString()),e.limit!==void 0&&(r.limit=String(e.limit)),r}function o(e){e.invalidateQueries({predicate:r=>{const n=r.queryKey[0];return typeof n?._id=="string"&&n._id.startsWith("getApiV1ProjectsByNameTraffic")}})}function P(e){return s({...S({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function k(e){return s({...b({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function E(e,r){return s({...l({client:t,path:{name:e??"",id:r??""}}),enabled:!!(e&&r),staleTime:a})}function V(e,r){const n=C.useMemo(()=>w(r),[r.kind,r.sourceId,r.sinceMinutes,r.limit]);return s({...v({client:t,path:{name:e??""},query:n}),enabled:!!e,staleTime:a})}function A(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Cloud Run source");return p(e,n)},onSuccess:()=>{e&&o(r)}})}function I(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a WordPress source");return T(e,n)},onSuccess:()=>{e&&o(r)}})}function Q(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Vercel source");return h(e,n)},onSuccess:()=>{e&&o(r)}})}function R(e,r){const n=c();return u({mutationFn:f=>{if(!e||!r)throw new Error("Project and sourceId are required to sync");return m(e,r,f??void 0)},onSuccess:()=>{e&&(o(n),n.invalidateQueries({queryKey:y({client:t})}))}})}export{F as R,I as a,Q as b,A as c,P as d,E as e,V as f,R as g,M as t,k as u};
@@ -1 +1 @@
1
- import{c}from"./index-DTCZ93Ne.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
1
+ import{c}from"./index-BStwmAg6.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
package/assets/index.html CHANGED
@@ -12,12 +12,12 @@
12
12
  <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
13
13
  <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
14
14
  <title>Canonry</title>
15
- <script type="module" crossorigin src="./assets/index-DTCZ93Ne.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-BStwmAg6.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
17
17
  <link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/vendor-recharts-DWvKDyBF.js">
19
19
  <link rel="modulepreload" crossorigin href="./assets/vendor-markdown-DK7fbRNb.js">
20
- <link rel="stylesheet" crossorigin href="./assets/index-DeGyEwik.css">
20
+ <link rel="stylesheet" crossorigin href="./assets/index-Bm3JQsW0.css">
21
21
  </head>
22
22
  <body>
23
23
  <div id="root"></div>
@@ -22,7 +22,7 @@ import {
22
22
  trafficConnectVercelRequestSchema,
23
23
  trafficConnectWordpressRequestSchema,
24
24
  trafficEventKindSchema
25
- } from "./chunk-FYGBW3SM.js";
25
+ } from "./chunk-VZPDBHBW.js";
26
26
 
27
27
  // src/config.ts
28
28
  import fs from "fs";
@@ -10,7 +10,7 @@ import {
10
10
  categoryLabel,
11
11
  determineAnswerMentioned,
12
12
  normalizeProjectDomain
13
- } from "./chunk-FYGBW3SM.js";
13
+ } from "./chunk-VZPDBHBW.js";
14
14
 
15
15
  // src/intelligence-service.ts
16
16
  import { eq, desc, asc, and, ne, or, inArray } from "drizzle-orm";
@@ -27,6 +27,7 @@ __export(schema_exports, {
27
27
  agentMemory: () => agentMemory,
28
28
  agentSessions: () => agentSessions,
29
29
  aiReferralEventsHourly: () => aiReferralEventsHourly,
30
+ aiUserFetchEventsHourly: () => aiUserFetchEventsHourly,
30
31
  apiKeys: () => apiKeys,
31
32
  auditLog: () => auditLog,
32
33
  backlinkDomains: () => backlinkDomains,
@@ -643,6 +644,34 @@ var crawlerEventsHourly = sqliteTable("crawler_events_hourly", {
643
644
  index("idx_crawler_hourly_project_ts").on(table.projectId, table.tsHour),
644
645
  index("idx_crawler_hourly_path").on(table.projectId, table.pathNormalized)
645
646
  ]);
647
+ var aiUserFetchEventsHourly = sqliteTable("ai_user_fetch_events_hourly", {
648
+ projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
649
+ sourceId: text("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
650
+ tsHour: text("ts_hour").notNull(),
651
+ botId: text("bot_id").notNull(),
652
+ operator: text("operator").notNull(),
653
+ verificationStatus: text("verification_status").notNull(),
654
+ pathNormalized: text("path_normalized").notNull(),
655
+ status: integer("status").notNull(),
656
+ hits: integer("hits").notNull().default(0),
657
+ sampledUserAgent: text("sampled_user_agent"),
658
+ createdAt: text("created_at").notNull(),
659
+ updatedAt: text("updated_at").notNull()
660
+ }, (table) => [
661
+ primaryKey({
662
+ columns: [
663
+ table.projectId,
664
+ table.sourceId,
665
+ table.tsHour,
666
+ table.botId,
667
+ table.verificationStatus,
668
+ table.pathNormalized,
669
+ table.status
670
+ ]
671
+ }),
672
+ index("idx_ai_user_fetch_hourly_project_ts").on(table.projectId, table.tsHour),
673
+ index("idx_ai_user_fetch_hourly_path").on(table.projectId, table.pathNormalized)
674
+ ]);
646
675
  var aiReferralEventsHourly = sqliteTable("ai_referral_events_hourly", {
647
676
  projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
648
677
  sourceId: text("source_id").notNull().references(() => trafficSources.id, { onDelete: "cascade" }),
@@ -2056,6 +2085,78 @@ var MIGRATION_VERSIONS = [
2056
2085
  `ALTER TABLE audit_log ADD COLUMN user_agent TEXT`,
2057
2086
  `ALTER TABLE audit_log ADD COLUMN actor_session TEXT`
2058
2087
  ]
2088
+ },
2089
+ {
2090
+ version: 64,
2091
+ name: "ai-user-fetch-events-hourly",
2092
+ // Splits per-user fetches (ChatGPT-User, Perplexity-User) out of
2093
+ // crawler_events_hourly so the dashboard / API can distinguish bulk
2094
+ // machine crawl from human-in-the-loop fetch. Bot IDs are pinned to the
2095
+ // two `purpose: 'user-agent'` rules that existed before this change —
2096
+ // future user-fetch UAs land in the new table directly via the
2097
+ // refactored classifier and never need a backfill.
2098
+ //
2099
+ // Statements are idempotent: CREATE/INDEX are IF NOT EXISTS; the
2100
+ // INSERT … SELECT uses ON CONFLICT DO NOTHING (composite PK rows
2101
+ // already moved skip silently); the DELETE keys on `bot_id`, so a
2102
+ // second run is a no-op after the first DELETE drains the source.
2103
+ statements: [
2104
+ `CREATE TABLE IF NOT EXISTS ai_user_fetch_events_hourly (
2105
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
2106
+ source_id TEXT NOT NULL REFERENCES traffic_sources(id) ON DELETE CASCADE,
2107
+ ts_hour TEXT NOT NULL,
2108
+ bot_id TEXT NOT NULL,
2109
+ operator TEXT NOT NULL,
2110
+ verification_status TEXT NOT NULL,
2111
+ path_normalized TEXT NOT NULL,
2112
+ status INTEGER NOT NULL,
2113
+ hits INTEGER NOT NULL DEFAULT 0,
2114
+ sampled_user_agent TEXT,
2115
+ created_at TEXT NOT NULL,
2116
+ updated_at TEXT NOT NULL,
2117
+ PRIMARY KEY (project_id, source_id, ts_hour, bot_id, verification_status, path_normalized, status)
2118
+ )`,
2119
+ `CREATE INDEX IF NOT EXISTS idx_ai_user_fetch_hourly_project_ts ON ai_user_fetch_events_hourly(project_id, ts_hour)`,
2120
+ `CREATE INDEX IF NOT EXISTS idx_ai_user_fetch_hourly_path ON ai_user_fetch_events_hourly(project_id, path_normalized)`,
2121
+ `INSERT INTO ai_user_fetch_events_hourly
2122
+ (project_id, source_id, ts_hour, bot_id, operator, verification_status, path_normalized, status, hits, sampled_user_agent, created_at, updated_at)
2123
+ SELECT project_id, source_id, ts_hour, bot_id, operator, verification_status, path_normalized, status, hits, sampled_user_agent, created_at, updated_at
2124
+ FROM crawler_events_hourly
2125
+ WHERE bot_id IN ('openai-chatgpt-user', 'perplexity-user')
2126
+ ON CONFLICT DO NOTHING`,
2127
+ `DELETE FROM crawler_events_hourly WHERE bot_id IN ('openai-chatgpt-user', 'perplexity-user')`
2128
+ ]
2129
+ },
2130
+ {
2131
+ version: 65,
2132
+ name: "split-mistral-ai-rule",
2133
+ // The pre-existing `mistral-ai` rule matched both `MistralAI-User/*`
2134
+ // (per-user fetch) and `MistralBot/*` (bulk crawl) under one id, so
2135
+ // every historical row landed in crawler_events_hourly with
2136
+ // bot_id='mistral-ai'. The rule is now split into `mistral-ai-user`
2137
+ // (purpose: 'user-agent') and `mistral-bot` (purpose: 'crawl'); this
2138
+ // migration best-effort routes the legacy rows using the bucket's
2139
+ // representative sampled_user_agent.
2140
+ //
2141
+ // Mixed-UA buckets (where a single (project, source, hour, path,
2142
+ // status) accumulated both UAs under the old shared id) are routed
2143
+ // by whichever UA happened to be sampled — the bucket-key granularity
2144
+ // doesn't preserve per-event UAs, so any heuristic has the same
2145
+ // limitation. Going forward the split rules write to disjoint tables.
2146
+ //
2147
+ // Idempotent: the INSERT…SELECT uses ON CONFLICT DO NOTHING; the
2148
+ // UPDATE and DELETE both filter on bot_id='mistral-ai', so a second
2149
+ // run finds no rows after the first apply.
2150
+ statements: [
2151
+ `INSERT INTO ai_user_fetch_events_hourly
2152
+ (project_id, source_id, ts_hour, bot_id, operator, verification_status, path_normalized, status, hits, sampled_user_agent, created_at, updated_at)
2153
+ SELECT project_id, source_id, ts_hour, 'mistral-ai-user', operator, verification_status, path_normalized, status, hits, sampled_user_agent, created_at, updated_at
2154
+ FROM crawler_events_hourly
2155
+ WHERE bot_id = 'mistral-ai' AND sampled_user_agent LIKE '%MistralAI-User%'
2156
+ ON CONFLICT DO NOTHING`,
2157
+ `DELETE FROM crawler_events_hourly WHERE bot_id = 'mistral-ai' AND sampled_user_agent LIKE '%MistralAI-User%'`,
2158
+ `UPDATE crawler_events_hourly SET bot_id = 'mistral-bot' WHERE bot_id = 'mistral-ai'`
2159
+ ]
2059
2160
  }
2060
2161
  ];
2061
2162
  function isDuplicateColumnError(err) {
@@ -4436,6 +4537,7 @@ export {
4436
4537
  agentMemory,
4437
4538
  trafficSources,
4438
4539
  crawlerEventsHourly,
4540
+ aiUserFetchEventsHourly,
4439
4541
  aiReferralEventsHourly,
4440
4542
  rawEventSamples,
4441
4543
  discoverySessions,