@ainyc/canonry 4.51.0 → 4.51.2

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.
@@ -0,0 +1 @@
1
+ import{c as d,j as a,bK as S,bG as l,bL as v,aj as m,l as t,bM as y,bH as i,bN as T,bO as h,bP as p,bQ as b}from"./index-VMFHNbas.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"}]],P=d("refresh-cw",g);function B(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 k(e){return s({...S({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function F(e){return s({...b({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function V(e,r){return s({...l({client:t,path:{name:e??"",id:r??""}}),enabled:!!(e&&r),staleTime:a})}function A(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 E(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 Q(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 I(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 N(e,r){const n=c();return u({mutationFn:f=>{if(!e||!r)throw new Error("Project and sourceId are required to sync");return y(e,r,f??void 0)},onSuccess:()=>{e&&(o(n),n.invalidateQueries({queryKey:m({client:t})}))}})}export{P as R,Q as a,I as b,E as c,k as d,V as e,A as f,N as g,B as t,F as u};
@@ -1 +1 @@
1
- import{c}from"./index-DKBPD33e.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-VMFHNbas.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,7 +12,7 @@
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-DKBPD33e.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-VMFHNbas.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">
@@ -380,6 +380,9 @@ function missingDependency(message, details) {
380
380
  function internalError(message, details) {
381
381
  return new AppError("INTERNAL_ERROR", message, 500, details);
382
382
  }
383
+ function runtimeStateMissing(message, details) {
384
+ return new AppError("RUNTIME_STATE_MISSING", message, 503, details);
385
+ }
383
386
 
384
387
  // ../contracts/src/project.ts
385
388
  var configSourceSchema = z4.enum(["cli", "api", "config-file"]);
@@ -3584,6 +3587,7 @@ export {
3584
3587
  agentBusy,
3585
3588
  missingDependency,
3586
3589
  internalError,
3590
+ runtimeStateMissing,
3587
3591
  findDuplicateLocationLabels,
3588
3592
  hasLocationLabel,
3589
3593
  resolveLocations,
@@ -22,7 +22,7 @@ import {
22
22
  trafficConnectVercelRequestSchema,
23
23
  trafficConnectWordpressRequestSchema,
24
24
  trafficEventKindSchema
25
- } from "./chunk-2ARCCG5E.js";
25
+ } from "./chunk-FYGBW3SM.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-2ARCCG5E.js";
13
+ } from "./chunk-FYGBW3SM.js";
14
14
 
15
15
  // src/intelligence-service.ts
16
16
  import { eq, desc, asc, and, ne, or, inArray } from "drizzle-orm";
@@ -164,11 +164,26 @@ var auditLog = sqliteTable("audit_log", {
164
164
  // reader could see it (the deletion would erase the only evidence it
165
165
  // happened). Detached rows surface in audit queries with project_id=NULL.
166
166
  projectId: text("project_id").references(() => projects.id, { onDelete: "set null" }),
167
+ // High-level identity of the caller: 'api' for HTTP requests, 'scheduler'
168
+ // for cron-triggered work, 'cli' / 'agent' / 'mcp' for direct DB writes
169
+ // (where applicable). Coarse on purpose — narrower attribution lives in
170
+ // `userAgent` and `actorSession`.
167
171
  actor: text("actor").notNull(),
168
172
  action: text("action").notNull(),
169
173
  entityType: text("entity_type").notNull(),
170
174
  entityId: text("entity_id"),
171
175
  diff: text("diff"),
176
+ // User-Agent header from the originating HTTP request, when available.
177
+ // The narrowest reliable signal for "which client did this" — distinguishes
178
+ // CLI (`canonry-cli/X.Y.Z`), dashboard (browser UA), MCP adapter, and
179
+ // external scripts. NULL for non-HTTP writes (scheduler, run-coordinator,
180
+ // direct CLI commands that bypass the API).
181
+ userAgent: text("user_agent"),
182
+ // Optional caller-supplied trace key for cross-request correlation —
183
+ // a session ID, prompt ID, batch ID, etc. The Aero agent populates this
184
+ // with its session id so post-mortems can group a related sequence of
185
+ // mutations. NULL when the caller didn't provide one.
186
+ actorSession: text("actor_session"),
172
187
  createdAt: text("created_at").notNull()
173
188
  }, (table) => [
174
189
  index("idx_audit_log_project").on(table.projectId),
@@ -2023,6 +2038,24 @@ var MIGRATION_VERSIONS = [
2023
2038
  `CREATE UNIQUE INDEX IF NOT EXISTS idx_recommendation_explanations_unique ON recommendation_explanations(project_id, target_ref, prompt_version)`,
2024
2039
  `CREATE INDEX IF NOT EXISTS idx_recommendation_explanations_project ON recommendation_explanations(project_id)`
2025
2040
  ]
2041
+ },
2042
+ {
2043
+ version: 63,
2044
+ name: "audit-log-attribution-columns",
2045
+ // Adds `user_agent` and `actor_session` to `audit_log` so post-mortems
2046
+ // can attribute destructive events (like the 2026-05-15 azcoatings
2047
+ // queries.replaced incident — see PR #593) to a specific caller.
2048
+ // Without these columns, every mutation rides as `actor='api'` with no
2049
+ // narrower identity, so it's impossible to tell whether a destructive
2050
+ // event came from CLI, dashboard, MCP, an agent, or an external script.
2051
+ //
2052
+ // Both columns nullable — the audit log accepts writes from sources
2053
+ // that don't have an HTTP request context (scheduler, run-coordinator,
2054
+ // direct DB writes from CLI commands).
2055
+ statements: [
2056
+ `ALTER TABLE audit_log ADD COLUMN user_agent TEXT`,
2057
+ `ALTER TABLE audit_log ADD COLUMN actor_session TEXT`
2058
+ ]
2026
2059
  }
2027
2060
  ];
2028
2061
  function isDuplicateColumnError(err) {