@usefragments/core 1.10.2 → 1.11.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/dist/{chunk-MZ4SW3TP.js → chunk-3IOWHECM.js} +8 -1
- package/dist/{chunk-MZ4SW3TP.js.map → chunk-3IOWHECM.js.map} +1 -1
- package/dist/chunk-7ULGH74M.js +66 -0
- package/dist/chunk-7ULGH74M.js.map +1 -0
- package/dist/{chunk-YF65VYRY.js → chunk-ML5S6QNU.js} +191 -169
- package/dist/chunk-ML5S6QNU.js.map +1 -0
- package/dist/chunk-PWIJMOI4.js +202 -0
- package/dist/chunk-PWIJMOI4.js.map +1 -0
- package/dist/{chunk-XN3LSDPY.js → chunk-RPSEABY3.js} +622 -344
- package/dist/chunk-RPSEABY3.js.map +1 -0
- package/dist/chunk-RYFULE43.js +578 -0
- package/dist/chunk-RYFULE43.js.map +1 -0
- package/dist/codes/index.d.ts +2 -2
- package/dist/codes/index.js +3 -2
- package/dist/compiled-types/index.d.ts +327 -2
- package/dist/compiled-types/index.js +1 -1
- package/dist/generate/index.d.ts +3 -2
- package/dist/{governance-CLk_wkP9.d.ts → governance-BAsy1k2H.d.ts} +472 -513
- package/dist/governance-telemetry.d.ts +6 -0
- package/dist/governance-telemetry.js +1 -1
- package/dist/{index-_sxhUNqx.d.ts → index-C8bcXVav.d.ts} +448 -448
- package/dist/index.d.ts +9165 -1297
- package/dist/index.js +3041 -350
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +228 -0
- package/dist/manifest.js +24 -0
- package/dist/manifest.js.map +1 -0
- package/dist/preview/index.js +45 -1
- package/dist/preview/index.js.map +1 -1
- package/dist/preview-runtime.d.ts +1 -2
- package/dist/preview-runtime.js +150 -14
- package/dist/preview-runtime.js.map +1 -1
- package/dist/react-types.d.ts +1 -2
- package/dist/registry.d.ts +1412 -203
- package/dist/registry.js +30 -3
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +3 -2
- package/dist/storyAdapter.d.ts +1 -2
- package/dist/storyAdapter.js +11 -49
- package/dist/storyAdapter.js.map +1 -1
- package/dist/test-utils.d.ts +3 -2
- package/package.json +8 -2
- package/src/__tests__/contract-parser.test.ts +318 -277
- package/src/__tests__/preview-runtime-hook.test.tsx +315 -0
- package/src/__tests__/preview-runtime.test.tsx +30 -8
- package/src/__tests__/schema.test.ts +191 -14
- package/src/analysis-plan/analysis-plan-v1.test.ts +320 -0
- package/src/analysis-plan/coverage.ts +181 -0
- package/src/analysis-plan/digest.ts +141 -0
- package/src/analysis-plan/index.ts +34 -0
- package/src/analysis-plan/types.ts +207 -0
- package/src/codes/__tests__/codes.test.ts +9 -0
- package/src/codes/codes.ts +30 -0
- package/src/compiled-types/index.ts +640 -39
- package/src/compiled-types/parse.test.ts +145 -4
- package/src/component-contract.ts +95 -53
- package/src/composition.ts +7 -13
- package/src/constants.ts +3 -6
- package/src/contract/hash.test.ts +20 -0
- package/src/contract/hash.ts +66 -9
- package/src/contract/index.ts +24 -1
- package/src/contract/manifest.test.ts +94 -0
- package/src/contract/manifest.ts +68 -0
- package/src/contract/preimage.test.ts +219 -1
- package/src/contract/preimage.ts +326 -6
- package/src/contract/stamp.test.ts +3 -0
- package/src/contract/stamp.ts +1 -1
- package/src/contract-parser.ts +54 -30
- package/src/defineFragment.test.ts +476 -91
- package/src/defineFragment.ts +204 -114
- package/src/domain-ids.test.ts +52 -0
- package/src/domain-ids.ts +106 -0
- package/src/evaluation/evaluate.test.ts +522 -0
- package/src/evaluation/evaluate.ts +680 -0
- package/src/evaluation/evaluation-v2-receipt-v1.test.ts +760 -0
- package/src/evaluation/index.ts +58 -0
- package/src/evaluation/receipt.ts +753 -0
- package/src/evaluation/types.ts +406 -0
- package/src/facts/builders.ts +2 -0
- package/src/facts/compile.ts +29 -6
- package/src/facts/fact-index.ts +13 -3
- package/src/facts/fact-integrity-v1.test.ts +172 -0
- package/src/facts/facts.test.ts +15 -0
- package/src/facts/ids.ts +46 -3
- package/src/facts/index.ts +14 -1
- package/src/facts/integrity.ts +134 -0
- package/src/facts/types.ts +36 -0
- package/src/feature-plan/digest.ts +217 -0
- package/src/feature-plan/feature-plan-v1.test.ts +529 -0
- package/src/feature-plan/index.ts +65 -0
- package/src/feature-plan/types.ts +628 -0
- package/src/governance-integrity.test.ts +1 -0
- package/src/governance-integrity.ts +5 -3
- package/src/governance-telemetry.ts +8 -0
- package/src/governance.ts +52 -8
- package/src/index.ts +299 -37
- package/src/preview/validation.test.ts +62 -0
- package/src/preview/validation.ts +48 -2
- package/src/preview-runtime.tsx +227 -20
- package/src/registry-install-plan.ts +200 -109
- package/src/registry-shards.test.ts +263 -0
- package/src/registry.ts +237 -0
- package/src/repository-binding.test.ts +50 -0
- package/src/repository-binding.ts +96 -0
- package/src/rules/families.test.ts +36 -0
- package/src/rules/finding.ts +7 -2
- package/src/rules/index.ts +17 -1
- package/src/rules/rule-config.test.ts +66 -0
- package/src/rules/rule-config.ts +73 -0
- package/src/rules/rules.test.ts +26 -0
- package/src/rules/tokens-css-vars-must-be-defined.test.ts +51 -2
- package/src/rules/tokens-css-vars-must-be-defined.ts +34 -1
- package/src/schema.ts +293 -113
- package/src/schemas/index.ts +1 -1
- package/src/storyAdapter.test.ts +68 -12
- package/src/storyAdapter.ts +44 -75
- package/src/types.ts +258 -37
- package/dist/chunk-RANPUC6C.js +0 -72
- package/dist/chunk-RANPUC6C.js.map +0 -1
- package/dist/chunk-XN3LSDPY.js.map +0 -1
- package/dist/chunk-YF65VYRY.js.map +0 -1
- package/src/fragment-types.ts +0 -214
- package/src/react-create-element.test.ts +0 -22
- package/src/react-create-element.ts +0 -12
- package/src/storyFilters.test.ts +0 -350
- package/src/storyFilters.ts +0 -253
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/registry.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { portableRepoPathError } from \"./config-paths.js\";\nimport { canonicalPreimage, contractHash, sha256Hex } from \"./contract/hash.js\";\n\nexport const REGISTRY_MANIFEST_SCHEMA_VERSION = \"fragments.registry.v1\";\nexport const REGISTRY_ARTIFACT_SCHEMA_VERSION = \"fragments.registry-artifact.v1\";\nexport const REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION = \"fragments.registry-lock.v1\";\n\nconst sha256Schema = z.string().regex(/^[0-9a-f]{64}$/);\n\nconst registryPathSchema = z\n .string()\n .min(1)\n .superRefine((value, ctx) => {\n const error = portableRepoPathError(value);\n if (error) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: error });\n }\n });\n\nconst registryFilePathSchema = registryPathSchema.superRefine((value, ctx) => {\n if (value === \".\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"File path must point to a file, not the package root\",\n });\n }\n});\n\nexport const registryDependencyTypeSchema = z.enum([\"runtime\", \"peer\", \"dev\", \"optional\"]);\n\nexport const registryDependencySchema = z.object({\n name: z.string().min(1),\n versionRange: z.string().min(1),\n type: registryDependencyTypeSchema,\n optional: z.boolean().optional(),\n});\n\nexport const registryFileRoleSchema = z.enum([\n \"source\",\n \"style\",\n \"token\",\n \"contract\",\n \"test\",\n \"story\",\n \"example\",\n \"asset\",\n \"barrel\",\n \"metadata\",\n]);\n\nexport const registryFileSchema = z.object({\n path: registryFilePathSchema,\n role: registryFileRoleSchema,\n sha256: sha256Schema,\n size: z.number().int().nonnegative(),\n contentType: z.string().min(1),\n contentRef: z.string().min(1),\n});\n\nexport const registryFileContentSchema = z.object({\n path: registryFilePathSchema,\n content: z.string(),\n sha256: sha256Schema,\n size: z.number().int().nonnegative(),\n contentType: z.string().min(1),\n});\n\nexport const registrySourceSchema = z.discriminatedUnion(\"kind\", [\n z.object({\n kind: z.literal(\"package\"),\n packageName: z.string().min(1),\n version: z.string().optional(),\n rootPath: registryPathSchema.optional(),\n commitSha: z.string().optional(),\n }),\n z.object({\n kind: z.literal(\"github\"),\n repoFullName: z.string().min(1),\n commitSha: z.string().min(1),\n path: registryPathSchema.optional(),\n }),\n z.object({\n kind: z.literal(\"local\"),\n rootPath: registryPathSchema.optional(),\n commitSha: z.string().optional(),\n }),\n z.object({\n kind: z.literal(\"manual\"),\n label: z.string().min(1),\n }),\n]);\n\nexport const registryComponentExportSchema = z.object({\n name: z.string().min(1),\n kind: z.enum([\"component\", \"hook\", \"utility\", \"type\", \"style\"]).default(\"component\"),\n path: registryFilePathSchema.optional(),\n});\n\nexport const registryComponentSchema = z.object({\n componentId: z.string().min(1),\n publicRef: z.string().min(1),\n name: z.string().min(1),\n status: z.string().min(1).default(\"stable\"),\n tier: z.enum([\"core\", \"composition\", \"utility\", \"custom\"]).default(\"core\"),\n category: z.string().optional(),\n files: z.array(registryFileSchema).min(1),\n styleFiles: z.array(registryFilePathSchema).default([]),\n tokenDependencies: z.array(z.string().min(1)).default([]),\n runtimeDependencies: z.array(registryDependencySchema).default([]),\n peerDependencies: z.array(registryDependencySchema).default([]),\n internalDependencies: z.array(z.string().min(1)).default([]),\n exports: z.array(registryComponentExportSchema).default([]),\n contract: z.unknown().optional(),\n examples: z.array(z.unknown()).default([]),\n provenance: z.record(z.unknown()).default({}),\n});\n\nexport const registryEntrypointSchema = z.object({\n specifier: z.string().min(1),\n sourcePath: registryFilePathSchema,\n});\n\nexport const registryInstallProfileSchema = z.object({\n name: z.string().min(1),\n targetPath: registryPathSchema,\n importPath: z.string().min(1),\n stylePath: registryPathSchema.optional(),\n includeTests: z.boolean().default(false),\n});\n\nconst registryManifestBaseSchema = z.object({\n schemaVersion: z.literal(REGISTRY_MANIFEST_SCHEMA_VERSION),\n registryId: z.string().min(1),\n name: z.string().min(1),\n channel: z.string().min(1),\n version: z.string().min(1),\n contractVersionId: z.string().optional(),\n fcid: sha256Schema.optional(),\n generatedAt: z.string().datetime(),\n source: registrySourceSchema,\n packageFiles: z.array(registryFileSchema).default([]),\n /** Files every install writes, whatever the selection: the stylesheet entry and its closure. */\n baseFiles: z.array(registryFileSchema).default([]),\n entrypoints: z.array(registryEntrypointSchema).default([]),\n components: z.record(z.string(), registryComponentSchema),\n dependencies: z.array(registryDependencySchema).default([]),\n installProfiles: z.array(registryInstallProfileSchema).default([]),\n});\n\nexport const registryManifestDraftSchema = registryManifestBaseSchema;\n\nexport const registryManifestSchema = registryManifestBaseSchema.extend({\n registryHash: sha256Schema,\n});\n\nexport const registryArtifactSchema = z\n .object({\n schemaVersion: z.literal(REGISTRY_ARTIFACT_SCHEMA_VERSION),\n manifest: registryManifestSchema,\n files: z.record(registryFilePathSchema, registryFileContentSchema),\n })\n .superRefine((artifact, ctx) => {\n const filesByPath = artifact.files;\n for (const [path, content] of Object.entries(filesByPath)) {\n if (content.path !== path) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", path, \"path\"],\n message: `Registry file map key ${path} does not match content path ${content.path}`,\n });\n }\n }\n\n const manifestFiles = [\n ...artifact.manifest.packageFiles,\n ...artifact.manifest.baseFiles,\n ...artifact.manifest.entrypoints.map((entrypoint) => ({\n path: entrypoint.sourcePath,\n role: \"barrel\" as const,\n sha256: filesByPath[entrypoint.sourcePath]?.sha256 ?? \"\",\n size: filesByPath[entrypoint.sourcePath]?.size ?? 0,\n contentType: filesByPath[entrypoint.sourcePath]?.contentType ?? \"text/plain\",\n contentRef: `sha256:${filesByPath[entrypoint.sourcePath]?.sha256 ?? \"\"}`,\n })),\n ...Object.values(artifact.manifest.components).flatMap((component) => component.files),\n ];\n\n for (const file of manifestFiles) {\n const content = filesByPath[file.path];\n if (!content) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", file.path],\n message: `Missing content for registry file ${file.path}`,\n });\n continue;\n }\n if (content.sha256 !== file.sha256) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", file.path, \"sha256\"],\n message: `Content hash for ${file.path} does not match manifest`,\n });\n }\n if (content.size !== file.size) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", file.path, \"size\"],\n message: `Content size for ${file.path} does not match manifest`,\n });\n }\n }\n });\n\nexport const registryInstallReceiptFileSchema = z.object({\n path: registryFilePathSchema,\n sha256: sha256Schema,\n sourcePath: registryFilePathSchema,\n componentId: z.string().min(1).optional(),\n});\n\nexport const registryInstallReceiptComponentSchema = z.object({\n componentId: z.string().min(1),\n publicRef: z.string().min(1),\n name: z.string().min(1),\n files: z.array(registryFilePathSchema),\n});\n\nexport const registryInstallReceiptSchema = z.object({\n schemaVersion: z.literal(REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION),\n registryId: z.string().min(1),\n registryVersion: z.string().min(1),\n registryHash: sha256Schema,\n fcid: sha256Schema.optional(),\n channel: z.string().min(1).optional(),\n targetPath: registryPathSchema,\n importPath: z.string().min(1),\n installedComponents: z.array(registryInstallReceiptComponentSchema),\n files: z.array(registryInstallReceiptFileSchema),\n dependencies: z.array(registryDependencySchema).default([]),\n installedAt: z.string().datetime(),\n});\n\nexport type RegistryDependencyType = z.infer<typeof registryDependencyTypeSchema>;\nexport type RegistryDependency = z.infer<typeof registryDependencySchema>;\nexport type RegistryFileRole = z.infer<typeof registryFileRoleSchema>;\nexport type RegistryFile = z.infer<typeof registryFileSchema>;\nexport type RegistryFileContent = z.infer<typeof registryFileContentSchema>;\nexport type RegistrySource = z.infer<typeof registrySourceSchema>;\nexport type RegistryComponentExport = z.infer<typeof registryComponentExportSchema>;\nexport type RegistryComponent = z.infer<typeof registryComponentSchema>;\nexport type RegistryEntrypoint = z.infer<typeof registryEntrypointSchema>;\nexport type RegistryInstallProfile = z.infer<typeof registryInstallProfileSchema>;\nexport type RegistryManifestDraft = z.input<typeof registryManifestDraftSchema>;\nexport type RegistryManifest = z.infer<typeof registryManifestSchema>;\nexport type RegistryArtifact = z.infer<typeof registryArtifactSchema>;\nexport type RegistryInstallReceiptFile = z.infer<typeof registryInstallReceiptFileSchema>;\nexport type RegistryInstallReceiptComponent = z.infer<typeof registryInstallReceiptComponentSchema>;\nexport type RegistryInstallReceipt = z.infer<typeof registryInstallReceiptSchema>;\n\nexport interface RegistryFileInput {\n path: string;\n role: RegistryFileRole;\n content: string;\n contentType: string;\n contentRef?: string;\n}\n\nexport interface RegistryArtifactInput {\n manifest: RegistryManifestDraft;\n files: readonly RegistryFileContent[];\n}\n\nfunction registryHashPayload(manifest: RegistryManifestDraft | RegistryManifest): unknown {\n const { generatedAt: _generatedAt, ...withoutGeneratedAt } = manifest;\n if (\"registryHash\" in withoutGeneratedAt) {\n const { registryHash: _registryHash, ...withoutHash } = withoutGeneratedAt;\n return withoutHash;\n }\n return withoutGeneratedAt;\n}\n\nexport function computeRegistryHash(manifest: RegistryManifestDraft | RegistryManifest): string {\n return contractHash(registryHashPayload(manifest));\n}\n\nexport function finalizeRegistryManifest(input: RegistryManifestDraft): RegistryManifest {\n const draft = registryManifestDraftSchema.parse(input);\n return registryManifestSchema.parse({\n ...draft,\n registryHash: computeRegistryHash(draft),\n });\n}\n\nexport function hashRegistryFileContent(content: string): string {\n return sha256Hex(content);\n}\n\nexport function registryFileSize(content: string): number {\n return new TextEncoder().encode(content).length;\n}\n\nexport function buildRegistryFile(input: RegistryFileInput): {\n metadata: RegistryFile;\n content: RegistryFileContent;\n} {\n const sha256 = hashRegistryFileContent(input.content);\n const size = registryFileSize(input.content);\n const path = registryFilePathSchema.parse(input.path);\n const contentType = z.string().min(1).parse(input.contentType);\n return {\n metadata: registryFileSchema.parse({\n path,\n role: input.role,\n sha256,\n size,\n contentType,\n contentRef: input.contentRef ?? `sha256:${sha256}`,\n }),\n content: registryFileContentSchema.parse({\n path,\n content: input.content,\n sha256,\n size,\n contentType,\n }),\n };\n}\n\nexport function buildRegistryArtifact(input: RegistryArtifactInput): RegistryArtifact {\n const manifest = finalizeRegistryManifest(input.manifest);\n const files = new Map<string, RegistryFileContent>();\n for (const file of input.files) {\n const content = registryFileContentSchema.parse(file);\n if (files.has(content.path)) {\n throw new Error(`Duplicate registry file content for ${content.path}`);\n }\n files.set(content.path, content);\n }\n\n return registryArtifactSchema.parse({\n schemaVersion: REGISTRY_ARTIFACT_SCHEMA_VERSION,\n manifest,\n files: Object.fromEntries(files),\n });\n}\n\nexport function assertValidRegistryArtifact(artifact: unknown): RegistryArtifact {\n return registryArtifactSchema.parse(artifact);\n}\n\nexport function registryArtifactDigest(artifact: RegistryArtifact): string {\n const files = Object.fromEntries(\n Object.entries(artifact.files)\n .map(([path, file]) => [path, { sha256: file.sha256, size: file.size }] as const)\n .sort(([leftPath], [rightPath]) => leftPath.localeCompare(rightPath))\n );\n\n return contractHash({\n schemaVersion: artifact.schemaVersion,\n manifest: registryHashPayload(artifact.manifest),\n files,\n });\n}\n\nexport function registryManifestCanonicalPreimage(\n manifest: RegistryManifestDraft | RegistryManifest\n): string {\n return canonicalPreimage(registryHashPayload(manifest));\n}\n\n// ============================================================================\n// Sharded artifact (schema v2): index without bodies + content shards\n// ============================================================================\n\nexport const REGISTRY_INDEX_SCHEMA_VERSION = \"fragments.registry-index.v2\";\nexport const REGISTRY_SHARD_SCHEMA_VERSION = \"fragments.registry-shard.v2\";\n\nconst registryShardPathSchema = registryFilePathSchema.superRefine((value, ctx) => {\n if (!value.endsWith(\".json\")) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: \"Shard path must end with .json\" });\n }\n});\n\nexport const registryShardSchema = z\n .object({\n schemaVersion: z.literal(REGISTRY_SHARD_SCHEMA_VERSION),\n files: z.record(z.string().min(1), registryFileContentSchema),\n })\n .superRefine((shard, ctx) => {\n for (const [contentRef, file] of Object.entries(shard.files)) {\n if (contentRef !== `sha256:${file.sha256}`) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"files\", contentRef],\n message: `Shard key ${contentRef} does not match content hash of ${file.path}`,\n });\n }\n }\n });\n\nexport const registryIndexSchema = z\n .object({\n schemaVersion: z.literal(REGISTRY_INDEX_SCHEMA_VERSION),\n manifest: registryManifestSchema,\n /** Shard path (relative to the index) → registry file paths whose bodies it carries. */\n shards: z.record(registryShardPathSchema, z.array(registryFilePathSchema).min(1)),\n })\n .superRefine((index, ctx) => {\n const owner = new Map<string, string>();\n for (const [shardPath, paths] of Object.entries(index.shards)) {\n for (const path of paths) {\n const existing = owner.get(path);\n if (existing) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"shards\", shardPath],\n message: `Registry file ${path} is listed in both ${existing} and ${shardPath}`,\n });\n }\n owner.set(path, shardPath);\n }\n }\n for (const path of registryManifestFilePaths(index.manifest)) {\n if (!owner.has(path)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"shards\"],\n message: `Registry file ${path} is not carried by any shard`,\n });\n }\n }\n });\n\n/**\n * A short-lived pointer (`latest.json`) to an immutable versioned index. One hop only;\n * `index` is a relative path so the hop cannot leave the pointer's origin.\n */\nexport const REGISTRY_POINTER_SCHEMA_VERSION = \"fragments.registry-pointer.v1\";\n\nexport const registryPointerSchema = z.object({\n schemaVersion: z.literal(REGISTRY_POINTER_SCHEMA_VERSION),\n registryId: z.string().min(1),\n version: z.string().min(1),\n registryHash: sha256Schema,\n index: registryShardPathSchema,\n generatedAt: z.string().datetime(),\n});\n\nexport type RegistryShard = z.infer<typeof registryShardSchema>;\nexport type RegistryIndex = z.infer<typeof registryIndexSchema>;\nexport type RegistryPointer = z.infer<typeof registryPointerSchema>;\n\nexport function buildRegistryPointer(index: RegistryIndex, indexPath: string): RegistryPointer {\n return registryPointerSchema.parse({\n schemaVersion: REGISTRY_POINTER_SCHEMA_VERSION,\n registryId: index.manifest.registryId,\n version: index.manifest.version,\n registryHash: index.manifest.registryHash,\n index: indexPath,\n generatedAt: index.manifest.generatedAt,\n });\n}\n\n/** Every file path the manifest references, sorted and unique. */\nexport function registryManifestFilePaths(manifest: RegistryManifest): string[] {\n return [...registryManifestFileMetadata(manifest).keys()].sort((left, right) =>\n left.localeCompare(right)\n );\n}\n\n/** Path → metadata for every manifest file; entrypoint-only paths map to `null`. */\nexport function registryManifestFileMetadata(\n manifest: RegistryManifest\n): Map<string, RegistryFile | null> {\n const files = new Map<string, RegistryFile | null>();\n const add = (file: RegistryFile) => {\n if (!files.get(file.path)) files.set(file.path, file);\n };\n manifest.packageFiles.forEach(add);\n manifest.baseFiles.forEach(add);\n for (const component of Object.values(manifest.components)) component.files.forEach(add);\n for (const entrypoint of manifest.entrypoints) {\n if (!files.has(entrypoint.sourcePath)) files.set(entrypoint.sourcePath, null);\n }\n return files;\n}\n\n/**\n * Default shard layout: one shard per component directory, one shard per shared\n * top-level directory under `src/` (`shared/tokens.json`, `shared/utils.json`, …),\n * `shared/src.json` for files directly under `src/`, and `shared/package.json` for\n * package-root files (`package.json`, `fragments.json`) that only complete installs need.\n */\nexport function defaultRegistryShardPath(path: string): string {\n const componentMatch = /^src\\/components\\/([^/]+)\\//.exec(path);\n if (componentMatch) return `components/${componentMatch[1]}.json`;\n if (!path.startsWith(\"src/\")) return \"shared/package.json\";\n const segments = path.slice(\"src/\".length).split(\"/\");\n return segments.length > 1 ? `shared/${segments[0]}.json` : \"shared/src.json\";\n}\n\nexport interface ShardedRegistryArtifact {\n index: RegistryIndex;\n shards: Map<string, RegistryShard>;\n}\n\nfunction shardKeyFor(metadata: RegistryFile | null | undefined, sha256: string): string {\n return metadata?.contentRef ?? `sha256:${sha256}`;\n}\n\nexport function shardRegistryArtifact(\n artifact: RegistryArtifact,\n shardPathFor: (path: string) => string = defaultRegistryShardPath\n): ShardedRegistryArtifact {\n const metadata = registryManifestFileMetadata(artifact.manifest);\n const shards = new Map<string, RegistryShard>();\n const shardPaths: Record<string, string[]> = {};\n\n for (const [path, content] of Object.entries(artifact.files).sort(([left], [right]) =>\n left.localeCompare(right)\n )) {\n const shardPath = shardPathFor(path);\n const shard = shards.get(shardPath) ?? {\n schemaVersion: REGISTRY_SHARD_SCHEMA_VERSION,\n files: {},\n };\n shard.files[shardKeyFor(metadata.get(path), content.sha256)] = content;\n shards.set(shardPath, shard);\n (shardPaths[shardPath] ??= []).push(path);\n }\n\n const index = registryIndexSchema.parse({\n schemaVersion: REGISTRY_INDEX_SCHEMA_VERSION,\n manifest: artifact.manifest,\n shards: shardPaths,\n });\n for (const [path, shard] of shards) shards.set(path, registryShardSchema.parse(shard));\n return { index, shards };\n}\n\nfunction shardOwnerMap(index: RegistryIndex): Map<string, string> {\n const owner = new Map<string, string>();\n for (const [shardPath, paths] of Object.entries(index.shards)) {\n for (const path of paths) owner.set(path, shardPath);\n }\n return owner;\n}\n\n/** The shards (sorted, unique) that carry the given registry file paths. */\nexport function registryShardsForPaths(index: RegistryIndex, paths: readonly string[]): string[] {\n const owner = shardOwnerMap(index);\n const shards = new Set<string>();\n for (const path of paths) {\n const shardPath = owner.get(path);\n if (!shardPath) throw new Error(`Registry index has no shard for ${path}`);\n shards.add(shardPath);\n }\n return [...shards].sort((left, right) => left.localeCompare(right));\n}\n\n/**\n * Rebuild a v1-shaped artifact from an index plus the shards that cover `paths`.\n * Only the requested paths are materialised; every body is checked against the\n * manifest's hash and size before it is accepted.\n */\nexport function assembleRegistryArtifact(args: {\n index: RegistryIndex;\n shards: ReadonlyMap<string, RegistryShard>;\n paths: readonly string[];\n}): RegistryArtifact {\n const metadata = registryManifestFileMetadata(args.index.manifest);\n const owner = shardOwnerMap(args.index);\n const files: Record<string, RegistryFileContent> = {};\n\n for (const path of [...new Set(args.paths)].sort((left, right) => left.localeCompare(right))) {\n const shardPath = owner.get(path);\n if (!shardPath) throw new Error(`Registry index has no shard for ${path}`);\n const shard = args.shards.get(shardPath);\n if (!shard) throw new Error(`Registry shard ${shardPath} was not loaded (needed for ${path})`);\n const expected = metadata.get(path) ?? null;\n const content = expected\n ? shard.files[expected.contentRef]\n : Object.values(shard.files).find((file) => file.path === path);\n if (!content || content.path !== path) {\n throw new Error(`Registry shard ${shardPath} is missing content for ${path}`);\n }\n // Re-hash the body: a shard's own sha256/size fields are claims, the index is the truth.\n const actualSha256 = hashRegistryFileContent(content.content);\n const actualSize = registryFileSize(content.content);\n const expectedSha256 = expected?.sha256 ?? content.sha256;\n const expectedSize = expected?.size ?? content.size;\n if (actualSha256 !== expectedSha256 || actualSize !== expectedSize) {\n throw new Error(`Registry shard ${shardPath} content for ${path} does not match the index`);\n }\n files[path] = content;\n }\n\n return {\n schemaVersion: REGISTRY_ARTIFACT_SCHEMA_VERSION,\n manifest: args.index.manifest,\n files,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// src/contract/hash.ts
|
|
2
|
+
function normalizeNumber(value) {
|
|
3
|
+
if (Number.isNaN(value)) return '"@num:nan"';
|
|
4
|
+
if (value === Infinity) return '"@num:+inf"';
|
|
5
|
+
if (value === -Infinity) return '"@num:-inf"';
|
|
6
|
+
if (Object.is(value, -0)) return "0";
|
|
7
|
+
return JSON.stringify(value);
|
|
8
|
+
}
|
|
9
|
+
function canonicalPreimage(value) {
|
|
10
|
+
return canonicalPreimageValue(value, /* @__PURE__ */ new Set(), "(root)");
|
|
11
|
+
}
|
|
12
|
+
function compareCanonicalStrings(left, right) {
|
|
13
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
14
|
+
}
|
|
15
|
+
function canonicalPreimageValue(value, ancestors, path) {
|
|
16
|
+
if (value === void 0 || value === null) return "null";
|
|
17
|
+
const type = typeof value;
|
|
18
|
+
if (type === "number") return normalizeNumber(value);
|
|
19
|
+
if (type === "string" || type === "boolean") return JSON.stringify(value);
|
|
20
|
+
if (type === "bigint") return JSON.stringify(value.toString());
|
|
21
|
+
if (type === "function" || type === "symbol") {
|
|
22
|
+
throw new TypeError(`Unsupported contract value at ${path}: ${type}`);
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
if (ancestors.has(value)) throw new TypeError(`Circular contract value at ${path}`);
|
|
26
|
+
ancestors.add(value);
|
|
27
|
+
try {
|
|
28
|
+
return `[${value.map((entry, index) => canonicalPreimageValue(entry, ancestors, `${path}[${index}]`)).join(",")}]`;
|
|
29
|
+
} finally {
|
|
30
|
+
ancestors.delete(value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (type !== "object") {
|
|
34
|
+
throw new TypeError(`Unsupported contract value at ${path}: ${type}`);
|
|
35
|
+
}
|
|
36
|
+
const object = value;
|
|
37
|
+
const prototype = Object.getPrototypeOf(object);
|
|
38
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
39
|
+
const objectType = prototype?.constructor?.name ?? "unknown";
|
|
40
|
+
throw new TypeError(`Unsupported contract object at ${path}: ${objectType}`);
|
|
41
|
+
}
|
|
42
|
+
if (ancestors.has(object)) throw new TypeError(`Circular contract value at ${path}`);
|
|
43
|
+
ancestors.add(object);
|
|
44
|
+
const entries = Object.entries(object).filter(([, v]) => v !== void 0).sort(([a], [b]) => compareCanonicalStrings(a, b));
|
|
45
|
+
try {
|
|
46
|
+
return `{${entries.map(
|
|
47
|
+
([key, entry]) => `${JSON.stringify(key)}:${canonicalPreimageValue(entry, ancestors, `${path}.${key}`)}`
|
|
48
|
+
).join(",")}}`;
|
|
49
|
+
} finally {
|
|
50
|
+
ancestors.delete(object);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
var K = new Uint32Array([
|
|
54
|
+
1116352408,
|
|
55
|
+
1899447441,
|
|
56
|
+
3049323471,
|
|
57
|
+
3921009573,
|
|
58
|
+
961987163,
|
|
59
|
+
1508970993,
|
|
60
|
+
2453635748,
|
|
61
|
+
2870763221,
|
|
62
|
+
3624381080,
|
|
63
|
+
310598401,
|
|
64
|
+
607225278,
|
|
65
|
+
1426881987,
|
|
66
|
+
1925078388,
|
|
67
|
+
2162078206,
|
|
68
|
+
2614888103,
|
|
69
|
+
3248222580,
|
|
70
|
+
3835390401,
|
|
71
|
+
4022224774,
|
|
72
|
+
264347078,
|
|
73
|
+
604807628,
|
|
74
|
+
770255983,
|
|
75
|
+
1249150122,
|
|
76
|
+
1555081692,
|
|
77
|
+
1996064986,
|
|
78
|
+
2554220882,
|
|
79
|
+
2821834349,
|
|
80
|
+
2952996808,
|
|
81
|
+
3210313671,
|
|
82
|
+
3336571891,
|
|
83
|
+
3584528711,
|
|
84
|
+
113926993,
|
|
85
|
+
338241895,
|
|
86
|
+
666307205,
|
|
87
|
+
773529912,
|
|
88
|
+
1294757372,
|
|
89
|
+
1396182291,
|
|
90
|
+
1695183700,
|
|
91
|
+
1986661051,
|
|
92
|
+
2177026350,
|
|
93
|
+
2456956037,
|
|
94
|
+
2730485921,
|
|
95
|
+
2820302411,
|
|
96
|
+
3259730800,
|
|
97
|
+
3345764771,
|
|
98
|
+
3516065817,
|
|
99
|
+
3600352804,
|
|
100
|
+
4094571909,
|
|
101
|
+
275423344,
|
|
102
|
+
430227734,
|
|
103
|
+
506948616,
|
|
104
|
+
659060556,
|
|
105
|
+
883997877,
|
|
106
|
+
958139571,
|
|
107
|
+
1322822218,
|
|
108
|
+
1537002063,
|
|
109
|
+
1747873779,
|
|
110
|
+
1955562222,
|
|
111
|
+
2024104815,
|
|
112
|
+
2227730452,
|
|
113
|
+
2361852424,
|
|
114
|
+
2428436474,
|
|
115
|
+
2756734187,
|
|
116
|
+
3204031479,
|
|
117
|
+
3329325298
|
|
118
|
+
]);
|
|
119
|
+
function rotr(value, bits) {
|
|
120
|
+
return (value >>> bits | value << 32 - bits) >>> 0;
|
|
121
|
+
}
|
|
122
|
+
function sha256Hex(message) {
|
|
123
|
+
const bytes = new TextEncoder().encode(message);
|
|
124
|
+
const length = bytes.length;
|
|
125
|
+
const bitLength = length * 8;
|
|
126
|
+
const withMarker = length + 1;
|
|
127
|
+
const zeroPad = (56 - withMarker % 64 + 64) % 64;
|
|
128
|
+
const total = withMarker + zeroPad + 8;
|
|
129
|
+
const buffer = new Uint8Array(total);
|
|
130
|
+
buffer.set(bytes, 0);
|
|
131
|
+
buffer[length] = 128;
|
|
132
|
+
const view = new DataView(buffer.buffer);
|
|
133
|
+
view.setUint32(total - 8, Math.floor(bitLength / 4294967296));
|
|
134
|
+
view.setUint32(total - 4, bitLength >>> 0);
|
|
135
|
+
let h0 = 1779033703;
|
|
136
|
+
let h1 = 3144134277;
|
|
137
|
+
let h2 = 1013904242;
|
|
138
|
+
let h3 = 2773480762;
|
|
139
|
+
let h4 = 1359893119;
|
|
140
|
+
let h5 = 2600822924;
|
|
141
|
+
let h6 = 528734635;
|
|
142
|
+
let h7 = 1541459225;
|
|
143
|
+
const w = new Uint32Array(64);
|
|
144
|
+
for (let chunk = 0; chunk < total; chunk += 64) {
|
|
145
|
+
for (let t = 0; t < 16; t++) w[t] = view.getUint32(chunk + t * 4);
|
|
146
|
+
for (let t = 16; t < 64; t++) {
|
|
147
|
+
const w15 = w[t - 15];
|
|
148
|
+
const w2 = w[t - 2];
|
|
149
|
+
const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
|
|
150
|
+
const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
|
|
151
|
+
w[t] = w[t - 16] + s0 + w[t - 7] + s1 >>> 0;
|
|
152
|
+
}
|
|
153
|
+
let a = h0;
|
|
154
|
+
let b = h1;
|
|
155
|
+
let c = h2;
|
|
156
|
+
let d = h3;
|
|
157
|
+
let e = h4;
|
|
158
|
+
let f = h5;
|
|
159
|
+
let g = h6;
|
|
160
|
+
let h = h7;
|
|
161
|
+
for (let t = 0; t < 64; t++) {
|
|
162
|
+
const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
163
|
+
const ch = e & f ^ ~e & g;
|
|
164
|
+
const temp1 = h + s1 + ch + K[t] + w[t] >>> 0;
|
|
165
|
+
const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
166
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
167
|
+
const temp2 = s0 + maj >>> 0;
|
|
168
|
+
h = g;
|
|
169
|
+
g = f;
|
|
170
|
+
f = e;
|
|
171
|
+
e = d + temp1 >>> 0;
|
|
172
|
+
d = c;
|
|
173
|
+
c = b;
|
|
174
|
+
b = a;
|
|
175
|
+
a = temp1 + temp2 >>> 0;
|
|
176
|
+
}
|
|
177
|
+
h0 = h0 + a >>> 0;
|
|
178
|
+
h1 = h1 + b >>> 0;
|
|
179
|
+
h2 = h2 + c >>> 0;
|
|
180
|
+
h3 = h3 + d >>> 0;
|
|
181
|
+
h4 = h4 + e >>> 0;
|
|
182
|
+
h5 = h5 + f >>> 0;
|
|
183
|
+
h6 = h6 + g >>> 0;
|
|
184
|
+
h7 = h7 + h >>> 0;
|
|
185
|
+
}
|
|
186
|
+
return [h0, h1, h2, h3, h4, h5, h6, h7].map((value) => value.toString(16).padStart(8, "0")).join("");
|
|
187
|
+
}
|
|
188
|
+
function contractHash(body) {
|
|
189
|
+
return sha256Hex(canonicalPreimage(body));
|
|
190
|
+
}
|
|
191
|
+
function artifactContentHash(body) {
|
|
192
|
+
return sha256Hex(canonicalPreimage(body));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export {
|
|
196
|
+
canonicalPreimage,
|
|
197
|
+
compareCanonicalStrings,
|
|
198
|
+
sha256Hex,
|
|
199
|
+
contractHash,
|
|
200
|
+
artifactContentHash
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=chunk-PWIJMOI4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contract/hash.ts"],"sourcesContent":["/**\n * Frontend Contract hashing — the cross-runtime content-address (FCID).\n *\n * The keystone trust property of the Frontend Contract is that \"what the agent\n * was served\" and \"what CI enforced\" are provably the same bytes. That only\n * holds if the contract hash is computed by an *identical* function in every\n * runtime that touches it: the CLI (Node), the Convex isolate, and the browser.\n *\n * The fact-IR `hash64Hex` (FNV-1a, in `../facts/ids.ts`) is deliberately NOT\n * used here: it is a 64-bit non-cryptographic integrity reference for in-process\n * fact dedup, and Convex independently reaches for `crypto.subtle` (async, and a\n * *different* algorithm). Two different hashes over the same preimage cannot back\n * a \"same 64 hex chars or the build is rejected\" guarantee.\n *\n * So this module ships ONE function: a synchronous, dependency-free SHA-256 over\n * a number-normalizing canonical preimage. Synchronous so it composes with the\n * sync fact-compilation path; dependency-free so it is byte-identical across\n * Node, the Convex isolate, and the browser without a native/optional dep\n * (`crypto.subtle` is async; `@noble/hashes` is not a dependency of this MIT,\n * browser-safe package). `TextEncoder` is the only ambient global used, and it is\n * present in all three runtimes.\n */\n\n// ---------------------------------------------------------------------------\n// Canonical preimage\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize a number to a stable string. `JSON.stringify` is stable for finite\n * numbers, but renders `NaN`/`Infinity` as `null` (ambiguous) and does not\n * collapse `-0`. Token values flow into the contract body, so a serializer that\n * silently maps `NaN` to `null` would hash two different inputs to the same\n * preimage. Non-finite numbers get legacy v1 sentinels instead; `-0` collapses\n * to `0`.\n */\nfunction normalizeNumber(value: number): string {\n if (Number.isNaN(value)) return '\"@num:nan\"';\n if (value === Infinity) return '\"@num:+inf\"';\n if (value === -Infinity) return '\"@num:-inf\"';\n if (Object.is(value, -0)) return \"0\";\n return JSON.stringify(value);\n}\n\n/**\n * Deterministic, canonical serialization of a contract body for hashing.\n *\n * - object keys sorted lexicographically; attribute order is irrelevant\n * - `undefined` properties dropped (so optional fields don't perturb the hash)\n * - numbers normalized via {@link normalizeNumber}\n * - `bigint` encoded as its decimal string (JSON cannot represent it natively)\n * - circular, executable, and non-plain runtime values rejected with a stable path\n *\n * This is intentionally a separate serializer from `facts/ids.ts#canonicalJson`:\n * that one targets in-process fact IDs and does not normalize numbers, and we\n * must not change its output (it would silently re-key existing fact IDs).\n */\nexport function canonicalPreimage(value: unknown): string {\n return canonicalPreimageValue(value, new Set<object>(), \"(root)\");\n}\n\n/**\n * Locale-independent lexical order for authority-bearing canonical records.\n *\n * `String#localeCompare` follows the runtime's default locale, so it can order\n * the same Unicode identifiers differently across a developer machine, CI,\n * and a browser. Relational string comparison is defined by ECMAScript over\n * UTF-16 code units and therefore gives every runtime the same ordering.\n */\nexport function compareCanonicalStrings(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n\nfunction canonicalPreimageValue(value: unknown, ancestors: Set<object>, path: string): string {\n if (value === undefined || value === null) return \"null\";\n const type = typeof value;\n if (type === \"number\") return normalizeNumber(value as number);\n if (type === \"string\" || type === \"boolean\") return JSON.stringify(value);\n if (type === \"bigint\") return JSON.stringify((value as bigint).toString());\n if (type === \"function\" || type === \"symbol\") {\n throw new TypeError(`Unsupported contract value at ${path}: ${type}`);\n }\n if (Array.isArray(value)) {\n if (ancestors.has(value)) throw new TypeError(`Circular contract value at ${path}`);\n ancestors.add(value);\n try {\n return `[${value\n .map((entry, index) => canonicalPreimageValue(entry, ancestors, `${path}[${index}]`))\n .join(\",\")}]`;\n } finally {\n ancestors.delete(value);\n }\n }\n if (type !== \"object\") {\n throw new TypeError(`Unsupported contract value at ${path}: ${type}`);\n }\n const object = value as object;\n const prototype = Object.getPrototypeOf(object);\n if (prototype !== Object.prototype && prototype !== null) {\n const objectType = prototype?.constructor?.name ?? \"unknown\";\n throw new TypeError(`Unsupported contract object at ${path}: ${objectType}`);\n }\n if (ancestors.has(object)) throw new TypeError(`Circular contract value at ${path}`);\n ancestors.add(object);\n const entries = Object.entries(object as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => compareCanonicalStrings(a, b));\n try {\n return `{${entries\n .map(\n ([key, entry]) =>\n `${JSON.stringify(key)}:${canonicalPreimageValue(entry, ancestors, `${path}.${key}`)}`\n )\n .join(\",\")}}`;\n } finally {\n ancestors.delete(object);\n }\n}\n\n// ---------------------------------------------------------------------------\n// SHA-256 (FIPS 180-4), synchronous, pure JS\n// ---------------------------------------------------------------------------\n\n// First 32 bits of the fractional parts of the cube roots of the first 64 primes.\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nfunction rotr(value: number, bits: number): number {\n return ((value >>> bits) | (value << (32 - bits))) >>> 0;\n}\n\n/**\n * SHA-256 of a UTF-8 string, returned as 64 lowercase hex chars.\n *\n * Deterministic and synchronous in every runtime. Verified against the FIPS\n * 180-4 vectors in `hash.test.ts`.\n */\nexport function sha256Hex(message: string): string {\n const bytes = new TextEncoder().encode(message);\n const length = bytes.length;\n const bitLength = length * 8;\n\n // Padding: append 0x80, then zeros, then the 64-bit big-endian bit length,\n // so the total is a multiple of 64 bytes.\n const withMarker = length + 1;\n const zeroPad = (56 - (withMarker % 64) + 64) % 64;\n const total = withMarker + zeroPad + 8;\n const buffer = new Uint8Array(total);\n buffer.set(bytes, 0);\n buffer[length] = 0x80;\n\n const view = new DataView(buffer.buffer);\n // 64-bit length: high word then low word, big-endian. bitLength can exceed\n // 2^32 for very large inputs, so split rather than truncate.\n view.setUint32(total - 8, Math.floor(bitLength / 0x100000000));\n view.setUint32(total - 4, bitLength >>> 0);\n\n let h0 = 0x6a09e667;\n let h1 = 0xbb67ae85;\n let h2 = 0x3c6ef372;\n let h3 = 0xa54ff53a;\n let h4 = 0x510e527f;\n let h5 = 0x9b05688c;\n let h6 = 0x1f83d9ab;\n let h7 = 0x5be0cd19;\n\n const w = new Uint32Array(64);\n for (let chunk = 0; chunk < total; chunk += 64) {\n for (let t = 0; t < 16; t++) w[t] = view.getUint32(chunk + t * 4);\n for (let t = 16; t < 64; t++) {\n const w15 = w[t - 15];\n const w2 = w[t - 2];\n const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ (w15 >>> 3);\n const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ (w2 >>> 10);\n w[t] = (w[t - 16] + s0 + w[t - 7] + s1) >>> 0;\n }\n\n let a = h0;\n let b = h1;\n let c = h2;\n let d = h3;\n let e = h4;\n let f = h5;\n let g = h6;\n let h = h7;\n\n for (let t = 0; t < 64; t++) {\n const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const ch = (e & f) ^ (~e & g);\n const temp1 = (h + s1 + ch + K[t] + w[t]) >>> 0;\n const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const maj = (a & b) ^ (a & c) ^ (b & c);\n const temp2 = (s0 + maj) >>> 0;\n h = g;\n g = f;\n f = e;\n e = (d + temp1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (temp1 + temp2) >>> 0;\n }\n\n h0 = (h0 + a) >>> 0;\n h1 = (h1 + b) >>> 0;\n h2 = (h2 + c) >>> 0;\n h3 = (h3 + d) >>> 0;\n h4 = (h4 + e) >>> 0;\n h5 = (h5 + f) >>> 0;\n h6 = (h6 + g) >>> 0;\n h7 = (h7 + h) >>> 0;\n }\n\n return [h0, h1, h2, h3, h4, h5, h6, h7]\n .map((value) => value.toString(16).padStart(8, \"0\"))\n .join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Contract hash (FCID)\n// ---------------------------------------------------------------------------\n\n/**\n * The Frontend Contract ID: `sha256(canonicalPreimage(body))`, 64 lowercase hex\n * chars. Identical inputs produce an identical FCID in the CLI, the Convex\n * isolate, and the browser — which is what lets the gen-time agent view and the\n * CI enforcement reference the same contract by hash.\n *\n * Never feed preview modules, story states, guidance, or runtime config into\n * this function and call the result an FCID — those belong to\n * {@link artifactContentHash}.\n */\nexport function contractHash(body: unknown): string {\n return sha256Hex(canonicalPreimage(body));\n}\n\n/**\n * Content-address for preview artifacts (`artifactId`): the same deterministic\n * SHA-256 canonicalization as {@link contractHash}, but a separate named seam so\n * callers never assign `artifactId` from an FCID (or vice versa). Hash preview\n * modules, states, guidance/render content, and runtime config here.\n */\nexport function artifactContentHash(body: unknown): string {\n return sha256Hex(canonicalPreimage(body));\n}\n"],"mappings":"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","names":[]}
|