@aeptus/aexeo-emdash 0.8.1 → 0.8.3
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/CHANGELOG.md +92 -1
- package/dist/configured.js +50 -81
- package/dist/facts-route.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/presence-route.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/wasm/aexeo_emdash_bridge_bg.wasm +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,95 @@ and the project follows [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.8.3] - 2026-05-04
|
|
10
|
+
|
|
11
|
+
Picks up the upstream aexeo-core 0.0.9 improvements that address
|
|
12
|
+
the two open quality items Aeptus flagged after the 0.8.1 + CLI
|
|
13
|
+
0.0.8 rollout.
|
|
14
|
+
|
|
15
|
+
### Changed (engine via bridge)
|
|
16
|
+
|
|
17
|
+
- **Truth-manifest generator no longer picks listing-page or
|
|
18
|
+
404 titles as the organization/product name.** Aeptus's
|
|
19
|
+
facts.json was being generated with `organization.name = "Blog"`
|
|
20
|
+
and `product.name = "Page not found"` because the listing page's
|
|
21
|
+
title outvoted the homepage and the 404 page's title leaked into
|
|
22
|
+
the candidate corpus. Three engine fixes ship in this release:
|
|
23
|
+
(a) the generic-label blocklist now covers blog, posts,
|
|
24
|
+
articles, authors, tags, categories, search, archive, page not
|
|
25
|
+
found, 404, error, oops, and pure-numeric labels;
|
|
26
|
+
(b) 404 / error pages are detected by title/h1 patterns and
|
|
27
|
+
excluded from the candidate corpus entirely;
|
|
28
|
+
(c) the homepage signal wins over any subpage signal regardless
|
|
29
|
+
of count when present.
|
|
30
|
+
|
|
31
|
+
This is a generation-quality improvement, not a wire-format
|
|
32
|
+
change — existing stored manifests are unaffected. Hosts who
|
|
33
|
+
re-run `intelligence facts generate` will get a cleaner draft.
|
|
34
|
+
|
|
35
|
+
- **GEO009 ("page facts misalign across title/H1/OG/schema")
|
|
36
|
+
now uses the same identity-extraction logic as the
|
|
37
|
+
`intelligence identity` diagnostic.** Previously the rule read
|
|
38
|
+
every JSON-LD `name` field (including BreadcrumbList items and
|
|
39
|
+
ItemList children), so it fired on listing/author/localized
|
|
40
|
+
routes where breadcrumb crumbs leaked in. The diagnostic
|
|
41
|
+
already restricted to top-level identity-bearing schema; the
|
|
42
|
+
rule and the diagnostic now share that filter. Aeptus's
|
|
43
|
+
~44 GEO009 warnings on listing/author/localized routes should
|
|
44
|
+
drop after re-running the audit.
|
|
45
|
+
|
|
46
|
+
### Notes for hosts upgrading from 0.8.x
|
|
47
|
+
|
|
48
|
+
- No code changes required — pure engine-side improvements.
|
|
49
|
+
- Re-run `intelligence facts generate` if you generated your
|
|
50
|
+
manifest with v0.0.7 or earlier of the CLI; the new generator
|
|
51
|
+
output is materially better.
|
|
52
|
+
- Re-run the audit; expect GEO009 counts to drop on listing
|
|
53
|
+
pages without any host-side change.
|
|
54
|
+
|
|
55
|
+
## [0.8.2] - 2026-05-04
|
|
56
|
+
|
|
57
|
+
Fix for the residual entity-presence trim() crash that 0.8.1
|
|
58
|
+
didn't solve.
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- **`/facts` and `/presence` routes were double-wrapping their
|
|
63
|
+
return values.** Both handlers returned `{ data: ... }` payloads,
|
|
64
|
+
but emdash's route registry already wraps a handler's return as
|
|
65
|
+
`{ data: <result> }` at the wire boundary. The result was
|
|
66
|
+
`{ data: { data: ... } }` on the wire. The React caller's
|
|
67
|
+
single-unwrap (`body.data`) surfaced `{ data: ... }` to the
|
|
68
|
+
consumer where the actual payload was expected — so
|
|
69
|
+
`(res as ManifestData).manifest` came back as `undefined`,
|
|
70
|
+
`JSON.stringify(undefined)` returned the literal `undefined`,
|
|
71
|
+
`setDraft(undefined)` set the textarea draft to undefined, and
|
|
72
|
+
the next render crashed on `draft.trim()`.
|
|
73
|
+
|
|
74
|
+
Fixed by changing both route handlers to return raw payloads
|
|
75
|
+
(matching the `/data` and `/refresh` route convention that has
|
|
76
|
+
always worked correctly). Errors are now signaled by throwing
|
|
77
|
+
`PluginRouteError` from the `emdash` package — the registry
|
|
78
|
+
treats thrown PluginRouteErrors as structured failures and
|
|
79
|
+
routes them through the host's standard error path. Returned
|
|
80
|
+
`{ error: ... }` objects (the previous pattern) flowed through
|
|
81
|
+
the success path and silently masqueraded as data.
|
|
82
|
+
|
|
83
|
+
### Notes for hosts upgrading from 0.8.x
|
|
84
|
+
|
|
85
|
+
- No code changes required.
|
|
86
|
+
- The wire format of the `/facts` and `/presence` route responses
|
|
87
|
+
changes: where they previously returned
|
|
88
|
+
`{ data: { data: <payload> } }`, they now return
|
|
89
|
+
`{ data: <payload> }`. Anyone calling these routes directly
|
|
90
|
+
(outside the bundled React admin) needs to drop one unwrap.
|
|
91
|
+
The bundled admin is updated in lockstep so editors see no
|
|
92
|
+
behavioral difference beyond the bug being fixed.
|
|
93
|
+
- Error responses for these routes now come back through the
|
|
94
|
+
standard `PluginRouteError` envelope (HTTP 4xx with
|
|
95
|
+
`{ error: { code, message } }`) instead of being silently
|
|
96
|
+
embedded in success responses.
|
|
97
|
+
|
|
9
98
|
## [0.8.1] - 2026-05-03
|
|
10
99
|
|
|
11
100
|
Fix for the entity-presence diagnostic shipped in 0.8.0.
|
|
@@ -519,7 +608,9 @@ First public release.
|
|
|
519
608
|
`astro.config.mjs` for the WASM import to resolve to a
|
|
520
609
|
precompiled `WebAssembly.Module`. Not optional.
|
|
521
610
|
|
|
522
|
-
[Unreleased]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.8.
|
|
611
|
+
[Unreleased]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.8.3...HEAD
|
|
612
|
+
[0.8.3]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.8.2...aexeo-emdash-v0.8.3
|
|
613
|
+
[0.8.2]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.8.1...aexeo-emdash-v0.8.2
|
|
523
614
|
[0.8.1]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.8.0...aexeo-emdash-v0.8.1
|
|
524
615
|
[0.8.0]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.7.0...aexeo-emdash-v0.8.0
|
|
525
616
|
[0.7.0]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.6.0...aexeo-emdash-v0.7.0
|
package/dist/configured.js
CHANGED
|
@@ -469,8 +469,8 @@ async function handleDataRoute(ctx, options) {
|
|
|
469
469
|
});
|
|
470
470
|
await persistManifestStateFindings(ctx);
|
|
471
471
|
}
|
|
472
|
-
const
|
|
473
|
-
return { payload, summary };
|
|
472
|
+
const payload2 = await buildFindingsPayload(ctx);
|
|
473
|
+
return { payload: payload2, summary };
|
|
474
474
|
}
|
|
475
475
|
async function buildFindingsPayload(ctx) {
|
|
476
476
|
const stored = await readAllStoredDocuments(ctx.kv);
|
|
@@ -649,6 +649,7 @@ function buildPublishedUrl(meta, route, siteUrl) {
|
|
|
649
649
|
}
|
|
650
650
|
|
|
651
651
|
// src/facts-route.ts
|
|
652
|
+
import { PluginRouteError } from "emdash";
|
|
652
653
|
async function handleFactsRoute(ctx) {
|
|
653
654
|
const body = ctx.input ?? {};
|
|
654
655
|
switch (body.kind) {
|
|
@@ -661,47 +662,34 @@ async function handleFactsRoute(ctx) {
|
|
|
661
662
|
case "save":
|
|
662
663
|
return await handleSave(ctx, body);
|
|
663
664
|
default:
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
message: `unknown facts route kind: ${String(body.kind)}`
|
|
668
|
-
}
|
|
669
|
-
};
|
|
665
|
+
throw PluginRouteError.badRequest(
|
|
666
|
+
`unknown facts route kind: ${String(body.kind)}`
|
|
667
|
+
);
|
|
670
668
|
}
|
|
671
669
|
}
|
|
672
670
|
async function handleData(ctx) {
|
|
673
671
|
const manifest = await readStoredFacts(ctx.kv);
|
|
674
672
|
return {
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
present: manifest !== null
|
|
681
|
-
}
|
|
673
|
+
manifest,
|
|
674
|
+
// The presence flag lets the React component branch on
|
|
675
|
+
// "show authoring CTA" vs "show 'manifest stored' state" without
|
|
676
|
+
// having to introspect the manifest shape.
|
|
677
|
+
present: manifest !== null
|
|
682
678
|
};
|
|
683
679
|
}
|
|
684
680
|
async function handlePrompt(ctx) {
|
|
685
681
|
const documents = await readAllDocuments(ctx.kv);
|
|
686
682
|
if (documents.length === 0) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
message: "no documents indexed yet \u2014 click Refresh on the Findings page first, then come back to author the manifest"
|
|
691
|
-
}
|
|
692
|
-
};
|
|
683
|
+
throw PluginRouteError.badRequest(
|
|
684
|
+
"no documents indexed yet \u2014 click Refresh on the Findings page first, then come back to author the manifest"
|
|
685
|
+
);
|
|
693
686
|
}
|
|
694
687
|
const prompt = await generateFactsPrompt2(JSON.stringify(documents));
|
|
695
|
-
return {
|
|
688
|
+
return { prompt };
|
|
696
689
|
}
|
|
697
690
|
async function handleValidate(ctx, body) {
|
|
698
691
|
if (typeof body.manifest_json !== "string" || body.manifest_json.length === 0) {
|
|
699
|
-
|
|
700
|
-
error: {
|
|
701
|
-
code: "missing_manifest",
|
|
702
|
-
message: "manifest_json field is required"
|
|
703
|
-
}
|
|
704
|
-
};
|
|
692
|
+
throw PluginRouteError.badRequest("manifest_json field is required");
|
|
705
693
|
}
|
|
706
694
|
const documents = await readAllDocuments(ctx.kv);
|
|
707
695
|
try {
|
|
@@ -709,24 +697,16 @@ async function handleValidate(ctx, body) {
|
|
|
709
697
|
body.manifest_json,
|
|
710
698
|
JSON.stringify(documents)
|
|
711
699
|
);
|
|
712
|
-
return
|
|
700
|
+
return JSON.parse(raw);
|
|
713
701
|
} catch (error) {
|
|
714
|
-
|
|
715
|
-
error:
|
|
716
|
-
|
|
717
|
-
message: error instanceof Error ? error.message : String(error)
|
|
718
|
-
}
|
|
719
|
-
};
|
|
702
|
+
throw PluginRouteError.badRequest(
|
|
703
|
+
error instanceof Error ? error.message : String(error)
|
|
704
|
+
);
|
|
720
705
|
}
|
|
721
706
|
}
|
|
722
707
|
async function handleSave(ctx, body) {
|
|
723
708
|
if (typeof body.manifest_json !== "string" || body.manifest_json.length === 0) {
|
|
724
|
-
|
|
725
|
-
error: {
|
|
726
|
-
code: "missing_manifest",
|
|
727
|
-
message: "manifest_json field is required"
|
|
728
|
-
}
|
|
729
|
-
};
|
|
709
|
+
throw PluginRouteError.badRequest("manifest_json field is required");
|
|
730
710
|
}
|
|
731
711
|
const documents = await readAllDocuments(ctx.kv);
|
|
732
712
|
let validation;
|
|
@@ -738,37 +718,31 @@ async function handleSave(ctx, body) {
|
|
|
738
718
|
const parsed2 = JSON.parse(raw);
|
|
739
719
|
validation = parsed2.validation;
|
|
740
720
|
} catch (error) {
|
|
741
|
-
|
|
742
|
-
error:
|
|
743
|
-
|
|
744
|
-
message: error instanceof Error ? error.message : String(error)
|
|
745
|
-
}
|
|
746
|
-
};
|
|
721
|
+
throw PluginRouteError.badRequest(
|
|
722
|
+
error instanceof Error ? error.message : String(error)
|
|
723
|
+
);
|
|
747
724
|
}
|
|
748
725
|
if (!validation.valid || validation.errors.length > 0) {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
message: `manifest does not pass shape validation: ${validation.errors.slice(0, 3).join("; ")}`
|
|
753
|
-
}
|
|
754
|
-
};
|
|
726
|
+
throw PluginRouteError.badRequest(
|
|
727
|
+
`manifest does not pass shape validation: ${validation.errors.slice(0, 3).join("; ")}`
|
|
728
|
+
);
|
|
755
729
|
}
|
|
756
730
|
let parsed;
|
|
757
731
|
try {
|
|
758
732
|
parsed = JSON.parse(body.manifest_json);
|
|
759
733
|
} catch (error) {
|
|
760
|
-
|
|
761
|
-
error:
|
|
762
|
-
|
|
763
|
-
message: error instanceof Error ? error.message : String(error)
|
|
764
|
-
}
|
|
765
|
-
};
|
|
734
|
+
throw PluginRouteError.badRequest(
|
|
735
|
+
error instanceof Error ? error.message : String(error)
|
|
736
|
+
);
|
|
766
737
|
}
|
|
767
738
|
await ctx.kv.set(FACTS_KEY, parsed);
|
|
768
739
|
await persistManifestStateFindings(ctx);
|
|
769
|
-
return {
|
|
740
|
+
return { saved: true };
|
|
770
741
|
}
|
|
771
742
|
|
|
743
|
+
// src/presence-route.ts
|
|
744
|
+
import { PluginRouteError as PluginRouteError2 } from "emdash";
|
|
745
|
+
|
|
772
746
|
// src/presence-check.ts
|
|
773
747
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
774
748
|
var USER_AGENT = "aexeo-emdash-plugin/0.8 (+https://github.com/schiste/Aexeo; entity-presence diagnostic)";
|
|
@@ -1073,58 +1047,53 @@ async function handlePresenceRoute(ctx) {
|
|
|
1073
1047
|
case "refresh":
|
|
1074
1048
|
return await handleRefresh(ctx);
|
|
1075
1049
|
default:
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
message: `unknown presence route kind: ${String(body.kind)}`
|
|
1080
|
-
}
|
|
1081
|
-
};
|
|
1050
|
+
throw PluginRouteError2.badRequest(
|
|
1051
|
+
`unknown presence route kind: ${String(body.kind)}`
|
|
1052
|
+
);
|
|
1082
1053
|
}
|
|
1083
1054
|
}
|
|
1084
1055
|
async function handleData2(ctx) {
|
|
1085
1056
|
const manifest = await readStoredFacts(ctx.kv);
|
|
1086
1057
|
if (manifest === null) {
|
|
1087
|
-
return
|
|
1058
|
+
return payload("no_manifest", [], null, null);
|
|
1088
1059
|
}
|
|
1089
1060
|
const entity = entityFromManifest(manifest);
|
|
1090
1061
|
if (entity === null) {
|
|
1091
|
-
return
|
|
1062
|
+
return payload("no_organization", [], null, null);
|
|
1092
1063
|
}
|
|
1093
1064
|
const cached = await ctx.kv.get(PRESENCE_KEY);
|
|
1094
1065
|
if (!cached) {
|
|
1095
|
-
return
|
|
1066
|
+
return payload("empty", [], null, entity.name);
|
|
1096
1067
|
}
|
|
1097
1068
|
if (cached.entityName !== entity.name) {
|
|
1098
|
-
return
|
|
1069
|
+
return payload("empty", [], null, entity.name);
|
|
1099
1070
|
}
|
|
1100
1071
|
const ageMs = ageMillis(cached.generatedAt);
|
|
1101
1072
|
const state = ageMs !== null && ageMs > CACHE_TTL_MS ? "stale" : "fresh";
|
|
1102
|
-
return
|
|
1073
|
+
return payload(state, cached.results, cached.generatedAt, entity.name);
|
|
1103
1074
|
}
|
|
1104
1075
|
async function handleRefresh(ctx) {
|
|
1105
1076
|
const manifest = await readStoredFacts(ctx.kv);
|
|
1106
1077
|
if (manifest === null) {
|
|
1107
|
-
return
|
|
1078
|
+
return payload("no_manifest", [], null, null);
|
|
1108
1079
|
}
|
|
1109
1080
|
const entity = entityFromManifest(manifest);
|
|
1110
1081
|
if (entity === null) {
|
|
1111
|
-
return
|
|
1082
|
+
return payload("no_organization", [], null, null);
|
|
1112
1083
|
}
|
|
1113
1084
|
const results = await checkAllSources(entity);
|
|
1114
1085
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1115
|
-
const
|
|
1086
|
+
const cachePayload = {
|
|
1116
1087
|
results,
|
|
1117
1088
|
generatedAt,
|
|
1118
1089
|
entityName: entity.name
|
|
1119
1090
|
};
|
|
1120
|
-
await ctx.kv.set(PRESENCE_KEY,
|
|
1121
|
-
return
|
|
1091
|
+
await ctx.kv.set(PRESENCE_KEY, cachePayload);
|
|
1092
|
+
return payload("fresh", results, generatedAt, entity.name);
|
|
1122
1093
|
}
|
|
1123
|
-
function
|
|
1094
|
+
function payload(state, results, generatedAt, entityName) {
|
|
1124
1095
|
const ageMinutes = generatedAt === null ? null : Math.max(0, Math.floor((ageMillis(generatedAt) ?? 0) / 6e4));
|
|
1125
|
-
return {
|
|
1126
|
-
data: { state, results, generatedAt, entityName, ageMinutes }
|
|
1127
|
-
};
|
|
1096
|
+
return { state, results, generatedAt, entityName, ageMinutes };
|
|
1128
1097
|
}
|
|
1129
1098
|
function ageMillis(iso) {
|
|
1130
1099
|
const t = Date.parse(iso);
|
|
@@ -1191,7 +1160,7 @@ function globToMatcher(pattern) {
|
|
|
1191
1160
|
}
|
|
1192
1161
|
|
|
1193
1162
|
// src/version.ts
|
|
1194
|
-
var PACKAGE_VERSION = "0.8.
|
|
1163
|
+
var PACKAGE_VERSION = "0.8.3";
|
|
1195
1164
|
|
|
1196
1165
|
// src/configured.ts
|
|
1197
1166
|
import { definePlugin } from "emdash";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facts-route.d.ts","sourceRoot":"","sources":["../src/facts-route.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"facts-route.d.ts","sourceRoot":"","sources":["../src/facts-route.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAa9C,UAAU,YAAa,SAAQ,UAAU;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAcD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB1E"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence-route.d.ts","sourceRoot":"","sources":["../src/presence-route.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presence-route.d.ts","sourceRoot":"","sources":["../src/presence-route.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0C9C,UAAU,YAAa,SAAQ,UAAU;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAMD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "0.8.
|
|
1
|
+
export declare const PACKAGE_VERSION = "0.8.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
Binary file
|