agentskeptic 1.0.4 → 1.1.1

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 (292) hide show
  1. package/README.md +18 -20
  2. package/config/marketing.json +187 -0
  3. package/dist/actionableFailure.d.ts.map +1 -1
  4. package/dist/actionableFailure.js +95 -0
  5. package/dist/actionableFailure.js.map +1 -1
  6. package/dist/assurance/assurancePathArgs.d.ts.map +1 -1
  7. package/dist/assurance/assurancePathArgs.js +1 -0
  8. package/dist/assurance/assurancePathArgs.js.map +1 -1
  9. package/dist/assurance/buildAssuranceOutput.d.ts +29 -0
  10. package/dist/assurance/buildAssuranceOutput.d.ts.map +1 -0
  11. package/dist/assurance/buildAssuranceOutput.js +53 -0
  12. package/dist/assurance/buildAssuranceOutput.js.map +1 -0
  13. package/dist/assurance/checkStale.d.ts +7 -0
  14. package/dist/assurance/checkStale.d.ts.map +1 -1
  15. package/dist/assurance/checkStale.js +14 -3
  16. package/dist/assurance/checkStale.js.map +1 -1
  17. package/dist/assurance/runAssurance.d.ts.map +1 -1
  18. package/dist/assurance/runAssurance.js +26 -3
  19. package/dist/assurance/runAssurance.js.map +1 -1
  20. package/dist/bootstrap/executeBootstrapPack.d.ts.map +1 -1
  21. package/dist/bootstrap/executeBootstrapPack.js +3 -2
  22. package/dist/bootstrap/executeBootstrapPack.js.map +1 -1
  23. package/dist/certificateDigest.d.ts +4 -0
  24. package/dist/certificateDigest.d.ts.map +1 -0
  25. package/dist/certificateDigest.js +7 -0
  26. package/dist/certificateDigest.js.map +1 -0
  27. package/dist/certificateDigest.test.d.ts +2 -0
  28. package/dist/certificateDigest.test.d.ts.map +1 -0
  29. package/dist/certificateDigest.test.js +14 -0
  30. package/dist/certificateDigest.test.js.map +1 -0
  31. package/dist/cli/lockOrchestration.d.ts.map +1 -1
  32. package/dist/cli/lockOrchestration.js +30 -5
  33. package/dist/cli/lockOrchestration.js.map +1 -1
  34. package/dist/cli/runFunnelAnonSet.js +1 -1
  35. package/dist/cli.js +121 -114
  36. package/dist/cli.js.map +1 -1
  37. package/dist/cliArgv.d.ts.map +1 -1
  38. package/dist/cliArgv.js +4 -2
  39. package/dist/cliArgv.js.map +1 -1
  40. package/dist/cliArgv.test.d.ts +2 -0
  41. package/dist/cliArgv.test.d.ts.map +1 -0
  42. package/dist/cliArgv.test.js +34 -0
  43. package/dist/cliArgv.test.js.map +1 -0
  44. package/dist/cliOperationalCodes.d.ts +7 -0
  45. package/dist/cliOperationalCodes.d.ts.map +1 -1
  46. package/dist/cliOperationalCodes.js +7 -0
  47. package/dist/cliOperationalCodes.js.map +1 -1
  48. package/dist/commercial/activationCorrelation.d.ts +3 -0
  49. package/dist/commercial/activationCorrelation.d.ts.map +1 -0
  50. package/dist/commercial/activationCorrelation.js +6 -0
  51. package/dist/commercial/activationCorrelation.js.map +1 -0
  52. package/dist/commercial/getCurrentUsage.d.ts +16 -0
  53. package/dist/commercial/getCurrentUsage.d.ts.map +1 -0
  54. package/dist/commercial/getCurrentUsage.js +33 -0
  55. package/dist/commercial/getCurrentUsage.js.map +1 -0
  56. package/dist/commercial/licensePreflight.d.ts +1 -0
  57. package/dist/commercial/licensePreflight.d.ts.map +1 -1
  58. package/dist/commercial/licensePreflight.js +27 -8
  59. package/dist/commercial/licensePreflight.js.map +1 -1
  60. package/dist/commercial/postVerifyOutcomeBeacon.d.ts +2 -0
  61. package/dist/commercial/postVerifyOutcomeBeacon.d.ts.map +1 -1
  62. package/dist/commercial/postVerifyOutcomeBeacon.js +8 -4
  63. package/dist/commercial/postVerifyOutcomeBeacon.js.map +1 -1
  64. package/dist/commercial/verifyWorkloadClassify.d.ts +2 -7
  65. package/dist/commercial/verifyWorkloadClassify.d.ts.map +1 -1
  66. package/dist/commercial/verifyWorkloadClassify.js +1 -1
  67. package/dist/commercial/verifyWorkloadClassify.js.map +1 -1
  68. package/dist/commercial/verifyWorkloadClassify.test.js +7 -0
  69. package/dist/commercial/verifyWorkloadClassify.test.js.map +1 -1
  70. package/dist/compare.acceptance.test.js +25 -0
  71. package/dist/compare.acceptance.test.js.map +1 -1
  72. package/dist/compareRunManifest.d.ts +32 -0
  73. package/dist/compareRunManifest.d.ts.map +1 -0
  74. package/dist/compareRunManifest.js +60 -0
  75. package/dist/compareRunManifest.js.map +1 -0
  76. package/dist/crossing/crossingDecisionReadyFooter.d.ts +1 -1
  77. package/dist/crossing/crossingDecisionReadyFooter.d.ts.map +1 -1
  78. package/dist/crossing/crossingDecisionReadyFooter.js +1 -1
  79. package/dist/crossing/crossingDecisionReadyFooter.js.map +1 -1
  80. package/dist/debug-ui/app.css +42 -0
  81. package/dist/debug-ui/app.js +206 -15
  82. package/dist/debug-ui/index.html +11 -4
  83. package/dist/debug-ui/urlState.d.ts +15 -0
  84. package/dist/debug-ui/urlState.js +92 -0
  85. package/dist/debugCorpus.test.js +33 -7
  86. package/dist/debugCorpus.test.js.map +1 -1
  87. package/dist/debugPanels.d.ts +0 -3
  88. package/dist/debugPanels.d.ts.map +1 -1
  89. package/dist/debugPanels.js +0 -23
  90. package/dist/debugPanels.js.map +1 -1
  91. package/dist/debugPanels.test.js +16 -15
  92. package/dist/debugPanels.test.js.map +1 -1
  93. package/dist/debugServer.d.ts.map +1 -1
  94. package/dist/debugServer.js +19 -16
  95. package/dist/debugServer.js.map +1 -1
  96. package/dist/debugServer.test.js +18 -9
  97. package/dist/debugServer.test.js.map +1 -1
  98. package/dist/debugUiUrlState.test.d.ts +2 -0
  99. package/dist/debugUiUrlState.test.d.ts.map +1 -0
  100. package/dist/debugUiUrlState.test.js +49 -0
  101. package/dist/debugUiUrlState.test.js.map +1 -0
  102. package/dist/decisionGate.d.ts.map +1 -1
  103. package/dist/decisionGate.js +2 -5
  104. package/dist/decisionGate.js.map +1 -1
  105. package/dist/discovery-payload-v1.json +23 -27
  106. package/dist/enforceCli.d.ts.map +1 -1
  107. package/dist/enforceCli.js +15 -40
  108. package/dist/enforceCli.js.map +1 -1
  109. package/dist/enforceStateful.d.ts +2 -0
  110. package/dist/enforceStateful.d.ts.map +1 -0
  111. package/dist/enforceStateful.js +106 -0
  112. package/dist/enforceStateful.js.map +1 -0
  113. package/dist/enforcementProjection.d.ts +17 -0
  114. package/dist/enforcementProjection.d.ts.map +1 -0
  115. package/dist/enforcementProjection.js +20 -0
  116. package/dist/enforcementProjection.js.map +1 -0
  117. package/dist/executionTrace.test.js +35 -0
  118. package/dist/executionTrace.test.js.map +1 -1
  119. package/dist/executionTraceDiff.d.ts +36 -0
  120. package/dist/executionTraceDiff.d.ts.map +1 -0
  121. package/dist/executionTraceDiff.js +86 -0
  122. package/dist/executionTraceDiff.js.map +1 -0
  123. package/dist/executionTraceDiff.test.d.ts +2 -0
  124. package/dist/executionTraceDiff.test.d.ts.map +1 -0
  125. package/dist/executionTraceDiff.test.js +44 -0
  126. package/dist/executionTraceDiff.test.js.map +1 -0
  127. package/dist/failureOriginCatalog.d.ts.map +1 -1
  128. package/dist/failureOriginCatalog.js +19 -0
  129. package/dist/failureOriginCatalog.js.map +1 -1
  130. package/dist/firstFiveMinutesChecklist.d.ts +11 -0
  131. package/dist/firstFiveMinutesChecklist.d.ts.map +1 -0
  132. package/dist/firstFiveMinutesChecklist.js +18 -0
  133. package/dist/firstFiveMinutesChecklist.js.map +1 -0
  134. package/dist/funnel/workflowLineageClassify.d.ts +1 -1
  135. package/dist/funnel/workflowLineageClassify.js +1 -1
  136. package/dist/index.d.ts +5 -2
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +4 -2
  139. package/dist/index.js.map +1 -1
  140. package/dist/langGraphCheckpointTrustGate.d.ts.map +1 -1
  141. package/dist/langGraphCheckpointTrustGate.js +2 -5
  142. package/dist/langGraphCheckpointTrustGate.js.map +1 -1
  143. package/dist/operationalDisposition.d.ts +56 -0
  144. package/dist/operationalDisposition.d.ts.map +1 -1
  145. package/dist/operationalDisposition.js +56 -0
  146. package/dist/operationalDisposition.js.map +1 -1
  147. package/dist/pipeline.d.ts +1 -0
  148. package/dist/pipeline.d.ts.map +1 -1
  149. package/dist/pipeline.js +18 -18
  150. package/dist/pipeline.js.map +1 -1
  151. package/dist/publicDistribution.generated.d.ts +2 -2
  152. package/dist/publicDistribution.generated.d.ts.map +1 -1
  153. package/dist/publicDistribution.generated.js +7 -8
  154. package/dist/publicDistribution.generated.js.map +1 -1
  155. package/dist/quickVerify/quickVerifyScope.d.ts +1 -1
  156. package/dist/quickVerify/quickVerifyScope.js +1 -1
  157. package/dist/quickVerify/runQuickVerify.js +1 -1
  158. package/dist/quickVerify/runQuickVerify.js.map +1 -1
  159. package/dist/quickVerify/verifyExecution.d.ts +1 -1
  160. package/dist/quickVerify/verifyExecution.d.ts.map +1 -1
  161. package/dist/quickVerify/verifyExecution.js +3 -2
  162. package/dist/quickVerify/verifyExecution.js.map +1 -1
  163. package/dist/reconciler.d.ts +6 -2
  164. package/dist/reconciler.d.ts.map +1 -1
  165. package/dist/reconciler.js +17 -11
  166. package/dist/reconciler.js.map +1 -1
  167. package/dist/registryDraft/createRegistryDraftAjv.d.ts +1 -1
  168. package/dist/registryDraft/createRegistryDraftAjv.js +1 -1
  169. package/dist/regressionArtifact.d.ts +63 -0
  170. package/dist/regressionArtifact.d.ts.map +1 -0
  171. package/dist/regressionArtifact.js +290 -0
  172. package/dist/regressionArtifact.js.map +1 -0
  173. package/dist/relationalInvariant.d.ts +13 -3
  174. package/dist/relationalInvariant.d.ts.map +1 -1
  175. package/dist/relationalInvariant.existsSql.test.js +1 -1
  176. package/dist/relationalInvariant.existsSql.test.js.map +1 -1
  177. package/dist/relationalInvariant.js +59 -39
  178. package/dist/relationalInvariant.js.map +1 -1
  179. package/dist/relationalInvariant.test.js +2 -2
  180. package/dist/relationalInvariant.test.js.map +1 -1
  181. package/dist/resolveExpectation.d.ts +18 -2
  182. package/dist/resolveExpectation.d.ts.map +1 -1
  183. package/dist/resolveExpectation.js +332 -1
  184. package/dist/resolveExpectation.js.map +1 -1
  185. package/dist/resolveExpectation.test.js +25 -0
  186. package/dist/resolveExpectation.test.js.map +1 -1
  187. package/dist/runComparison.d.ts +0 -1
  188. package/dist/runComparison.d.ts.map +1 -1
  189. package/dist/runComparison.js +18 -86
  190. package/dist/runComparison.js.map +1 -1
  191. package/dist/runComparison.test.js +101 -57
  192. package/dist/runComparison.test.js.map +1 -1
  193. package/dist/schema-validation.test.js +29 -0
  194. package/dist/schema-validation.test.js.map +1 -1
  195. package/dist/schemaLoad.d.ts +1 -1
  196. package/dist/schemaLoad.d.ts.map +1 -1
  197. package/dist/schemaLoad.js +10 -0
  198. package/dist/schemaLoad.js.map +1 -1
  199. package/dist/sortedJsonStringify.d.ts +2 -0
  200. package/dist/sortedJsonStringify.d.ts.map +1 -0
  201. package/dist/sortedJsonStringify.js +23 -0
  202. package/dist/sortedJsonStringify.js.map +1 -0
  203. package/dist/sqlDialect.d.ts +8 -0
  204. package/dist/sqlDialect.d.ts.map +1 -0
  205. package/dist/sqlDialect.js +37 -0
  206. package/dist/sqlDialect.js.map +1 -0
  207. package/dist/standardVerifyWorkflowCli.d.ts.map +1 -1
  208. package/dist/standardVerifyWorkflowCli.js +3 -2
  209. package/dist/standardVerifyWorkflowCli.js.map +1 -1
  210. package/dist/stateWitness.d.ts +4 -0
  211. package/dist/stateWitness.d.ts.map +1 -0
  212. package/dist/stateWitness.js +383 -0
  213. package/dist/stateWitness.js.map +1 -0
  214. package/dist/stateWitness.test.d.ts +2 -0
  215. package/dist/stateWitness.test.d.ts.map +1 -0
  216. package/dist/stateWitness.test.js +120 -0
  217. package/dist/stateWitness.test.js.map +1 -0
  218. package/dist/telemetry/maybeEmitOssClaimTicketUrl.d.ts +2 -0
  219. package/dist/telemetry/maybeEmitOssClaimTicketUrl.d.ts.map +1 -1
  220. package/dist/telemetry/maybeEmitOssClaimTicketUrl.js +13 -2
  221. package/dist/telemetry/maybeEmitOssClaimTicketUrl.js.map +1 -1
  222. package/dist/telemetry/ossClaimOrigin.d.ts +1 -1
  223. package/dist/telemetry/ossClaimOrigin.js +1 -1
  224. package/dist/telemetry/postOssClaimContinuation.d.ts +1 -1
  225. package/dist/telemetry/postOssClaimContinuation.d.ts.map +1 -1
  226. package/dist/telemetry/postOssClaimContinuation.js +10 -6
  227. package/dist/telemetry/postOssClaimContinuation.js.map +1 -1
  228. package/dist/telemetry/postOssClaimTicket.d.ts +8 -0
  229. package/dist/telemetry/postOssClaimTicket.d.ts.map +1 -1
  230. package/dist/telemetry/postOssClaimTicket.js +31 -5
  231. package/dist/telemetry/postOssClaimTicket.js.map +1 -1
  232. package/dist/telemetry/verificationHypothesisContract.d.ts +1 -1
  233. package/dist/telemetry/verificationHypothesisContract.js +1 -1
  234. package/dist/types.d.ts +115 -3
  235. package/dist/types.d.ts.map +1 -1
  236. package/dist/types.js.map +1 -1
  237. package/dist/verificationConnections.d.ts +10 -0
  238. package/dist/verificationConnections.d.ts.map +1 -0
  239. package/dist/verificationConnections.js +190 -0
  240. package/dist/verificationConnections.js.map +1 -0
  241. package/dist/verificationDatabaseUrl.d.ts +11 -0
  242. package/dist/verificationDatabaseUrl.d.ts.map +1 -0
  243. package/dist/verificationDatabaseUrl.js +41 -0
  244. package/dist/verificationDatabaseUrl.js.map +1 -0
  245. package/dist/verificationDatabaseUrl.test.d.ts +2 -0
  246. package/dist/verificationDatabaseUrl.test.d.ts.map +1 -0
  247. package/dist/verificationDatabaseUrl.test.js +66 -0
  248. package/dist/verificationDatabaseUrl.test.js.map +1 -0
  249. package/dist/verificationDiagnostics.d.ts.map +1 -1
  250. package/dist/verificationDiagnostics.js +33 -9
  251. package/dist/verificationDiagnostics.js.map +1 -1
  252. package/dist/verificationDiagnostics.test.js +15 -0
  253. package/dist/verificationDiagnostics.test.js.map +1 -1
  254. package/dist/verificationPolicy.d.ts +2 -1
  255. package/dist/verificationPolicy.d.ts.map +1 -1
  256. package/dist/verificationPolicy.js +97 -0
  257. package/dist/verificationPolicy.js.map +1 -1
  258. package/dist/verificationPolicy.test.js +7 -0
  259. package/dist/verificationPolicy.test.js.map +1 -1
  260. package/dist/verificationUserPhrases.d.ts.map +1 -1
  261. package/dist/verificationUserPhrases.js +21 -0
  262. package/dist/verificationUserPhrases.js.map +1 -1
  263. package/dist/verify/batchVerifyTelemetrySubcommand.d.ts.map +1 -1
  264. package/dist/verify/batchVerifyTelemetrySubcommand.js +8 -1
  265. package/dist/verify/batchVerifyTelemetrySubcommand.js.map +1 -1
  266. package/dist/vitestMonorepoRoot.d.ts +10 -0
  267. package/dist/vitestMonorepoRoot.d.ts.map +1 -0
  268. package/dist/vitestMonorepoRoot.js +97 -0
  269. package/dist/vitestMonorepoRoot.js.map +1 -0
  270. package/dist/wireReasonCodes.d.ts +21 -0
  271. package/dist/wireReasonCodes.d.ts.map +1 -1
  272. package/dist/wireReasonCodes.js +21 -0
  273. package/dist/wireReasonCodes.js.map +1 -1
  274. package/package.json +61 -40
  275. package/schemas/assurance-output-v1.schema.json +81 -0
  276. package/schemas/compare-run-manifest-v1.schema.json +65 -0
  277. package/schemas/conformance-normalized-result.schema.json +73 -0
  278. package/schemas/connector-capabilities.schema.json +38 -0
  279. package/schemas/execution-trace-view.schema.json +1 -1
  280. package/schemas/openapi-commercial-v1.in.yaml +613 -14
  281. package/schemas/openapi-commercial-v1.yaml +613 -14
  282. package/schemas/quick-verify-report.schema.json +1 -1
  283. package/schemas/regression-artifact-v1.schema.json +212 -0
  284. package/schemas/tools-registry.schema.json +103 -0
  285. package/schemas/workflow-engine-result.schema.json +69 -1
  286. package/schemas/workflow-truth-report.schema.json +12 -0
  287. package/scripts/discovery-acquisition.lib.cjs +6 -17
  288. package/scripts/discovery-payload.lib.cjs +5 -3
  289. package/scripts/emit-primary-marketing.cjs +326 -0
  290. package/scripts/origin.cjs +52 -0
  291. package/scripts/public-product-anchors.cjs +3 -0
  292. package/scripts/validate-marketing.cjs +156 -0
