@canonry/canonry 7.18.0 → 7.19.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/assets/assets/AuditHistoryPanel-DEEWm-4t.js +1 -0
- package/assets/assets/{BacklinksPage-BBqbRSeG.js → BacklinksPage-F5QBgXbF.js} +1 -1
- package/assets/assets/{HistoryPage-D8nQ8E8_.js → HistoryPage-CNp42sUO.js} +1 -1
- package/assets/assets/MeasurementPropertyPage-XpI9hVMb.js +4 -0
- package/assets/assets/ProjectPage-B_V4QpyI.js +8 -0
- package/assets/assets/{RunsPage-D0qkTwas.js → RunsPage-PTHloZl3.js} +1 -1
- package/assets/assets/{SettingsPage-DaqR1wKC.js → SettingsPage-C-aDo2zf.js} +1 -1
- package/assets/assets/{SiteHealthSection-dGXxZ8IR.js → SiteHealthSection-DvoT8IuX.js} +3 -3
- package/assets/assets/{TrafficPage-DodOmnVv.js → TrafficPage-DahJoMKF.js} +3 -3
- package/assets/assets/{TrafficSourceDetailPage-C7b-BcKF.js → TrafficSourceDetailPage-BGlHXOlk.js} +1 -1
- package/assets/assets/{extract-error-message-BYvzTsML.js → extract-error-message-CP_fyJLM.js} +1 -1
- package/assets/assets/{index-BVzozur0.js → index-C5V8xlr0.js} +36 -36
- package/assets/assets/{react-sigma_core.esm.min-DXcq1O0r.js → react-sigma_core.esm.min-DUS8srfg.js} +1 -1
- package/assets/assets/v2-overview-adapter-ycJ1guZb.js +1 -0
- package/assets/index.html +1 -1
- package/dist/{chunk-JMC7CEJB.js → chunk-35IIFDIT.js} +2 -2
- package/dist/{chunk-U7D7LNVJ.js → chunk-A75L7CUV.js} +2 -2
- package/dist/{chunk-X2S7D3MN.js → chunk-CYHUZ2JQ.js} +120 -7
- package/dist/{chunk-5M2RY5WU.js → chunk-OMP5OLBK.js} +6 -6
- package/dist/{chunk-JUOFNJLV.js → chunk-PBTTPZZE.js} +3 -3
- package/dist/{chunk-COQOQYRZ.js → chunk-UUI4HOEL.js} +100 -24
- package/dist/{chunk-EAAM47H6.js → chunk-VSTKTQPS.js} +3 -3
- package/dist/cli.js +25 -15
- package/dist/{demo-server-XWRIXME5.js → demo-server-K5G54GOE.js} +4 -4
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-332S7D7Y.js → intelligence-service-LV2TQMMR.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +12 -12
- package/assets/assets/AuditHistoryPanel-CgKpjgpq.js +0 -1
- package/assets/assets/MeasurementPropertyPage-CQ8lLoeA.js +0 -1
- package/assets/assets/ProjectPage-CP4fvluh.js +0 -8
- package/assets/assets/v2-overview-adapter-1MHnrdnr.js +0 -1
|
@@ -556,6 +556,8 @@ import {
|
|
|
556
556
|
measurementDraftUpsertTargetRequestSchema,
|
|
557
557
|
measurementIdempotencyKeyConflict,
|
|
558
558
|
measurementIdempotencyKeyRequired,
|
|
559
|
+
measurementNameKey,
|
|
560
|
+
measurementNameWords,
|
|
559
561
|
measurementOverviewQuerySchema,
|
|
560
562
|
measurementOverviewResponseSchema,
|
|
561
563
|
measurementOverviewSortSchema,
|
|
@@ -599,6 +601,8 @@ import {
|
|
|
599
601
|
measurementSegmentRetirementResponseSchema,
|
|
600
602
|
measurementSetupResponseSchema,
|
|
601
603
|
measurementStableKeySchema,
|
|
604
|
+
measurementTargetNameIssueMessage,
|
|
605
|
+
measurementTargetNameIssues,
|
|
602
606
|
measurementV2UsageEdgeKey,
|
|
603
607
|
mentionStateFromAnswerMentioned,
|
|
604
608
|
missingDependency,
|
|
@@ -662,6 +666,7 @@ import {
|
|
|
662
666
|
providerError,
|
|
663
667
|
providerSummaryEntryDtoSchema,
|
|
664
668
|
providersFailing,
|
|
669
|
+
qualifiedNameIncludesName,
|
|
665
670
|
queryDtoSchema,
|
|
666
671
|
queryGenerateRequestSchema,
|
|
667
672
|
queryGenerateResponseSchema,
|
|
@@ -848,7 +853,7 @@ import {
|
|
|
848
853
|
wordpressSchemaDeployResultDtoSchema,
|
|
849
854
|
wordpressSchemaStatusResultDtoSchema,
|
|
850
855
|
wordpressStatusDtoSchema
|
|
851
|
-
} from "./chunk-
|
|
856
|
+
} from "./chunk-CYHUZ2JQ.js";
|
|
852
857
|
|
|
853
858
|
// src/intelligence-service.ts
|
|
854
859
|
import { eq as eq89, desc as desc41, asc as asc18, and as and75, ne as ne16, or as or22, inArray as inArray36, gte as gte24, lte as lte20, isNull as isNull17, sql as sql32, exists as exists2 } from "drizzle-orm";
|
|
@@ -16090,11 +16095,9 @@ function normalizeMeasurementLocation(value) {
|
|
|
16090
16095
|
if (value === null) return null;
|
|
16091
16096
|
return normalizeIdentityText(value) || null;
|
|
16092
16097
|
}
|
|
16093
|
-
|
|
16094
|
-
return value.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
16095
|
-
}
|
|
16098
|
+
var words = measurementNameWords;
|
|
16096
16099
|
function measurementMentionAliasKey(value) {
|
|
16097
|
-
return
|
|
16100
|
+
return measurementNameKey(value);
|
|
16098
16101
|
}
|
|
16099
16102
|
function aliasMatchesAt(textWords, aliasWords, start) {
|
|
16100
16103
|
if (aliasWords.length === 0 || start + aliasWords.length > textWords.length) return false;
|
|
@@ -23305,11 +23308,8 @@ function compileMeasurementDraft(authoring, context) {
|
|
|
23305
23308
|
aliasClaims.set(identity, target.stableKey);
|
|
23306
23309
|
});
|
|
23307
23310
|
const aliases = sortedUnique(target.aliases);
|
|
23308
|
-
const aliasKeys = aliases.map(measurementMentionAliasKey).filter(Boolean);
|
|
23309
23311
|
target.identityAliases?.forEach((identityAlias, index2) => {
|
|
23310
|
-
|
|
23311
|
-
const qualifiesAlias = aliasKeys.some((aliasKey) => identityKey !== aliasKey && `\0${identityKey}\0`.includes(`\0${aliasKey}\0`));
|
|
23312
|
-
if (!qualifiesAlias) {
|
|
23312
|
+
if (!qualifiedNameIncludesName(identityAlias, aliases)) {
|
|
23313
23313
|
sink.fail("target-identity-alias-unqualified", "An identity phrase must include a Property alias and additional identifying context.", ["targets", targetIndex, "identityAliases", index2]);
|
|
23314
23314
|
}
|
|
23315
23315
|
});
|
|
@@ -23827,13 +23827,18 @@ function withRequestedContext(assignment, contextOverride) {
|
|
|
23827
23827
|
const { executionContexts: _frozenContexts, ...withoutFrozenContexts } = assignment;
|
|
23828
23828
|
return { ...withoutFrozenContexts, contextOverride };
|
|
23829
23829
|
}
|
|
23830
|
-
function upsertTarget(authoring, body) {
|
|
23830
|
+
function upsertTarget(authoring, body, context) {
|
|
23831
23831
|
const { target } = parseBody2(measurementDraftUpsertTargetRequestSchema, body, "upsert-target");
|
|
23832
23832
|
const index2 = authoring.targets.findIndex((candidate) => candidate.stableKey === target.stableKey);
|
|
23833
23833
|
const targets = [...authoring.targets];
|
|
23834
23834
|
if (index2 === -1) targets.push(target);
|
|
23835
23835
|
else targets[index2] = target;
|
|
23836
|
-
|
|
23836
|
+
const warnings = measurementTargetNameIssues({
|
|
23837
|
+
aliases: target.aliases,
|
|
23838
|
+
...target.identityAliases === void 0 ? {} : { identityAliases: target.identityAliases },
|
|
23839
|
+
brandNames: context.brandNames
|
|
23840
|
+
}).map((issue) => warn(issue.code, measurementTargetNameIssueMessage(issue), ["target", issue.field, issue.index]));
|
|
23841
|
+
return { authoring: { ...authoring, targets }, warnings };
|
|
23837
23842
|
}
|
|
23838
23843
|
function renameTarget(authoring, body) {
|
|
23839
23844
|
const { targetKey, label } = parseBody2(measurementDraftRenameTargetRequestSchema, body, "rename-target");
|
|
@@ -24156,7 +24161,7 @@ function applyDraftAction(action, authoring, body, context) {
|
|
|
24156
24161
|
const result = (() => {
|
|
24157
24162
|
switch (action) {
|
|
24158
24163
|
case "upsert-target":
|
|
24159
|
-
return upsertTarget(authoring, body);
|
|
24164
|
+
return upsertTarget(authoring, body, context);
|
|
24160
24165
|
case "rename-target":
|
|
24161
24166
|
return renameTarget(authoring, body);
|
|
24162
24167
|
case "merge-targets":
|
|
@@ -26635,6 +26640,9 @@ function capSources(row) {
|
|
|
26635
26640
|
function answerRowKey(row) {
|
|
26636
26641
|
return [row.expectedSlotId, row.usageEdgeId].join("\0");
|
|
26637
26642
|
}
|
|
26643
|
+
function otherQueryRowKey(row) {
|
|
26644
|
+
return [row.expectedSlotId, row.queryClass].join("\0");
|
|
26645
|
+
}
|
|
26638
26646
|
function encodeCursor(cursor) {
|
|
26639
26647
|
const { shape, ...rest } = cursor;
|
|
26640
26648
|
return Buffer.from(
|
|
@@ -26653,7 +26661,7 @@ function parseCursor2(value) {
|
|
|
26653
26661
|
if (typeof candidate !== "string" || candidate.length === 0) return null;
|
|
26654
26662
|
}
|
|
26655
26663
|
const shape = cursor.shape === void 0 ? MEASUREMENT_EVIDENCE_DEFAULT_SHAPE : cursor.shape;
|
|
26656
|
-
if (shape !== MeasurementEvidenceShapes.sources && shape !== MeasurementEvidenceShapes.answers) return null;
|
|
26664
|
+
if (shape !== MeasurementEvidenceShapes.sources && shape !== MeasurementEvidenceShapes.answers && shape !== MeasurementEvidenceShapes["other-queries"]) return null;
|
|
26657
26665
|
return {
|
|
26658
26666
|
v: 1,
|
|
26659
26667
|
key: cursor.key,
|
|
@@ -26686,12 +26694,57 @@ function propertyEvidenceRows(db, plan, active, run, query, queryClass) {
|
|
|
26686
26694
|
const location = query.location === void 0 ? void 0 : normalizeMeasurementLocation(query.location);
|
|
26687
26695
|
const owned = (row) => ownEdgeIds.has(row.usageEdgeId) && (provider === void 0 || row.provider === provider) && (location === void 0 || normalizeMeasurementLocation(row.location) === location);
|
|
26688
26696
|
const built = buildMeasurementEvidence(input);
|
|
26697
|
+
const narrowed = (row) => (provider === void 0 || row.provider === provider) && (location === void 0 || normalizeMeasurementLocation(row.location) === location);
|
|
26689
26698
|
return {
|
|
26690
26699
|
sources: built.evidence.filter(owned),
|
|
26691
26700
|
answers: built.answers.filter(owned),
|
|
26701
|
+
otherQueries: otherQueryCitations(input.usageEdges, built.answers, query.targetKey, queryClass).filter(narrowed),
|
|
26692
26702
|
evidenceFingerprint: snapshotEvidenceFingerprint(snapshots)
|
|
26693
26703
|
};
|
|
26694
26704
|
}
|
|
26705
|
+
function otherQueryCitations(usageEdges, answers, targetKey, queryClass) {
|
|
26706
|
+
const edgesByExecution = /* @__PURE__ */ new Map();
|
|
26707
|
+
for (const edge of usageEdges) {
|
|
26708
|
+
if (edge.type !== "target") continue;
|
|
26709
|
+
const edges = edgesByExecution.get(edge.executionId) ?? [];
|
|
26710
|
+
edges.push({ targetId: edge.targetId, queryClass: edge.queryClass ?? null });
|
|
26711
|
+
edgesByExecution.set(edge.executionId, edges);
|
|
26712
|
+
}
|
|
26713
|
+
const rows = [];
|
|
26714
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
26715
|
+
for (const answer of answers) {
|
|
26716
|
+
if (seen2.has(answer.expectedSlotId)) continue;
|
|
26717
|
+
seen2.add(answer.expectedSlotId);
|
|
26718
|
+
const edges = edgesByExecution.get(answer.executionId) ?? [];
|
|
26719
|
+
if (edges.some((edge) => edge.targetId === targetKey)) continue;
|
|
26720
|
+
const own = answer.sources.filter((source) => source.classification === "sibling" && source.matchedTargetIds.length === 1 && source.matchedTargetIds[0] === targetKey);
|
|
26721
|
+
if (own.length === 0) continue;
|
|
26722
|
+
const sources = own.map((source) => ({
|
|
26723
|
+
sourceUrl: source.sourceUrl,
|
|
26724
|
+
normalizedUrl: source.normalizedUrl,
|
|
26725
|
+
matchedUrlIds: source.matchedUrlIds
|
|
26726
|
+
}));
|
|
26727
|
+
const classes = sortedUnique(edges.flatMap((edge) => edge.queryClass === null ? [] : [edge.queryClass]));
|
|
26728
|
+
for (const edgeClass of classes) {
|
|
26729
|
+
if (queryClass !== "all" && edgeClass !== queryClass) continue;
|
|
26730
|
+
rows.push({
|
|
26731
|
+
observationId: answer.observationId,
|
|
26732
|
+
expectedSlotId: answer.expectedSlotId,
|
|
26733
|
+
executionId: answer.executionId,
|
|
26734
|
+
provider: answer.provider,
|
|
26735
|
+
queryText: answer.queryText,
|
|
26736
|
+
location: answer.location,
|
|
26737
|
+
queryClass: edgeClass,
|
|
26738
|
+
assignedTargetKeys: sortedUnique(edges.filter((edge) => edge.queryClass === edgeClass).map((edge) => edge.targetId)),
|
|
26739
|
+
sources: sources.slice(0, MAX_SOURCES_PER_ANSWER),
|
|
26740
|
+
sourceCount: sources.length,
|
|
26741
|
+
sourcesTruncated: sources.length > MAX_SOURCES_PER_ANSWER,
|
|
26742
|
+
evidenceComplete: answer.evidenceComplete
|
|
26743
|
+
});
|
|
26744
|
+
}
|
|
26745
|
+
}
|
|
26746
|
+
return rows;
|
|
26747
|
+
}
|
|
26695
26748
|
function pageOf2(rows, keyOf, shape, query, displayedRunId, planVersionId, evidenceFingerprint) {
|
|
26696
26749
|
const limit = query.limit ?? MEASUREMENT_PAGE_DEFAULT_LIMIT;
|
|
26697
26750
|
let offset = 0;
|
|
@@ -26766,10 +26819,10 @@ async function measurementPropertyEvidenceRoutes(app) {
|
|
|
26766
26819
|
// The page still arrives under the key the caller's shape names. An
|
|
26767
26820
|
// unmeasured Property has no rows in EITHER reading, and swapping the
|
|
26768
26821
|
// key here would read as "that shape is unavailable" instead.
|
|
26769
|
-
...shape === MeasurementEvidenceShapes.answers ? { answers: empty } : { evidence: empty }
|
|
26822
|
+
...shape === MeasurementEvidenceShapes.answers ? { answers: empty } : shape === MeasurementEvidenceShapes["other-queries"] ? { otherQueries: empty } : { evidence: empty }
|
|
26770
26823
|
});
|
|
26771
26824
|
}
|
|
26772
|
-
const { sources, answers, evidenceFingerprint } = propertyEvidenceRows(app.db, plan, active, displayed, query, queryClass);
|
|
26825
|
+
const { sources, answers, otherQueries, evidenceFingerprint } = propertyEvidenceRows(app.db, plan, active, displayed, query, queryClass);
|
|
26773
26826
|
const pageArgs = [shape, query, displayed.id, active.version.id, evidenceFingerprint];
|
|
26774
26827
|
return measurementPropertyEvidenceResponseSchema.parse({
|
|
26775
26828
|
property,
|
|
@@ -26779,7 +26832,7 @@ async function measurementPropertyEvidenceRoutes(app) {
|
|
|
26779
26832
|
displayedRunId: displayed.id,
|
|
26780
26833
|
...displayed.finishedAt ? { completedAt: displayed.finishedAt } : {}
|
|
26781
26834
|
},
|
|
26782
|
-
...shape === MeasurementEvidenceShapes.answers ? { answers: pageOf2(answers.map(capSources), answerRowKey, ...pageArgs) } : { evidence: pageOf2(sources, sourceRowKey, ...pageArgs) }
|
|
26835
|
+
...shape === MeasurementEvidenceShapes.answers ? { answers: pageOf2(answers.map(capSources), answerRowKey, ...pageArgs) } : shape === MeasurementEvidenceShapes["other-queries"] ? { otherQueries: pageOf2(otherQueries, otherQueryRowKey, ...pageArgs) } : { evidence: pageOf2(sources, sourceRowKey, ...pageArgs) }
|
|
26783
26836
|
});
|
|
26784
26837
|
}
|
|
26785
26838
|
);
|
|
@@ -28761,11 +28814,17 @@ function targetPresence(candidates, targets, targetKey) {
|
|
|
28761
28814
|
const values = scoped.map((candidate) => targetValues(candidate, targets, targetKey));
|
|
28762
28815
|
const citations = scoped.map((candidate, index2) => candidate.observation?.citationComplete === false ? null : values[index2].citation);
|
|
28763
28816
|
const anyKnown = (signals) => signals.includes(true) ? true : signals.length === 0 || signals.includes(null) ? null : false;
|
|
28817
|
+
const mention = anyKnown(values.map((value) => value.mention));
|
|
28818
|
+
const citation = anyKnown(citations);
|
|
28764
28819
|
return {
|
|
28765
28820
|
targetKey,
|
|
28766
|
-
mention
|
|
28767
|
-
citation
|
|
28768
|
-
identityAmbiguous: values.some((value) => value.mentionUnavailableReason === "identity-ambiguous")
|
|
28821
|
+
mention,
|
|
28822
|
+
citation,
|
|
28823
|
+
identityAmbiguous: values.some((value) => value.mentionUnavailableReason === "identity-ambiguous"),
|
|
28824
|
+
// Every answer was saved, so an unknown citation can only come from an
|
|
28825
|
+
// answer whose source list was partly saved. With the mention measured,
|
|
28826
|
+
// that is the one reason this Property reads not measured.
|
|
28827
|
+
uncheckedOnly: mention !== null && citation === null && scoped.length > 0 && scoped.every((candidate) => candidate.observation !== null)
|
|
28769
28828
|
};
|
|
28770
28829
|
}
|
|
28771
28830
|
function outcomeCounts(rows) {
|
|
@@ -28785,6 +28844,19 @@ function outcomeCounts(rows) {
|
|
|
28785
28844
|
}
|
|
28786
28845
|
return counts2;
|
|
28787
28846
|
}
|
|
28847
|
+
function uncheckedSourceEvidence(rows) {
|
|
28848
|
+
const unchecked = rows.filter((candidate) => candidate.observation !== null && !candidate.observation.citationComplete);
|
|
28849
|
+
if (unchecked.length === 0) return void 0;
|
|
28850
|
+
const cited = unchecked.map((candidate) => {
|
|
28851
|
+
const edgeTargets = new Set(candidate.edges.map((edge) => edge.targetKey));
|
|
28852
|
+
return candidate.observation.citedTargetKeys.filter((key) => edgeTargets.has(key));
|
|
28853
|
+
});
|
|
28854
|
+
return {
|
|
28855
|
+
answers: unchecked.length,
|
|
28856
|
+
citedAnswers: cited.filter((keys) => keys.length > 0).length,
|
|
28857
|
+
citedTargetKeys: sortedUnique(cited.flat())
|
|
28858
|
+
};
|
|
28859
|
+
}
|
|
28788
28860
|
function coverageSummary(candidates, definition, targets = targetMap(definition)) {
|
|
28789
28861
|
const unique3 = new Map(candidates.map((candidate) => [candidateKey(candidate), candidate]));
|
|
28790
28862
|
const rows = [...unique3.values()];
|
|
@@ -28807,13 +28879,15 @@ function summary2(candidates, definition, populationTargetKeys = selectedTargetK
|
|
|
28807
28879
|
eligibleTargets.length,
|
|
28808
28880
|
eligibleTargets.some((row) => row.mention === null && row.identityAmbiguous) ? "identity-ambiguous" : "evidence-incomplete"
|
|
28809
28881
|
);
|
|
28882
|
+
const notMeasuredUnchecked = targetRows.filter((row) => row.uncheckedOnly).length;
|
|
28810
28883
|
return {
|
|
28811
28884
|
queryCount: base.queryCount,
|
|
28812
28885
|
answerCount: base.answerCount,
|
|
28813
28886
|
mentionCoverage: base.mentionCoverage,
|
|
28814
28887
|
citationCoverage: base.citationCoverage,
|
|
28815
28888
|
propertyReach,
|
|
28816
|
-
outcomes: outcomeCounts(targetRows)
|
|
28889
|
+
outcomes: outcomeCounts(targetRows),
|
|
28890
|
+
...notMeasuredUnchecked > 0 ? { notMeasuredUnchecked } : {}
|
|
28817
28891
|
};
|
|
28818
28892
|
}
|
|
28819
28893
|
function queryRows(candidates, definition, selection) {
|
|
@@ -28830,6 +28904,7 @@ function queryRows(candidates, definition, selection) {
|
|
|
28830
28904
|
return [...groups.values()].map((rows) => {
|
|
28831
28905
|
const first = rows[0];
|
|
28832
28906
|
const value = coverageSummary(rows, definition, targets);
|
|
28907
|
+
const uncheckedSources = uncheckedSourceEvidence(value.rows);
|
|
28833
28908
|
return {
|
|
28834
28909
|
sourceSnapshotIds: sortedUnique(rows.flatMap((row) => row.observation ? [row.observation.answerId] : [])),
|
|
28835
28910
|
queryKey: first.slot.queryKey,
|
|
@@ -28845,7 +28920,8 @@ function queryRows(candidates, definition, selection) {
|
|
|
28845
28920
|
})(),
|
|
28846
28921
|
answerCount: value.answerCount,
|
|
28847
28922
|
mentionCoverage: value.mentionCoverage,
|
|
28848
|
-
citationCoverage: value.citationCoverage
|
|
28923
|
+
citationCoverage: value.citationCoverage,
|
|
28924
|
+
...uncheckedSources === void 0 ? {} : { uncheckedSources }
|
|
28849
28925
|
};
|
|
28850
28926
|
}).sort((left, right) => (selection.scope === "property" && selection.marketKey === void 0 ? compareText((left.marketKeys ?? []).join("\0"), (right.marketKeys ?? []).join("\0")) : 0) || compareText(normalizeIdentityText(left.query), normalizeIdentityText(right.query)) || compareText(left.provider, right.provider) || compareText(left.model ?? "", right.model ?? "") || compareText(left.location ?? "", right.location ?? "") || compareText(left.queryKey, right.queryKey));
|
|
28851
28927
|
}
|
|
@@ -39284,8 +39360,8 @@ var measurementOverviewCursorParameter = {
|
|
|
39284
39360
|
var measurementPropertyEvidenceShapeParameter = {
|
|
39285
39361
|
name: "shape",
|
|
39286
39362
|
in: "query",
|
|
39287
|
-
description: "What one row is. sources (the default) returns one row per cited URL under evidence, which is what a caller written before this parameter existed reads. answers returns one row per measured answer under answers, with the cited URLs nested inside it, so the answers that cited nothing at all are present rather than missing. Exactly one of the
|
|
39288
|
-
schema: { type: "string", enum: ["sources", "answers"], default: "sources" }
|
|
39363
|
+
description: "What one row is. sources (the default) returns one row per cited URL under evidence, which is what a caller written before this parameter existed reads. answers returns one row per measured answer under answers, with the cited URLs nested inside it, so the answers that cited nothing at all are present rather than missing. other-queries returns, under otherQueries, one row per answer to a query NOT assigned to this Property that cited one of its own pages, per assignment class; those answers are outside its rates. Exactly one of the keys is returned; the others are absent, not empty.",
|
|
39364
|
+
schema: { type: "string", enum: ["sources", "answers", "other-queries"], default: "sources" }
|
|
39289
39365
|
};
|
|
39290
39366
|
var measurementPropertyEvidenceCursorParameter = {
|
|
39291
39367
|
name: "cursor",
|
|
@@ -39995,7 +40071,7 @@ var routeCatalog = [
|
|
|
39995
40071
|
method: "get",
|
|
39996
40072
|
path: "/api/v1/projects/{name}/measurement-property-evidence",
|
|
39997
40073
|
summary: "Page one Property's evidence",
|
|
39998
|
-
description: "Returns the evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a question class, provider, or location. shape chooses what a row is: sources (the default) is one row per cited URL, answers is one row per measured answer with its cited URLs nested inside. Prefer answers to explain a gap \u2014 an answer that mentioned the Property without linking it, or that named nobody, has no URL to hang a source row on and is invisible in the default shape. Run selection matches the overview: the most recent completed run pinned to the active revision unless runId names another. Use this rather than GET /measurement-report when you want one Property \u2014 the report reconstructs every group and Target for a revision and does not paginate. Not available for a schema v1 revision, which records no question class to scope by. An empty page under measurement.state = not_measured means the Property has not been measured, which is not the same statement as a measured Property with no evidence.",
|
|
40074
|
+
description: "Returns the evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a question class, provider, or location. shape chooses what a row is: sources (the default) is one row per cited URL, answers is one row per measured answer with its cited URLs nested inside, other-queries is one row per answer to a query not assigned to this Property that cited its pages (outside its rates). Prefer answers to explain a gap \u2014 an answer that mentioned the Property without linking it, or that named nobody, has no URL to hang a source row on and is invisible in the default shape. Run selection matches the overview: the most recent completed run pinned to the active revision unless runId names another. Use this rather than GET /measurement-report when you want one Property \u2014 the report reconstructs every group and Target for a revision and does not paginate. Not available for a schema v1 revision, which records no question class to scope by. An empty page under measurement.state = not_measured means the Property has not been measured, which is not the same statement as a measured Property with no evidence.",
|
|
39999
40075
|
tags: ["measurement-plans"],
|
|
40000
40076
|
parameters: [
|
|
40001
40077
|
nameParameter,
|
|
@@ -142,7 +142,7 @@ import {
|
|
|
142
142
|
trafficSeriesGranularitySchema,
|
|
143
143
|
visibilityCompareSelectionSchema,
|
|
144
144
|
visibilityReportRequestSchema
|
|
145
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-CYHUZ2JQ.js";
|
|
146
146
|
|
|
147
147
|
// src/cli-error.ts
|
|
148
148
|
function isMachineFormat(format) {
|
|
@@ -446,7 +446,7 @@ var measurementPropertyEvidenceInputSchema = measurementPropertyEvidenceQuerySch
|
|
|
446
446
|
targetKey: measurementPropertyEvidenceQuerySchema.shape.targetKey.describe("Property stable key. Required \u2014 this read is scoped to exactly one Property."),
|
|
447
447
|
queryClass: propertyQueryClassInputSchema,
|
|
448
448
|
shape: measurementPropertyEvidenceQuerySchema.shape.shape.describe(
|
|
449
|
-
"What one row is. Omit for sources (one row per cited URL). answers gives one row per measured answer with its cited URLs nested, including the answers that cited nothing."
|
|
449
|
+
"What one row is. Omit for sources (one row per cited URL). answers gives one row per measured answer with its cited URLs nested, including the answers that cited nothing. other-queries gives one row per answer to a query NOT assigned to this Property that cited one of its own pages; those answers are outside its rates."
|
|
450
450
|
)
|
|
451
451
|
}).strict();
|
|
452
452
|
var measurementPortfolioSummaryInputSchema = measurementPortfolioSummaryQuerySchema.extend({
|
|
@@ -2938,7 +2938,7 @@ var canonryMcpTools = [
|
|
|
2938
2938
|
defineTool({
|
|
2939
2939
|
name: "canonry_measurement_property_evidence",
|
|
2940
2940
|
title: "Page one Property's measurement evidence",
|
|
2941
|
-
description: "Return the stored evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a provider or location. Defaults to non-brand queries; pass queryClass branded or all to change it, and state the returned class. shape chooses what a row is: sources (the default) returns one row per cited URL under evidence; answers returns one row per measured answer under answers, with the cited URLs nested inside and both signals on the row (mentioned, cited). Use shape=answers to explain a GAP: an answer that mentioned the Property without linking it, or that named nobody at all, has no URL to hang a source row on and does not appear in the default shape, so counting source rows understates what was measured. mentioned is null, never false, when the answer text was never captured: that is a missing signal, not a measured no. Exactly one of evidence or
|
|
2941
|
+
description: "Return the stored evidence rows for exactly one Property out of one revision-pinned run, optionally narrowed to a provider or location. Defaults to non-brand queries; pass queryClass branded or all to change it, and state the returned class. shape chooses what a row is: sources (the default) returns one row per cited URL under evidence; answers returns one row per measured answer under answers, with the cited URLs nested inside and both signals on the row (mentioned, cited). Use shape=answers to explain a GAP: an answer that mentioned the Property without linking it, or that named nobody at all, has no URL to hang a source row on and does not appear in the default shape, so counting source rows understates what was measured. shape=other-queries returns, under otherQueries, answers to queries assigned only to other Properties that still cited this Property's pages, one row per answer and assignment class with assignedTargetKeys; never add them to its rates. mentioned is null, never false, when the answer text was never captured: that is a missing signal, not a measured no. Exactly one of evidence, answers or otherQueries is returned and the others are absent rather than empty. A cursor is bound to the shape that issued it and is refused on the other. Prefer this over canonry_measurement_report when you want one Property: the report reconstructs every group and every Target for a revision and does not paginate. Run selection matches canonry_measurement_overview: the most recent completed run pinned to the active revision unless runId names another, and a run pinned to a different revision is refused rather than joined. The cursor also pins the active revision, displayed run, evidence snapshot, and filters; reuse it unchanged. Not available for a schema v1 revision, which records no question class to scope by. It never starts provider work; page size is at most 100. An empty page under measurement.state = not_measured means the Property has not been measured at all, which is NOT a measured result of zero.",
|
|
2942
2942
|
access: "read",
|
|
2943
2943
|
tier: "setup",
|
|
2944
2944
|
inputSchema: measurementPropertyEvidenceInputSchema,
|
package/dist/cli.js
CHANGED
|
@@ -34,11 +34,11 @@ import {
|
|
|
34
34
|
trackCliCommandFinished,
|
|
35
35
|
trackEvent,
|
|
36
36
|
waitForServerRuntimeStartup
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-OMP5OLBK.js";
|
|
38
38
|
import {
|
|
39
39
|
autoSyncSkills,
|
|
40
40
|
formatAutoSyncNotice
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-PBTTPZZE.js";
|
|
42
42
|
import {
|
|
43
43
|
configExists,
|
|
44
44
|
createApiClient,
|
|
@@ -55,13 +55,13 @@ import {
|
|
|
55
55
|
saveConfig,
|
|
56
56
|
saveConfigPatch,
|
|
57
57
|
shouldPrintServeSkillsNudge
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-35IIFDIT.js";
|
|
59
59
|
import {
|
|
60
60
|
DEFAULT_DEMO_TRUSTED_PROXIES,
|
|
61
61
|
trustedProxiesProblem,
|
|
62
62
|
trustedProxyProblem
|
|
63
63
|
} from "./chunk-RB2F4D3Z.js";
|
|
64
|
-
import "./chunk-
|
|
64
|
+
import "./chunk-A75L7CUV.js";
|
|
65
65
|
import {
|
|
66
66
|
CliError,
|
|
67
67
|
EXIT_SYSTEM_ERROR,
|
|
@@ -73,7 +73,7 @@ import {
|
|
|
73
73
|
runMeasurementDraftAction,
|
|
74
74
|
systemError,
|
|
75
75
|
usageError
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-VSTKTQPS.js";
|
|
77
77
|
import {
|
|
78
78
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
79
79
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
rawEventSamples,
|
|
106
106
|
readMarketCompetitorNames,
|
|
107
107
|
runs
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-UUI4HOEL.js";
|
|
109
109
|
import {
|
|
110
110
|
AdsDeliverySnapshotStatuses,
|
|
111
111
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -238,7 +238,7 @@ import {
|
|
|
238
238
|
visibilityCompareSelectionSchema,
|
|
239
239
|
visibilityReportRequestSchema,
|
|
240
240
|
winnabilityClassSchema
|
|
241
|
-
} from "./chunk-
|
|
241
|
+
} from "./chunk-CYHUZ2JQ.js";
|
|
242
242
|
|
|
243
243
|
// src/cli.ts
|
|
244
244
|
import { pathToFileURL } from "url";
|
|
@@ -788,7 +788,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
788
788
|
async function demoCommand(options) {
|
|
789
789
|
const { host, port } = parseDemoListenOptions(options);
|
|
790
790
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
791
|
-
const { createDemoServer } = await import("./demo-server-
|
|
791
|
+
const { createDemoServer } = await import("./demo-server-K5G54GOE.js");
|
|
792
792
|
const app = await createDemoServer({ trustProxy });
|
|
793
793
|
let stopping = false;
|
|
794
794
|
const stop = () => {
|
|
@@ -1202,7 +1202,7 @@ No DB writes performed. Re-run without --dry-run to apply.`);
|
|
|
1202
1202
|
}
|
|
1203
1203
|
}
|
|
1204
1204
|
async function backfillInsightsCommand(project2, opts) {
|
|
1205
|
-
const { IntelligenceService } = await import("./intelligence-service-
|
|
1205
|
+
const { IntelligenceService } = await import("./intelligence-service-LV2TQMMR.js");
|
|
1206
1206
|
const config = loadConfig();
|
|
1207
1207
|
const db = createClient(config.database);
|
|
1208
1208
|
migrate(db);
|
|
@@ -12326,7 +12326,8 @@ function printMeasurementProperty(response) {
|
|
|
12326
12326
|
function shapedPage(response) {
|
|
12327
12327
|
if (response.answers !== void 0) return { shape: MeasurementEvidenceShapes.answers, ...response.answers };
|
|
12328
12328
|
if (response.evidence !== void 0) return { shape: MeasurementEvidenceShapes.sources, ...response.evidence };
|
|
12329
|
-
|
|
12329
|
+
if (response.otherQueries !== void 0) return { shape: MeasurementEvidenceShapes["other-queries"], ...response.otherQueries };
|
|
12330
|
+
throw systemError("The measurement property evidence response carried no evidence, answers or otherQueries page.");
|
|
12330
12331
|
}
|
|
12331
12332
|
async function showMeasurementPropertyEvidence(project2, opts) {
|
|
12332
12333
|
const response = await createApiClient().getMeasurementPropertyEvidence(project2, {
|
|
@@ -12373,15 +12374,24 @@ function printMeasurementPropertyEvidence(response) {
|
|
|
12373
12374
|
}
|
|
12374
12375
|
const page = shapedPage(response);
|
|
12375
12376
|
const answerShape = page.shape === MeasurementEvidenceShapes.answers;
|
|
12377
|
+
const otherQueriesShape = page.shape === MeasurementEvidenceShapes["other-queries"];
|
|
12376
12378
|
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
12377
12379
|
if (page.items.length === 0) {
|
|
12378
|
-
lines.push(answerShape ? "No answers matched this Property in the displayed run." : "No source evidence matched this Property in the displayed run.");
|
|
12380
|
+
lines.push(answerShape ? "No answers matched this Property in the displayed run." : otherQueriesShape ? "No answer to another query cited this Property's pages in the displayed run." : "No source evidence matched this Property in the displayed run.");
|
|
12379
12381
|
console.log(lines.join("\n"));
|
|
12380
12382
|
return;
|
|
12381
12383
|
}
|
|
12382
|
-
lines.push(`${page.items.length} of ${page.totalEstimate ?? page.items.length} ${answerShape ? "answers" : "evidence rows"}`);
|
|
12384
|
+
lines.push(`${page.items.length} of ${page.totalEstimate ?? page.items.length} ${answerShape || otherQueriesShape ? "answers" : "evidence rows"}`);
|
|
12385
|
+
if (otherQueriesShape) lines.push("Cited on queries not assigned to this Property; not counted in its rates.");
|
|
12383
12386
|
lines.push("");
|
|
12384
|
-
if (page.shape === MeasurementEvidenceShapes
|
|
12387
|
+
if (page.shape === MeasurementEvidenceShapes["other-queries"]) {
|
|
12388
|
+
lines.push(`${"Engine".padEnd(12)}${"Question".padEnd(40)}${"Class".padEnd(11)}${"Assigned to".padEnd(24)}Pages`);
|
|
12389
|
+
for (const item of page.items) {
|
|
12390
|
+
lines.push(
|
|
12391
|
+
`${item.provider.padEnd(12)}${item.queryText.slice(0, 39).padEnd(40)}${item.queryClass.padEnd(11)}${item.assignedTargetKeys.join(", ").slice(0, 23).padEnd(24)}${item.sources.map((source) => source.sourceUrl).join(" ")}`
|
|
12392
|
+
);
|
|
12393
|
+
}
|
|
12394
|
+
} else if (page.shape === MeasurementEvidenceShapes.answers) {
|
|
12385
12395
|
lines.push(`${"Engine".padEnd(12)}${"Question".padEnd(40)}${"Mentioned".padEnd(15)}${"Cited".padEnd(8)}Sources`);
|
|
12386
12396
|
for (const item of page.items) {
|
|
12387
12397
|
lines.push(
|
|
@@ -21747,7 +21757,7 @@ Usage: ${usage}`, {
|
|
|
21747
21757
|
|
|
21748
21758
|
// src/cli-commands/measurement-plan.ts
|
|
21749
21759
|
var QUERY_CLASSES = ["all", "branded", "non-brand"];
|
|
21750
|
-
var EVIDENCE_SHAPES = ["sources", "answers"];
|
|
21760
|
+
var EVIDENCE_SHAPES = ["sources", "answers", "other-queries"];
|
|
21751
21761
|
function queryClassOption(input) {
|
|
21752
21762
|
const value = getString(input.values, "query-class");
|
|
21753
21763
|
if (value === void 0) return void 0;
|
|
@@ -21979,7 +21989,7 @@ Usage: ${usage}`);
|
|
|
21979
21989
|
},
|
|
21980
21990
|
{
|
|
21981
21991
|
path: ["measurement-plan", "property-evidence"],
|
|
21982
|
-
usage: "canonry measurement-plan property-evidence <project> --target-key <key> [--query-class all|branded|non-brand] [--provider <p>] [--location <l>] [--run-id <id>] [--shape sources|answers] [--cursor <c>] [--limit N] [--format json|jsonl]",
|
|
21992
|
+
usage: "canonry measurement-plan property-evidence <project> --target-key <key> [--query-class all|branded|non-brand] [--provider <p>] [--location <l>] [--run-id <id>] [--shape sources|answers|other-queries] [--cursor <c>] [--limit N] [--format json|jsonl]",
|
|
21983
21993
|
options: { ...PROPERTY_SCOPE_OPTIONS, shape: stringOption(), cursor: stringOption(), limit: stringOption() },
|
|
21984
21994
|
run: (input) => {
|
|
21985
21995
|
const usage = "canonry measurement-plan property-evidence <project> --target-key <key>";
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
computeFactorAverages,
|
|
6
6
|
layoutSiteCrawlGraphInput,
|
|
7
7
|
persistSiteCrawlGraphLayout
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-A75L7CUV.js";
|
|
9
9
|
import {
|
|
10
10
|
PACKAGE_VERSION,
|
|
11
11
|
canonryMcpTools
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-VSTKTQPS.js";
|
|
13
13
|
import {
|
|
14
14
|
HISTORY_WINDOW_RUNS,
|
|
15
15
|
IntelligenceService,
|
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
siteCrawlPages,
|
|
86
86
|
siteCrawlSnapshots,
|
|
87
87
|
trafficSources
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-UUI4HOEL.js";
|
|
89
89
|
import {
|
|
90
90
|
RunKinds,
|
|
91
91
|
SiteCrawlFetchStates,
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
roundPreservingTotal,
|
|
116
116
|
siteAuditPageFactorSchema,
|
|
117
117
|
wilsonInterval
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-CYHUZ2JQ.js";
|
|
119
119
|
|
|
120
120
|
// src/demo-server.ts
|
|
121
121
|
import { dirname, join as join2 } from "path";
|
package/dist/index.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OMP5OLBK.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-35IIFDIT.js";
|
|
10
|
+
import "./chunk-A75L7CUV.js";
|
|
11
|
+
import "./chunk-VSTKTQPS.js";
|
|
12
|
+
import "./chunk-UUI4HOEL.js";
|
|
13
|
+
import "./chunk-CYHUZ2JQ.js";
|
|
14
14
|
export {
|
|
15
15
|
GoogleMarketingRuntimeError,
|
|
16
16
|
createGoogleMarketingCredentialStore,
|
package/dist/mcp.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoSyncSkills
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PBTTPZZE.js";
|
|
4
4
|
import {
|
|
5
5
|
createApiClient,
|
|
6
6
|
createCanonryMcpServer
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-35IIFDIT.js";
|
|
8
|
+
import "./chunk-VSTKTQPS.js";
|
|
9
9
|
import {
|
|
10
10
|
isReadOnlyKey,
|
|
11
11
|
updateCheckEnvOptOut
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CYHUZ2JQ.js";
|
|
13
13
|
|
|
14
14
|
// src/mcp/cli.ts
|
|
15
15
|
import { randomUUID } from "crypto";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.19.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
|
|
6
6
|
"keywords": [
|
|
@@ -88,31 +88,31 @@
|
|
|
88
88
|
"@ainyc/canonry-web": "0.0.0",
|
|
89
89
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
90
90
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
91
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
91
92
|
"@ainyc/canonry-config": "0.0.0",
|
|
92
93
|
"@ainyc/canonry-db": "0.0.0",
|
|
93
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
94
94
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
95
|
-
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
96
|
-
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
97
95
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
98
|
-
"@ainyc/canonry-integration-
|
|
99
|
-
"@ainyc/canonry-integration-
|
|
96
|
+
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
97
|
+
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
100
98
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
101
|
-
"@ainyc/canonry-integration-google-
|
|
99
|
+
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
102
100
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
103
|
-
"@ainyc/canonry-integration-google-
|
|
101
|
+
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
104
102
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
103
|
+
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
105
104
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
106
105
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
106
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
107
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
107
108
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
108
109
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
109
|
-
"@ainyc/canonry-intelligence": "0.0.0",
|
|
110
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
111
|
-
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
112
110
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
113
111
|
"@ainyc/canonry-provider-muse": "0.0.0",
|
|
114
112
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
115
|
-
"@ainyc/canonry-
|
|
113
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
114
|
+
"@ainyc/canonry-integration-typesafe": "0.0.0",
|
|
115
|
+
"@ainyc/canonry-provider-local": "0.0.0"
|
|
116
116
|
},
|
|
117
117
|
"scripts": {
|
|
118
118
|
"build": "pnpm run build:cli && pnpm run build:web",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as a,u as h,j as e}from"./vendor-tanstack-ZXXkndVj.js";import{dJ as L,dK as P,cH as E,x as u,B as x,v,T as M}from"./index-BVzozur0.js";const o=100;function k(s){if(s==="all")return;const n=Number.parseInt(s,10);return new Date(Date.now()-n*24*60*60*1e3).toISOString()}function O(s){const n=s.userAgent?.toLowerCase()??"";return n.includes("canonry-mcp")?"MCP":n.includes("canonry-cli")?"CLI":n.includes("mozilla/")?"Dashboard":s.actor==="scheduler"?"Scheduler":s.actor==="agent"?"Agent":s.actor==="mcp"?"MCP":s.actor==="cli"?"CLI":s.actor}function B(s){return/delete|remove|revoke|disconnect|failed|refused/.test(s)?"negative":/create|add|connect|completed/.test(s)?"positive":/update|replace|sync|apply/.test(s)?"caution":"neutral"}function D(s){return[s.action,s.actor,s.entityType,s.entityId,s.actorSession,s.userAgent,s.diff==null?"":JSON.stringify(s.diff)].filter(Boolean).join(" ").toLowerCase()}function F({projectName:s}){const[n,l]=a.useState(0),[c,y]=a.useState("90d"),[m,N]=a.useState(""),[p,w]=a.useState(""),S=a.useMemo(()=>k(c),[c]),g={limit:o,offset:n*o,since:S,actor:m||void 0},C=h({...L({client:u,path:{name:s??""},query:g}),enabled:!!s}),A=h({...P({client:u,query:g}),enabled:!s}),f=h({...E({client:u}),enabled:!s}),i=s?C:A,r=i.data??[],I=a.useMemo(()=>new Map((f.data??[]).map(t=>[t.id,t.displayName||t.name])),[f.data]),d=p.trim().toLowerCase(),j=a.useMemo(()=>d?r.filter(t=>D(t).includes(d)):r,[r,d]),b=t=>{l(0),t()};return i.isLoading?e.jsx("p",{className:"supporting-copy mt-6",role:"status",children:"Loading change history…"}):e.jsxs("section",{className:"mt-6","aria-labelledby":"change-history-heading",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Audit trail"}),e.jsx("h2",{id:"change-history-heading",children:"Change history"}),e.jsx("p",{className:"supporting-copy mt-1 max-w-2xl",children:"Configuration and operator actions. Execution outcomes remain in Runs."})]}),e.jsx(x,{type:"button",variant:"outline",size:"sm",onClick:()=>{i.refetch()},disabled:i.isFetching,children:i.isFetching?"Refreshing…":"Refresh"})]}),e.jsxs("div",{className:"mt-4 grid gap-2 sm:grid-cols-3",children:[e.jsx("input",{type:"search","aria-label":"Search change history",value:p,onChange:t=>w(t.target.value),placeholder:"Search actions, entities, or details",className:"min-h-11 rounded-md border border-base bg-bg px-3 text-sm text-strong placeholder-mono-600 focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-600"}),e.jsxs("select",{"aria-label":"Filter change history by actor",value:m,onChange:t=>b(()=>N(t.target.value)),className:"min-h-11 rounded-md border border-base bg-bg px-3 text-sm text-strong focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-600",children:[e.jsx("option",{value:"",children:"All actors"}),e.jsx("option",{value:"api",children:"API and dashboard"}),e.jsx("option",{value:"cli",children:"CLI"}),e.jsx("option",{value:"scheduler",children:"Scheduler"}),e.jsx("option",{value:"agent",children:"Agent"}),e.jsx("option",{value:"mcp",children:"MCP"})]}),e.jsxs("select",{"aria-label":"Filter change history by date range",value:c,onChange:t=>b(()=>y(t.target.value)),className:"min-h-11 rounded-md border border-base bg-bg px-3 text-sm text-strong focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-600",children:[e.jsx("option",{value:"30d",children:"Last 30 days"}),e.jsx("option",{value:"90d",children:"Last 90 days"}),e.jsx("option",{value:"365d",children:"Last year"}),e.jsx("option",{value:"all",children:"All retained history"})]})]}),i.isError?e.jsxs(v,{className:"surface-card empty-card mt-4",children:[e.jsx("h3",{children:"Change history unavailable"}),e.jsx("p",{children:i.error instanceof Error?i.error.message:"Could not load the audit trail."})]}):j.length===0?e.jsxs(v,{className:"surface-card empty-card mt-4",children:[e.jsx("h3",{children:"No changes match these filters"}),e.jsx("p",{children:"Widen the date range or clear the actor and search filters."})]}):e.jsx("div",{className:"evidence-table-wrap mt-4",children:e.jsxs("table",{className:"evidence-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"When"}),s?null:e.jsx("th",{children:"Scope"}),e.jsx("th",{children:"Action"}),e.jsx("th",{children:"Entity"}),e.jsx("th",{children:"Origin"}),e.jsx("th",{children:"Details"})]})}),e.jsx("tbody",{children:j.map(t=>e.jsxs("tr",{children:[e.jsx("td",{className:"whitespace-nowrap tabular-nums text-muted",children:new Date(t.createdAt).toLocaleString()}),s?null:e.jsx("td",{className:"text-secondary",children:t.projectId?I.get(t.projectId)??`Deleted project · ${t.projectId}`:"Instance settings"}),e.jsx("td",{children:e.jsx(M,{tone:B(t.action),children:t.action})}),e.jsxs("td",{children:[e.jsx("span",{className:"text-strong",children:t.entityType}),t.entityId?e.jsx("span",{className:"mt-0.5 block max-w-48 truncate font-mono text-[11px] text-faint",title:t.entityId,children:t.entityId}):null]}),e.jsxs("td",{children:[e.jsx("span",{className:"text-secondary",children:O(t)}),t.actorSession?e.jsxs("span",{className:"mt-0.5 block max-w-40 truncate font-mono text-[11px] text-faint",title:t.actorSession,children:["Session ",t.actorSession]}):null]}),e.jsx("td",{children:t.diff==null?e.jsx("span",{className:"text-faint",children:"No field diff"}):e.jsxs("details",{children:[e.jsx("summary",{className:"min-h-11 cursor-pointer py-3 text-sm text-secondary hover:text-strong",children:"View diff"}),e.jsx("pre",{className:"max-h-72 max-w-xl overflow-auto whitespace-pre-wrap break-words rounded-md bg-bg-elevated p-3 text-xs text-secondary",children:JSON.stringify(t.diff,null,2)})]})})]},t.id))})]})}),!i.isError&&(n>0||r.length===o)?e.jsxs("div",{className:"mt-4 flex items-center justify-between gap-3",children:[e.jsx(x,{type:"button",variant:"outline",size:"sm",disabled:n===0,onClick:()=>l(t=>Math.max(0,t-1)),children:"Previous"}),e.jsxs("span",{className:"text-xs tabular-nums text-muted",children:["Page ",n+1]}),e.jsx(x,{type:"button",variant:"outline",size:"sm",disabled:r.length<o,onClick:()=>l(t=>t+1),children:"Next"})]}):null]})}export{F as A};
|