@@ -0,0 +1,326 @@
1
+ "use strict";
2
+
3
+ const { readFileSync, writeFileSync, mkdirSync } = require("node:fs");
4
+ const { join, dirname } = require("node:path");
5
+ const { normalize, assertNextPublicOriginParity, MARKETING_PATH } = require("./origin.cjs");
6
+
7
+ const ROOT = join(__dirname, "..");
8
+
9
+ const OPENAPI_IN = join(ROOT, "schemas", "openapi-commercial-v1.in.yaml");
10
+ const OPENAPI_OUT = join(ROOT, "schemas", "openapi-commercial-v1.yaml");
11
+ const OPENAPI_PUBLIC = join(ROOT, "website", "public", "openapi-commercial-v1.yaml");
12
+ const LLMS_PUBLIC = join(ROOT, "website", "public", "llms.txt");
13
+ const LLMS_REPO_ROOT = join(ROOT, "llms.txt");
14
+ const README_PATH = join(ROOT, "README.md");
15
+ const PKG_PATH = join(ROOT, "package.json");
16
+
17
+ const README_START = "<!-- public-product-anchors:start -->";
18
+ const README_END = "<!-- public-product-anchors:end -->";
19
+ const DISCOVERY_README_START = "<!-- discovery-acquisition-fold:start -->";
20
+ const DISCOVERY_README_END = "<!-- discovery-acquisition-fold:end -->";
21
+ const DISCOVERY_README_TITLE_START = "<!-- discovery-readme-title:start -->";
22
+ const DISCOVERY_README_TITLE_END = "<!-- discovery-readme-title:end -->";
23
+
24
+ const TOKENS = [
25
+ "__IDENTITY_ONE_LINER__",
26
+ "__DISTRIBUTION_CONTACT_URL__",
27
+ "__DISTRIBUTION_INTEGRATE_URL__",
28
+ "__DISTRIBUTION_REPO_URL__",
29
+ "__DISTRIBUTION_NPM_URL__",
30
+ "__OPENAPI_SELF_URL__",
31
+ "__SERVERS_ORIGIN__",
32
+ ];
33
+
34
+ /**
35
+ * @param {string} haystack
36
+ * @param {string} needle
37
+ */
38
+ function countOccurrences(haystack, needle) {
39
+ let n = 0;
40
+ let i = 0;
41
+ while (true) {
42
+ const j = haystack.indexOf(needle, i);
43
+ if (j === -1) break;
44
+ n++;
45
+ i = j + needle.length;
46
+ }
47
+ return n;
48
+ }
49
+
50
+ function validateOpenapiTemplate() {
51
+ const template = readFileSync(OPENAPI_IN, "utf8");
52
+ for (const tok of TOKENS) {
53
+ const c = countOccurrences(template, tok);
54
+ if (c !== 1) {
55
+ throw new Error(`openapi template: token ${tok} must appear exactly once, found ${c}`);
56
+ }
57
+ }
58
+ }
59
+
60
+ function escapeYamlDoubleQuotedOneLiner(s) {
61
+ return String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
62
+ }
63
+
64
+ /**
65
+ * @param {Record<string, unknown>} anchors
66
+ */
67
+ function distributionSsotBlobUrl(anchors) {
68
+ const u = String(anchors.gitRepositoryUrl);
69
+ const m = u.match(/github\.com\/([^/]+)\/([^/#?]+)/i);
70
+ if (!m) throw new Error("emit-primary-marketing: cannot derive SSOT blob URL from gitRepositoryUrl");
71
+ const repo = m[2].replace(/\.git$/i, "");
72
+ return `https://github.com/${m[1]}/${repo}/blob/main/docs/public-distribution.md`;
73
+ }
74
+
75
+ /**
76
+ * @param {string} line
77
+ * @param {string} origin
78
+ * @param {string} slug
79
+ */
80
+ function expandCliFooterLine(line, origin, slug) {
81
+ const acquisitionUrl = `${origin}${slug}`;
82
+ const integrateUrl = `${origin}/integrate`;
83
+ let out = String(line)
84
+ .replace(/\{\{ORIGIN\}\}/g, origin)
85
+ .replace(/\{\{ACQUISITION_URL\}\}/g, acquisitionUrl)
86
+ .replace(/\{\{INTEGRATE_URL\}\}/g, integrateUrl);
87
+ if (out.includes("{{")) {
88
+ throw new Error(`emit-primary-marketing: unresolved placeholder in cliFollowupLines: ${line}`);
89
+ }
90
+ return out;
91
+ }
92
+
93
+ /**
94
+ * @param {Record<string, unknown>} anchors
95
+ * @param {Record<string, unknown>} discovery
96
+ */
97
+ function writePublicDistributionGenerated(anchors, discovery) {
98
+ const ssotUrl = distributionSsotBlobUrl(anchors);
99
+ const origin = normalize(anchors.productionCanonicalOrigin);
100
+ const slug = String(discovery.slug);
101
+ const cliLines = /** @type {string[]} */ (discovery.cliFollowupLines);
102
+ const expanded = cliLines.map((l) => expandCliFooterLine(l, origin, slug));
103
+ expanded.push(`Distribution contract (SSOT): ${ssotUrl}`);
104
+ if (expanded.length > 6) {
105
+ throw new Error(
106
+ `emit-primary-marketing: distribution footer exceeds 6 lines (${expanded.length}); shorten cliFollowupLines`,
107
+ );
108
+ }
109
+ const returnParts = expanded.map((line) => `${JSON.stringify(`${line}\n`)}`);
110
+ const pkgRaw = readFileSync(PKG_PATH, "utf8");
111
+ const pkgJson = JSON.parse(pkgRaw);
112
+ const cliSemver = String(pkgJson.version ?? "").trim();
113
+ if (!cliSemver) {
114
+ throw new Error("emit-primary-marketing: package.json missing version");
115
+ }
116
+ const body = `// Generated by npm run emit-primary-marketing — do not hand edit.
117
+
118
+ export const PUBLIC_DISTRIBUTION_SSOT_BLOB_URL = ${JSON.stringify(ssotUrl)};
119
+
120
+ export const PUBLIC_CANONICAL_SITE_ORIGIN = ${JSON.stringify(origin)};
121
+
122
+ export const AGENTSKEPTIC_CLI_SEMVER = ${JSON.stringify(cliSemver)};
123
+
124
+ export function formatDistributionFooter(): string {
125
+ return ${returnParts.join("\n + ")};
126
+ }
127
+ `;
128
+ writeFileSync(join(ROOT, "src", "publicDistribution.generated.ts"), body, "utf8");
129
+ }
130
+
131
+ /**
132
+ * @param {Record<string, unknown>} anchors
133
+ * @param {Record<string, unknown>} discovery
134
+ */
135
+ function writeAgentsMd(anchors, discovery) {
136
+ const url = distributionSsotBlobUrl(anchors);
137
+ const origin = normalize(anchors.productionCanonicalOrigin);
138
+ const slug = String(discovery.slug);
139
+ const acquisitionUrl = `${origin}${slug}`;
140
+ const dp = require("./discovery-payload.lib.cjs");
141
+ const { owner, repo } = dp.parseGithubRepoFromUrl(String(anchors.gitRepositoryUrl));
142
+ const branch = dp.DISCOVERY_LLM_BRANCH;
143
+ const llmsRaw = `https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/${branch}/llms.txt`;
144
+ const openapiRaw = `https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/${branch}/schemas/openapi-commercial-v1.yaml`;
145
+ const body = `# AGENTS
146
+
147
+ Normative **public distribution** and anchor sync: [\`docs/public-distribution.md\`](docs/public-distribution.md) (same content as ${url}).
148
+
149
+ ## Machine-readable product entrypoints
150
+
151
+ - Committed \`llms.txt\` at repo root (same bytes as site \`/llms.txt\` after prebuild sync).
152
+ - Raw GitHub \`llms.txt\`: ${llmsRaw}
153
+ - OpenAPI YAML (repo raw): ${openapiRaw}
154
+ - Acquisition page (canonical): ${acquisitionUrl}
155
+ `;
156
+ writeFileSync(join(ROOT, "AGENTS.md"), body, "utf8");
157
+ }
158
+
159
+ function syncPrimaryMarketing() {
160
+ const discoveryLib = require("./discovery-acquisition.lib.cjs");
161
+ discoveryLib.validateDiscoveryAcquisition(ROOT);
162
+ const pm = discoveryLib.loadDiscoveryAcquisition(ROOT);
163
+ const anchors = pm;
164
+ const discovery = pm;
165
+
166
+ validateOpenapiTemplate();
167
+
168
+ const escaped = escapeYamlDoubleQuotedOneLiner(anchors.identityOneLiner);
169
+ const canonicalOrigin = normalize(anchors.productionCanonicalOrigin);
170
+ const openapiSelfCanonical = `${canonicalOrigin}/openapi-commercial-v1.yaml`;
171
+
172
+ const envUrl = process.env.NEXT_PUBLIC_APP_URL;
173
+ const effectivePublicOrigin =
174
+ typeof envUrl === "string" && envUrl.trim() ? envUrl.trim() : anchors.productionCanonicalOrigin;
175
+ const publicOriginNormalized = normalize(effectivePublicOrigin);
176
+ const openapiSelfEffective = `${publicOriginNormalized}/openapi-commercial-v1.yaml`;
177
+
178
+ const integrateUrl = `${canonicalOrigin}/integrate`;
179
+
180
+ const template = readFileSync(OPENAPI_IN, "utf8");
181
+ let mid = template;
182
+ mid = mid.replace("__IDENTITY_ONE_LINER__", escaped);
183
+ mid = mid.replace("__DISTRIBUTION_CONTACT_URL__", canonicalOrigin);
184
+ mid = mid.replace("__DISTRIBUTION_INTEGRATE_URL__", integrateUrl);
185
+ mid = mid.replace("__DISTRIBUTION_REPO_URL__", anchors.gitRepositoryUrl);
186
+ mid = mid.replace("__DISTRIBUTION_NPM_URL__", anchors.npmPackageUrl);
187
+
188
+ const repoYaml = mid
189
+ .replace("__SERVERS_ORIGIN__", canonicalOrigin)
190
+ .replace("__OPENAPI_SELF_URL__", openapiSelfCanonical);
191
+ writeFileSync(OPENAPI_OUT, repoYaml, "utf8");
192
+
193
+ mkdirSync(dirname(OPENAPI_PUBLIC), { recursive: true });
194
+ const publicYaml = mid
195
+ .replace("__SERVERS_ORIGIN__", publicOriginNormalized)
196
+ .replace("__OPENAPI_SELF_URL__", openapiSelfEffective);
197
+ writeFileSync(OPENAPI_PUBLIC, publicYaml, "utf8");
198
+
199
+ const discoveryPayload = require("./discovery-payload.lib.cjs");
200
+ const discoveryPayloadObj = discoveryPayload.buildDiscoveryPayload(ROOT);
201
+ const llmsNormalized = discoveryPayload.renderLlmsTextFromPayload(discoveryPayloadObj);
202
+
203
+ mkdirSync(dirname(LLMS_PUBLIC), { recursive: true });
204
+ writeFileSync(LLMS_PUBLIC, llmsNormalized, "utf8");
205
+ writeFileSync(LLMS_REPO_ROOT, llmsNormalized, "utf8");
206
+
207
+ const pkgRaw = readFileSync(PKG_PATH, "utf8");
208
+ const pkg = JSON.parse(pkgRaw);
209
+ pkg.description = String(discovery.pageMetadata.description);
210
+ pkg.repository = { type: "git", url: anchors.gitRepositoryGitUrl };
211
+ pkg.homepage = `${canonicalOrigin}${String(discovery.slug)}`;
212
+ pkg.bugs = { url: anchors.bugsUrl };
213
+ pkg.keywords = anchors.keywords;
214
+ writeFileSync(PKG_PATH, JSON.stringify(pkg, null, 2) + "\n", "utf8");
215
+
216
+ let readme = readFileSync(README_PATH, "utf8");
217
+ if (!readme.includes(DISCOVERY_README_TITLE_START) || !readme.includes(DISCOVERY_README_TITLE_END)) {
218
+ throw new Error("README.md must contain discovery-readme-title markers");
219
+ }
220
+ const titleBody = `# ${String(discovery.readmeTitle)}`;
221
+ const titleBlock = `${DISCOVERY_README_TITLE_START}\n${titleBody}\n${DISCOVERY_README_TITLE_END}`;
222
+ const titleRe = new RegExp(
223
+ `${DISCOVERY_README_TITLE_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${DISCOVERY_README_TITLE_END.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`,
224
+ );
225
+ if (!titleRe.test(readme)) {
226
+ throw new Error("README: could not match discovery-readme-title region");
227
+ }
228
+ readme = readme.replace(titleRe, titleBlock);
229
+
230
+ if (!readme.includes(DISCOVERY_README_START) || !readme.includes(DISCOVERY_README_END)) {
231
+ throw new Error("README.md must contain discovery-acquisition-fold markers");
232
+ }
233
+ const foldBody = discoveryLib.buildDiscoveryFoldBody(discovery, canonicalOrigin);
234
+ const discBlock = `${DISCOVERY_README_START}\n${foldBody}\n${DISCOVERY_README_END}`;
235
+ const discRe = new RegExp(
236
+ `${DISCOVERY_README_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${DISCOVERY_README_END.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`,
237
+ );
238
+ if (!discRe.test(readme)) {
239
+ throw new Error("README: could not match discovery-acquisition-fold region");
240
+ }
241
+ readme = readme.replace(discRe, discBlock);
242
+
243
+ if (!readme.includes(README_START) || !readme.includes(README_END)) {
244
+ throw new Error("README.md must contain public-product-anchors markers");
245
+ }
246
+ const pl = discoveryPayloadObj.links;
247
+ const inner = [
248
+ anchors.identityOneLiner,
249
+ "",
250
+ `- **Repository:** ${anchors.gitRepositoryUrl}`,
251
+ `- **npm package:** ${anchors.npmPackageUrl}`,
252
+ `- **Canonical site:** ${canonicalOrigin}`,
253
+ `- **Integrate:** ${integrateUrl}`,
254
+ `- **OpenAPI (canonical):** ${openapiSelfCanonical}`,
255
+ `- **llms.txt (agents, site):** ${canonicalOrigin}/llms.txt`,
256
+ `- **llms.txt (repo, raw):** ${pl.llmsRaw}`,
257
+ `- **llms.txt (repo, blob):** ${pl.llmsBlob}`,
258
+ "",
259
+ ].join("\n");
260
+ const block = `${README_START}\n${inner}\n${README_END}`;
261
+ const re = new RegExp(
262
+ `${README_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${README_END.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`,
263
+ );
264
+ if (!re.test(readme)) {
265
+ throw new Error("README: could not match public-product-anchors region");
266
+ }
267
+ readme = readme.replace(re, block);
268
+ writeFileSync(README_PATH, readme, "utf8");
269
+
270
+ writePublicDistributionGenerated(anchors, discovery);
271
+ writeAgentsMd(anchors, discovery);
272
+ }
273
+
274
+ function validateForCheck() {
275
+ const discoveryLib = require("./discovery-acquisition.lib.cjs");
276
+ discoveryLib.validateDiscoveryAcquisition(ROOT);
277
+ validateOpenapiTemplate();
278
+ const pm = JSON.parse(readFileSync(MARKETING_PATH, "utf8"));
279
+ const required = [
280
+ "identityOneLiner",
281
+ "productionCanonicalOrigin",
282
+ "gitRepositoryUrl",
283
+ "gitRepositoryGitUrl",
284
+ "npmPackageUrl",
285
+ "bugsUrl",
286
+ "keywords",
287
+ ];
288
+ for (const k of required) {
289
+ if (pm[k] === undefined || pm[k] === null) {
290
+ throw new Error(`marketing: missing ${k}`);
291
+ }
292
+ }
293
+ if (!Array.isArray(pm.keywords) || pm.keywords.length === 0) {
294
+ throw new Error("marketing: keywords must be a non-empty array");
295
+ }
296
+ }
297
+
298
+ function main() {
299
+ validateForCheck();
300
+ if (process.argv.includes("--check")) {
301
+ return;
302
+ }
303
+ syncPrimaryMarketing();
304
+ }
305
+
306
+ /** @deprecated use syncPrimaryMarketing */
307
+ const syncPublicProductAnchors = syncPrimaryMarketing;
308
+ /** @deprecated use validateForCheck */
309
+ const validateAnchors = validateForCheck;
310
+
311
+ module.exports = {
312
+ validateAnchors,
313
+ syncPublicProductAnchors,
314
+ syncPrimaryMarketing,
315
+ assertNextPublicOriginParity,
316
+ normalize,
317
+ };
318
+
319
+ if (require.main === module) {
320
+ try {
321
+ main();
322
+ } catch (e) {
323
+ console.error(e instanceof Error ? e.message : e);
324
+ process.exit(1);
325
+ }
326
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ const { readFileSync } = require("node:fs");
4
+ const { join } = require("node:path");
5
+
6
+ const ROOT = join(__dirname, "..");
7
+ const MARKETING_PATH = join(ROOT, "config", "marketing.json");
8
+
9
+ /**
10
+ * @param {string} s
11
+ */
12
+ function normalize(s) {
13
+ const t = String(s).trim();
14
+ if (!t) throw new Error("normalize: empty origin");
15
+ const u = new URL(t);
16
+ return u.origin;
17
+ }
18
+
19
+ function isLoopbackOrigin(raw) {
20
+ try {
21
+ const u = new URL(normalize(raw));
22
+ const h = u.hostname.toLowerCase();
23
+ return h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "[::1]";
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ function readProductionCanonicalOrigin() {
30
+ const pm = JSON.parse(readFileSync(MARKETING_PATH, "utf8"));
31
+ return String(pm.productionCanonicalOrigin);
32
+ }
33
+
34
+ function assertNextPublicOriginParity() {
35
+ const canonicalFromJson = readProductionCanonicalOrigin();
36
+ const skip = process.env.NODE_ENV !== "production" || process.env.VERCEL_ENV === "preview";
37
+ if (skip) return;
38
+ const url = String(process.env.NEXT_PUBLIC_APP_URL || "").trim();
39
+ if (!url) return;
40
+ if (normalize(url) !== normalize(canonicalFromJson)) {
41
+ if (process.env.VERCEL_ENV !== "production" && isLoopbackOrigin(url)) return;
42
+ throw new Error("NEXT_PUBLIC_APP_URL must equal productionCanonicalOrigin");
43
+ }
44
+ }
45
+
46
+ module.exports = {
47
+ normalize,
48
+ assertNextPublicOriginParity,
49
+ MARKETING_PATH,
50
+ /** @deprecated use MARKETING_PATH */
51
+ PRIMARY_MARKETING_PATH: MARKETING_PATH,
52
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ /** @deprecated Re-export — use `emit-primary-marketing.cjs` and `config/marketing.json`. */
3
+ module.exports = require("./emit-primary-marketing.cjs");
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+
3
+ const { readFileSync } = require("node:fs");
4
+ const { join } = require("node:path");
5
+
6
+ const BANNED = /\b(crossing success|PatternComplete|IntegrateSpine|Outcome Certificate|AC-)\b/i;
7
+
8
+ const URL_IN_TEXT = /https?:\/\/[^[\s<>"')]+/gi;
9
+
10
+ /**
11
+ * True if the string contains a URL whose host is GitHub (github.com or a subdomain).
12
+ * Uses URL parsing so substrings like "evil.com/.../github.com" do not false-positive.
13
+ * @param {string} s
14
+ */
15
+ function textContainsGithubHostUrl(s) {
16
+ for (const m of s.matchAll(URL_IN_TEXT)) {
17
+ try {
18
+ const { hostname } = new URL(m[0]);
19
+ if (hostname === "github.com" || hostname.endsWith(".github.com")) {
20
+ return true;
21
+ }
22
+ } catch {
23
+ // ignore invalid URL fragments
24
+ }
25
+ }
26
+ return false;
27
+ }
28
+
29
+ /**
30
+ * @param {string} root
31
+ */
32
+ function loadMarketing(root) {
33
+ const p = join(root, "config", "marketing.json");
34
+ return JSON.parse(readFileSync(p, "utf8"));
35
+ }
36
+
37
+ /**
38
+ * @param {string} s
39
+ */
40
+ function wordCount(s) {
41
+ return String(s)
42
+ .trim()
43
+ .split(/\s+/)
44
+ .filter(Boolean).length;
45
+ }
46
+
47
+ /**
48
+ * @param {Record<string, unknown>} m
49
+ */
50
+ function validateMarketingValue(m) {
51
+ if (m.schemaVersion !== 1) {
52
+ throw new Error("marketing: schemaVersion must be 1");
53
+ }
54
+ const required = [
55
+ "slug",
56
+ "identityOneLiner",
57
+ "productionCanonicalOrigin",
58
+ "gitRepositoryUrl",
59
+ "gitRepositoryGitUrl",
60
+ "npmPackageUrl",
61
+ "bugsUrl",
62
+ "keywords",
63
+ "heroTitle",
64
+ "heroSubtitle",
65
+ "visitorProblemAnswer",
66
+ "heroOutcome",
67
+ "heroMechanism",
68
+ "guaranteeFootnote",
69
+ "pageMetadata",
70
+ "readmeFold",
71
+ "shareableTerminalDemo",
72
+ "cliFollowupLines",
73
+ "r2",
74
+ "site",
75
+ "integratePage",
76
+ "problemIndex",
77
+ "llms",
78
+ ];
79
+ for (const k of required) {
80
+ if (m[k] === undefined || m[k] === null) {
81
+ throw new Error(`marketing: missing required key ${k}`);
82
+ }
83
+ }
84
+ if (!Array.isArray(m.keywords) || m.keywords.length === 0) {
85
+ throw new Error("marketing: keywords must be a non-empty array");
86
+ }
87
+ const ho = String(m.heroOutcome);
88
+ if (wordCount(ho) > 20) {
89
+ throw new Error(`marketing: heroOutcome must be at most 20 words (got ${wordCount(ho)})`);
90
+ }
91
+ if (String(m.heroMechanism).length > 200) {
92
+ throw new Error("marketing: heroMechanism must be at most 200 characters");
93
+ }
94
+ for (const field of [ho, String(m.heroMechanism)]) {
95
+ if (BANNED.test(field)) {
96
+ throw new Error(`marketing: banned term in home hero text: ${field.slice(0, 80)}`);
97
+ }
98
+ }
99
+ const g = String(m.guaranteeFootnote);
100
+ if (!g.toLowerCase().includes("read-only")) {
101
+ throw new Error("marketing: guaranteeFootnote must mention read-only");
102
+ }
103
+ if (textContainsGithubHostUrl(g)) {
104
+ throw new Error("marketing: guaranteeFootnote must not include a GitHub URL (site-local copy only)");
105
+ }
106
+ if (g.toLowerCase().includes("causality")) {
107
+ throw new Error("marketing: guaranteeFootnote must not contain the word causality");
108
+ }
109
+ const cmd = String(m.integratePage.packLedCommand);
110
+ if (!cmd.includes("agentskeptic crossing")) {
111
+ throw new Error("marketing: packLedCommand must include agentskeptic crossing");
112
+ }
113
+ if (!cmd.includes("--events")) {
114
+ throw new Error("marketing: packLedCommand must be pack-led (--events)");
115
+ }
116
+ if (!cmd.includes("tools.json")) {
117
+ throw new Error("marketing: packLedCommand must reference tools.json");
118
+ }
119
+ if (!Array.isArray(m.integratePage.requirements) || m.integratePage.requirements.length < 1) {
120
+ throw new Error("marketing: integratePage.requirements must be a non-empty array");
121
+ }
122
+ if (m.integratePage.requirements.length < 1 || m.integratePage.requirements.length > 5) {
123
+ throw new Error("marketing: integratePage.requirements must have 1–5 items");
124
+ }
125
+ const v = String(m.visitorProblemAnswer);
126
+ if (v.toLowerCase().includes("causality")) {
127
+ throw new Error("marketing: visitorProblemAnswer must not contain causality");
128
+ }
129
+ const demo = m.shareableTerminalDemo;
130
+ if (demo && String(demo.transcript).includes("```")) {
131
+ throw new Error("marketing: shareableTerminalDemo.transcript must not contain ```");
132
+ }
133
+ if (!m.readmeFold || !Array.isArray(m.readmeFold.templateLines)) {
134
+ throw new Error("marketing: readmeFold.templateLines required");
135
+ }
136
+ return m;
137
+ }
138
+
139
+ /**
140
+ * @param {string} root
141
+ */
142
+ function validateMarketing(root) {
143
+ return validateMarketingValue(loadMarketing(root));
144
+ }
145
+
146
+ if (require.main === module) {
147
+ try {
148
+ validateMarketing(join(__dirname, ".."));
149
+ process.exit(0);
150
+ } catch (e) {
151
+ console.error(e instanceof Error ? e.message : e);
152
+ process.exit(1);
153
+ }
154
+ }
155
+
156
+ module.exports = { validateMarketing, validateMarketingValue, loadMarketing };