@topik/core 0.1.0-alpha.5 → 0.1.0-alpha.7

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/index.d.mts CHANGED
@@ -1,26 +1,34 @@
1
+ import { CourseReferenceContext, ResolvedCourseContentLink, ResolvedCourseContentReference, ResolvedCourseNavigation, ResolvedCoursePage, resolveCourseContentHref, resolveCourseContentReference, resolveCourseNavigation } from "./course-navigation.mjs";
2
+ import { $ as TopikAssetPathDiagnosticReason, A as AssetBlobUri, B as parseGeneratedAssetName, C as TopikMaterializationResourceV1, D as digestTopikAssetSemanticRecord, E as createTopikMaterializationRecord, F as generateAutomaticAssetName, G as validateProjectNamespace, H as topikAssetNameDescriptor, I as isAssetBlobUri, J as TOPIK_ASSET_DIAGNOSTIC_IDS, K as TOPIK_ASSET_CORRELATION_ID_PATTERN, L as isGeneratedAssetName, M as GenerateAutomaticAssetNameOptions, N as GeneratedAssetName, O as digestTopikMaterializationRecord, P as ParsedAsset, Q as TopikAssetDiagnosticLocation, R as parseAsset, S as TopikMaterializationResourceInput, T as createTopikAssetSemanticRecord, U as validateAssetBlobUri, V as serializeAsset, W as validateAssetValue, X as TopikAssetDiagnostic, Y as TopikAssetCorrelationId, Z as TopikAssetDiagnosticId, _ as TopikAssetReferenceMappingV1, a as PreviewState, at as ASSET_TYPE, b as TopikMaterializationPayloadV1, c as AssetCompilationOptions, ct as TOPIK_ASSET_REFERENCE_VERSION, d as AssetNameInput, dt as TOPIK_MATERIALIZATION_VERSION, et as TopikAssetRecoveryCategory, f as AssetPayload, ft as TOPIK_PATH_V1_DESCRIPTOR, g as compileAssetResources, gt as SourceResource, h as ContentBearingResource, ht as ResourceType, i as PreviewPayloadDescriptor, it as ASSET_SCHEMA_ID, j as CompiledAsset, k as validateTopikMaterializationRecord, l as AssetCompilationResult, lt as TOPIK_BLOB_OUTPUT_PREFIX, m as CompiledResource, mt as Resource, n as CourseNavigationModule, nt as correlateTopikAssetResult, o as TOPIK_PREVIEW_PROTOCOL, ot as TOPIK_ASSET_LIMITS, p as CompileAssetResourcesInput, pt as TOPIK_PATH_VERSION, q as TOPIK_ASSET_DEFAULT_CORRELATION_ID, r as PreviewDiagnostic, rt as ASSET_API_VERSION, s as AssetCompilationError, st as TOPIK_ASSET_NAME_VERSION, t as CourseNavigationIndex, tt as TopikAssetResult, u as AssetNameGenerator, ut as TOPIK_JSON_VERSION, v as TopikAssetSemanticRecordV1, w as compareTopikAssetIdentities, x as TopikMaterializationRecordV1, y as TopikMaterializationPayloadInput, z as parseAssetBlobUri } from "./preview-DfACgOEg.mjs";
3
+ import { ExternalWikiDropdown, ExternalWikiTab, InternalWikiDropdown, InternalWikiTab, ResolvedWikiContentLink, ResolvedWikiContentReference, ResolvedWikiNavigation, ResolvedWikiPage, WikiSwitcherNode, findFirstWikiPage, findWikiPageAncestors, hasWikiNavChildren, isExternalWikiDropdown, isExternalWikiTab, isInternalWikiDropdown, isInternalWikiTab, joinWikiPath, resolveWikiContentHref, resolveWikiContentReference, resolveWikiNavigation } from "./wiki-navigation.mjs";
1
4
  import { z } from "zod";
2
- import { TopikContentDiagnostic, TopikGeneratedAssetName } from "@topik/content-schema";
5
+ import { TopikContentDiagnostic, TopikNavigationReference, TopikResourceReference } from "@topik/content";
6
+ import "yaml";
7
+ import { Person } from "@topik/schema/person/v1";
3
8
  import { CoursePage } from "@topik/schema/course-page/v1";
4
9
  import { Guide } from "@topik/schema/guide/v1";
10
+ import { Wiki, WikiNavNode } from "@topik/schema/wiki/v1";
5
11
  import { WikiPage } from "@topik/schema/wiki-page/v1";
6
- import { Asset } from "@topik/schema/asset/v1";
7
- import { Course } from "@topik/schema/course/v1";
8
- import { CourseModule } from "@topik/schema/course-module/v1";
9
- import { Person } from "@topik/schema/person/v1";
10
- import { Wiki, WikiDropdownNavNode, WikiExternalDropdownNavNode, WikiExternalTabNavNode, WikiInternalDropdownNavNode, WikiInternalTabNavNode, WikiNavContainerNode, WikiNavNode, WikiNavigation, WikiPageNavNode, WikiTabNavNode } from "@topik/schema/wiki/v1";
11
- //#region src/config/collection.d.ts
12
+ /** The public resource validator owns Person fields, including future schema additions. */
13
+ declare function parseSourcePersons(value: unknown): Person[];
12
14
  declare const collectionConfigSchema: z.ZodObject<{
13
15
  id: z.ZodString;
14
16
  title: z.ZodString;
17
+ sourceVersion: z.ZodOptional<z.ZodLiteral<1>>;
18
+ persons: z.ZodOptional<z.ZodUnknown>;
19
+ assets: z.ZodDefault<z.ZodObject<{
20
+ directory: z.ZodDefault<z.ZodString>;
21
+ }, z.core.$strict>>;
15
22
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
16
23
  }, z.core.$strip>;
17
- type CollectionConfig = z.infer<typeof collectionConfigSchema>;
18
- declare function parseCollectionConfig(raw: unknown): CollectionConfig;
19
- //#endregion
20
- //#region src/config/wiki.d.ts
24
+ type CollectionConfig = Omit<z.infer<typeof collectionConfigSchema>, "persons"> & {
25
+ persons?: ReturnType<typeof parseSourcePersons>;
26
+ };
27
+ export declare function parseCollectionConfig(raw: unknown): CollectionConfig;
21
28
  type WikiPageNavNode$1 = {
22
29
  type: "page";
23
30
  slug: string;
31
+ source?: string;
24
32
  icon?: string;
25
33
  hidden?: boolean;
26
34
  };
@@ -59,6 +67,11 @@ type WikiNavNode$1 = string | WikiPageNavNode$1 | WikiGroupNavNode | WikiInterna
59
67
  declare const wikiConfigSchema: z.ZodObject<{
60
68
  id: z.ZodString;
61
69
  title: z.ZodString;
70
+ sourceVersion: z.ZodOptional<z.ZodLiteral<1>>;
71
+ labels: z.ZodOptional<z.ZodUnknown>;
72
+ assets: z.ZodDefault<z.ZodObject<{
73
+ directory: z.ZodDefault<z.ZodString>;
74
+ }, z.core.$strict>>;
62
75
  description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNull]>>;
63
76
  navigation: z.ZodOptional<z.ZodArray<z.ZodType<WikiNavNode$1, unknown, z.core.$ZodTypeInternals<WikiNavNode$1, unknown>>>>;
64
77
  theme: z.ZodOptional<z.ZodObject<{
@@ -76,296 +89,262 @@ declare const wikiConfigSchema: z.ZodObject<{
76
89
  }, z.core.$strip>>;
77
90
  }, z.core.$strip>>;
78
91
  }, z.core.$strip>;
79
- type WikiConfig = z.infer<typeof wikiConfigSchema>;
80
- declare function parseWikiConfig(raw: unknown): WikiConfig;
81
- //#endregion
82
- //#region src/resource.d.ts
83
- type Resource = Asset | Course | CourseModule | CoursePage | Guide | Person | Wiki | WikiPage;
84
- /** Resources accepted as compiler input. `Asset` exists only in compiler output. */
85
- type SourceResource = Exclude<Resource, Asset>;
86
- type ResourceType = Resource["type"];
87
- //#endregion
88
- //#region src/assets/constants.d.ts
89
- declare const ASSET_API_VERSION: "v1";
90
- declare const ASSET_TYPE: "Asset";
91
- declare const ASSET_SCHEMA_ID: "https://topik.dev/schemas/asset/v1.json";
92
- declare const TOPIK_JSON_VERSION: "topik-json-v1";
93
- declare const TOPIK_PATH_VERSION: "topik-path-v1";
94
- declare const TOPIK_ASSET_REFERENCE_VERSION: "topik-asset-reference-v1";
95
- declare const TOPIK_MATERIALIZATION_VERSION: "topik-materialization-v1";
96
- declare const TOPIK_ASSET_NAME_VERSION: "topik-asset-name-v1";
97
- declare const TOPIK_BLOB_OUTPUT_PREFIX: "blobs";
98
- declare const TOPIK_PATH_V1_DESCRIPTOR: {
99
- readonly collisionNormalization: "toNFKC_Casefold";
100
- readonly id: "topik-path-v1";
101
- readonly localReferenceEncoding: "rfc3986-utf8-upper-v1";
102
- readonly maxComponentUtf8Bytes: 255;
103
- readonly maxComponents: 64;
104
- readonly maxRepositoryPathUtf8Bytes: 768;
105
- readonly normalizationSensitiveExclusion: "unicode-17-new-marks";
106
- readonly storageNormalization: "NFC";
107
- readonly unicodeVersion: "17.0.0";
92
+ type WikiConfig = Omit<z.infer<typeof wikiConfigSchema>, "labels"> & {
93
+ labels?: Record<string, string>;
108
94
  };
109
- declare const TOPIK_ASSET_LIMITS: {
110
- readonly maxDescriptorBytes: 1048576;
111
- readonly maxAssetBytes: 268435456;
112
- readonly maxAssets: 10000;
113
- readonly maxJsonDepth: 8;
114
- readonly maxComponentUtf8Bytes: 255;
115
- readonly maxComponents: 64;
116
- readonly maxRepositoryPathUtf8Bytes: 768;
117
- };
118
- //#endregion
119
- //#region src/assets/diagnostics.d.ts
120
- declare const TOPIK_ASSET_DIAGNOSTIC_IDS: readonly ["TOPIK_ASSET_UNSUPPORTED_VERSION", "TOPIK_ASSET_DUPLICATE_MEMBER", "TOPIK_ASSET_SCHEMA_INVALID", "TOPIK_ASSET_NON_CANONICAL", "TOPIK_ASSET_NAME_INVALID", "TOPIK_ASSET_NAME_COLLISION", "TOPIK_ASSET_SOURCE_NAMESPACE_REQUIRED", "TOPIK_ASSET_SOURCE_NAMESPACE_INVALID", "TOPIK_ASSET_PATH_INVALID", "TOPIK_ASSET_PATH_COLLISION", "TOPIK_ASSET_REFERENCE_AMBIGUOUS", "TOPIK_ASSET_REFERENCE_MALFORMED", "TOPIK_ASSET_REFERENCE_MISSING", "TOPIK_ASSET_FILE_MISSING", "TOPIK_ASSET_DIGEST_MISMATCH", "TOPIK_ASSET_SIZE_MISMATCH", "TOPIK_ASSET_MEDIA_TYPE_MISMATCH", "TOPIK_ASSET_FILE_TYPE_UNSUPPORTED", "TOPIK_ASSET_ACTIVE_CONTENT_UNSUPPORTED", "TOPIK_ASSET_REFERENCE_ACCESSIBILITY_INVALID", "TOPIK_EXTERNAL_REFERENCE_UNSAFE", "TOPIK_ASSET_INVENTORY_INCOMPLETE", "TOPIK_ASSET_VERSION_INCOMPARABLE"];
121
- declare const TOPIK_ASSET_DEFAULT_CORRELATION_ID: "cor_00000000000000000000000000";
122
- declare const TOPIK_ASSET_CORRELATION_ID_PATTERN: RegExp;
123
- type TopikAssetCorrelationId = `cor_${string}`;
124
- type TopikAssetDiagnosticId = (typeof TOPIK_ASSET_DIAGNOSTIC_IDS)[number];
125
- type TopikAssetPathDiagnosticReason = "invalid_utf8" | "capability_invalid" | "unicode_version_unsupported" | "not_nfc" | "absolute" | "separator_alias" | "dot_segment" | "percent_noncanonical" | "forbidden_character" | "reserved_name" | "too_long" | "casefold_collision";
126
- type TopikAssetRecoveryCategory = "upgrade-reader" | "repair-source" | "restore-file" | "verify-bytes" | "preserve-read-only";
127
- interface TopikAssetDiagnosticLocation {
128
- jsonPointer?: string;
129
- contentPosition?: string;
130
- path?: string;
131
- key?: string;
132
- commit?: string;
133
- }
134
- interface TopikAssetDiagnostic {
135
- id: TopikAssetDiagnosticId;
136
- /** Safe opaque operation correlation; callers may replace the deterministic default. */
137
- correlationId: TopikAssetCorrelationId;
138
- severity: "error";
139
- consequence: "block-resource" | "block-identity-and-writes" | "block-mutation";
140
- descriptorVersion: string;
141
- location: TopikAssetDiagnosticLocation;
142
- recovery: TopikAssetRecoveryCategory;
143
- reason?: TopikAssetPathDiagnosticReason;
144
- /** Human wording is intentionally not a stable compatibility surface. */
145
- message: string;
146
- }
147
- type TopikAssetResult<T> = {
148
- ok: true;
149
- value: T;
150
- diagnostics: readonly [];
151
- source?: Uint8Array;
152
- } | {
153
- ok: false;
154
- value?: T;
155
- diagnostics: readonly TopikAssetDiagnostic[];
156
- /** Exact caller bytes are non-loggable evidence; never copy them into diagnostics/telemetry. */
157
- source?: Uint8Array;
95
+ export declare function parseWikiConfig(raw: unknown): WikiConfig;
96
+ declare const moduleSchema: z.ZodObject<{
97
+ id: z.ZodString;
98
+ title: z.ZodString;
99
+ slug: z.ZodString;
100
+ order: z.ZodNumber;
101
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
102
+ labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
103
+ pages: z.ZodArray<z.ZodString>;
104
+ }, z.core.$strip>;
105
+ declare const courseConfigSchema: z.ZodObject<{
106
+ sourceVersion: z.ZodLiteral<1>;
107
+ id: z.ZodString;
108
+ title: z.ZodString;
109
+ slug: z.ZodString;
110
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
111
+ labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
112
+ authors: z.ZodOptional<z.ZodArray<z.ZodString>>;
113
+ persons: z.ZodOptional<z.ZodUnknown>;
114
+ assets: z.ZodDefault<z.ZodObject<{
115
+ directory: z.ZodDefault<z.ZodString>;
116
+ }, z.core.$strict>>;
117
+ modules: z.ZodArray<z.ZodObject<{
118
+ id: z.ZodString;
119
+ title: z.ZodString;
120
+ slug: z.ZodString;
121
+ order: z.ZodNumber;
122
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
123
+ labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
124
+ pages: z.ZodArray<z.ZodString>;
125
+ }, z.core.$strip>>;
126
+ }, z.core.$strip>;
127
+ type CourseConfig = Omit<z.infer<typeof courseConfigSchema>, "persons"> & {
128
+ persons?: ReturnType<typeof parseSourcePersons>;
158
129
  };
159
- declare function correlateTopikAssetResult<T>(result: TopikAssetResult<T>, correlationId: TopikAssetCorrelationId): TopikAssetResult<T>;
160
- //#endregion
161
- //#region src/assets/asset.d.ts
162
- interface ParsedAsset {
163
- asset: Asset;
164
- canonicalBytes: Uint8Array;
165
- }
166
- /** Compiler-generated name used by automatic Asset compilation. */
167
- type GeneratedAssetName = TopikGeneratedAssetName;
168
- declare const assetBlobUriBrand: unique symbol;
169
- /** Opaque compiler output path for one SHA-256-addressed Asset blob. */
170
- type AssetBlobUri = string & {
171
- readonly [assetBlobUriBrand]: "AssetBlobUri";
130
+ type CourseModuleConfig = z.infer<typeof moduleSchema>;
131
+ export declare function parseCourseConfig(raw: unknown): CourseConfig;
132
+ export declare const TOPIK_MANIFEST_FILENAME = ".topik.yaml";
133
+ export declare const TOPIK_MANIFEST_LIMITS: {
134
+ readonly maxBytes: 1048576;
135
+ readonly maxSources: 1000;
136
+ readonly maxDepth: 32;
172
137
  };
173
- declare function isAssetBlobUri(value: unknown): value is AssetBlobUri;
174
- declare function parseAssetBlobUri(value: string): AssetBlobUri;
175
- declare function parseGeneratedAssetName(value: string): GeneratedAssetName;
176
- /** Asset descriptor emitted by the compiler with a materialized payload. */
177
- interface CompiledAsset extends Asset {
178
- name: GeneratedAssetName;
179
- spec: {
180
- uri: AssetBlobUri;
181
- integrity: `sha256:${string}`;
182
- size: number;
183
- mediaType: string;
184
- };
185
- }
186
- declare function parseAsset(input: string | Uint8Array): TopikAssetResult<ParsedAsset>;
187
- declare function validateAssetValue(value: unknown): TopikAssetResult<Asset>;
188
- /** Serialize one Asset to deterministic UTF-8 canonical JSON and prove its round trip. */
189
- declare function serializeAsset(value: unknown): TopikAssetResult<Uint8Array>;
190
- /** Admit a compiler-materialized blob path; Asset resources may use other URI forms. */
191
- declare function validateAssetBlobUri(value: string): TopikAssetResult<{
192
- uri: AssetBlobUri;
193
- }>;
194
- declare function isGeneratedAssetName(value: unknown): value is GeneratedAssetName;
195
- declare function validateStableSourceNamespace(value: string): TopikAssetResult<string>;
196
- interface GenerateAutomaticAssetNameOptions {
197
- stableSourceNamespace: string;
198
- normalizedPath: string;
199
- }
200
- declare function generateAutomaticAssetName(options: GenerateAutomaticAssetNameOptions): TopikAssetResult<GeneratedAssetName>;
201
- declare function topikAssetNameDescriptor(): {
202
- id: typeof TOPIK_ASSET_NAME_VERSION;
138
+ export declare const topikManifestSourceSchema: z.ZodObject<{
139
+ kind: z.ZodEnum<{
140
+ collection: "collection";
141
+ course: "course";
142
+ wiki: "wiki";
143
+ }>;
144
+ config: z.ZodString;
145
+ }, z.core.$strict>;
146
+ export declare const topikManifestSchema: z.ZodObject<{
147
+ version: z.ZodLiteral<1>;
148
+ namespace: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
149
+ sources: z.ZodArray<z.ZodObject<{
150
+ kind: z.ZodEnum<{
151
+ collection: "collection";
152
+ course: "course";
153
+ wiki: "wiki";
154
+ }>;
155
+ config: z.ZodString;
156
+ }, z.core.$strict>>;
157
+ }, z.core.$strict>;
158
+ type TopikManifest = z.infer<typeof topikManifestSchema>;
159
+ type TopikManifestSource = z.infer<typeof topikManifestSourceSchema>;
160
+ export declare function parseTopikManifest(raw: unknown): TopikManifest;
161
+ export declare const DEFAULT_ASSET_DIRECTORY = "_assets";
162
+ /** Source-local destination for new synced media; not an input scan or compiler output path. */
163
+ export declare const sourceAssetsConfigSchema: z.ZodObject<{
164
+ directory: z.ZodDefault<z.ZodString>;
165
+ }, z.core.$strict>;
166
+ type SourceAssetsConfig = z.infer<typeof sourceAssetsConfigSchema>;
167
+ declare const PUBLIC_COMPILE_ERROR_MESSAGES: {
168
+ readonly "manifest-required": 'Project compilation requires .topik.yaml in the selected directory. Add a manifest such as: {"version":1,"namespace":"owner/project","sources":[{"kind":"wiki","config":"wiki.yaml"}]}';
169
+ readonly "manifest-invalid": "Root manifest is invalid.";
170
+ readonly "manifest-source-failed": "Manifest source could not be compiled.";
171
+ readonly "manifest-resource-conflict": "Manifest sources produce conflicting resource identities.";
172
+ readonly "config-access-failed": "Configuration file could not be accessed.";
173
+ readonly "config-invalid": "Configuration is invalid.";
174
+ readonly "config-not-found": "Required configuration file was not found.";
175
+ readonly "config-parse-failed": "Configuration file could not be parsed.";
176
+ readonly "config-read-failed": "Configuration file could not be read safely.";
177
+ readonly "file-safe-read-unsupported": "This platform cannot safely open compilation inputs.";
178
+ readonly "file-not-regular": "Compilation input must be a regular file.";
179
+ readonly "file-outside-compilation-root": "Compilation input resolves outside the source root.";
180
+ readonly "frontmatter-invalid": "Document frontmatter is invalid.";
181
+ readonly "reference-list-invalid": "Document resource references are invalid.";
182
+ readonly "reference-targets-invalid": "Resource reference target catalogue is invalid.";
183
+ readonly "wiki-page-not-found": "A configured Wiki page file was not found.";
184
+ readonly "wiki-page-ambiguous": "A Wiki source path matches more than one Markdown file. Keep exactly one source file.";
185
+ readonly "course-page-not-found": "A configured Course page file was not found.";
186
+ readonly "course-page-ambiguous": "A Course source path matches more than one Markdown file. Keep exactly one source file.";
187
+ readonly "author-not-found": "An author must reference a Person in the declared project.";
203
188
  };
204
- //#endregion
205
- //#region src/assets/identity.d.ts
206
- interface TopikAssetReferenceMappingV1 {
207
- resource: string;
208
- position: string;
209
- slot: string;
210
- name: string;
211
- }
212
- interface TopikAssetSemanticRecordV1 {
213
- descriptor: "topik-asset-semantic-v1";
214
- assetNames: readonly string[];
215
- references: readonly TopikAssetReferenceMappingV1[];
216
- }
217
- interface TopikMaterializationResourceV1 {
218
- resource: string;
219
- path: string;
220
- size: number;
221
- sha256: string;
222
- }
223
- interface TopikMaterializationPayloadV1 {
224
- path: string;
225
- size: number;
226
- sha256: string;
227
- assetNames: readonly string[];
228
- }
229
- interface TopikMaterializationRecordV1 {
230
- descriptor: "topik-materialization-v1";
231
- resources: readonly TopikMaterializationResourceV1[];
232
- payloads: readonly TopikMaterializationPayloadV1[];
233
- }
234
- interface TopikMaterializationResourceInput {
235
- resource: {
236
- type: string;
237
- name: string;
238
- };
239
- bytes: Uint8Array;
189
+ type PublicCompileErrorId = keyof typeof PUBLIC_COMPILE_ERROR_MESSAGES;
190
+ export declare function publicCompileErrorMessage(id: unknown): string | undefined;
191
+ /** Public compiler failure with fixed wording, stable ID, and optional safe relative location. */
192
+ export declare class PublicCompileError extends Error {
193
+ readonly id: PublicCompileErrorId;
194
+ readonly location?: string;
195
+ constructor(id: PublicCompileErrorId, location?: string);
240
196
  }
241
- interface TopikMaterializationPayloadInput {
242
- path: string;
243
- bytes: Uint8Array;
244
- assetNames: readonly string[];
245
- }
246
- declare function createTopikAssetSemanticRecord(assets: readonly Asset[], references: readonly TopikAssetReferenceMappingV1[]): TopikAssetSemanticRecordV1;
247
- declare function createTopikMaterializationRecord(resources: readonly TopikMaterializationResourceInput[], payloads: readonly TopikMaterializationPayloadInput[]): TopikMaterializationRecordV1;
248
- declare function validateTopikMaterializationRecord(record: unknown, resources: readonly Resource[], semantic: unknown): TopikAssetResult<TopikMaterializationRecordV1>;
249
- declare function digestTopikAssetSemanticRecord(record: TopikAssetSemanticRecordV1): string;
250
- declare function digestTopikMaterializationRecord(record: TopikMaterializationRecordV1): string;
251
- declare function compareTopikAssetIdentities(left: {
252
- semantic: TopikAssetSemanticRecordV1;
253
- materialization: TopikMaterializationRecordV1;
254
- }, right: {
255
- semantic: TopikAssetSemanticRecordV1;
256
- materialization: TopikMaterializationRecordV1;
257
- }): TopikAssetResult<{
258
- semanticEqual: boolean;
259
- exactEqual: boolean;
260
- }>;
261
- //#endregion
262
- //#region src/compile/assets.d.ts
263
- type ContentBearingResource = CoursePage | Guide | WikiPage;
264
- interface AssetCompilationOptions {
265
- /** Required only when supported local references are discovered automatically. */
266
- sourceNamespace?: string;
267
- }
268
- interface CompileAssetResourcesInput extends AssetCompilationOptions {
269
- rootDir: string;
270
- resources: readonly SourceResource[];
271
- /** Compilation-root-relative source paths keyed by `Type/name`. */
197
+ interface ManifestSourceDescriptor extends TopikManifestSource {
198
+ /** Zero-based declaration index, used only for provenance and diagnostics. */
199
+ sourceIndex: number;
200
+ /** Canonical root-relative directory; empty for the project root. */
201
+ directory: string;
202
+ /** Project namespace declared in the manifest. */
203
+ namespace: string;
204
+ }
205
+ interface ManifestSourceProvenance extends ManifestSourceDescriptor {
206
+ /** Root-relative destination for new synced media. Compilation does not write here. */
207
+ assetDirectory: string;
208
+ /** Authored resource keys mapped to root-relative content/config paths. */
272
209
  sourcePathsByResource: Readonly<Record<string, string>>;
273
- /** Other consumed compiler inputs that cannot be owned as Asset bytes. */
274
- protectedSourcePaths?: readonly string[];
275
- }
276
- interface AssetPayload {
277
- path: AssetBlobUri;
278
- integrity: `sha256:${string}`;
279
- mediaType: string;
280
- size: number;
281
- bytes: Uint8Array;
282
- assetNames: readonly string[];
283
210
  }
284
- interface AssetCompilationResult {
285
- resources: CompiledResource[];
286
- payloads: AssetPayload[];
287
- semantic: TopikAssetSemanticRecordV1;
288
- materialization: TopikMaterializationRecordV1;
211
+ interface ManifestCompileResult extends CompileResult {
212
+ provenance: ManifestSourceProvenance[];
289
213
  }
290
- type CompiledResource = SourceResource | CompiledAsset;
291
- declare class AssetCompilationError extends Error {
292
- readonly diagnostics: readonly TopikAssetDiagnostic[];
293
- constructor(message: string, diagnostics?: readonly TopikAssetDiagnostic[]);
214
+ export declare class ManifestSourceError extends PublicCompileError {
215
+ readonly sourceIndex: number;
216
+ readonly kind?: TopikManifestSource["kind"];
217
+ constructor(id: PublicCompileErrorId, sourceIndex: number, kind?: TopikManifestSource["kind"], config?: string);
294
218
  }
295
- /** Discover and resolve one compilation-wide Asset set and deduplicated payload inventory. */
296
- declare function compileAssetResources(input: CompileAssetResourcesInput): Promise<AssetCompilationResult>;
297
- //#endregion
298
- //#region src/compile/shared.d.ts
219
+ /** Explicit loading requires the canonical file in exactly the supplied root. */
220
+ export declare function loadTopikManifest(dir: string): Promise<TopikManifest>;
221
+ export declare function discoverManifestSources(options: CompileOptions): Promise<ManifestSourceDescriptor[]>;
222
+ /** Compile only declared sources, sharing the existing local compiler and Asset pipeline. */
223
+ export declare function compileManifest(options: CompileOptions): Promise<ManifestCompileResult>;
299
224
  interface CompileResult {
225
+ courseNavigation: CourseNavigationIndex;
226
+ /** Present for manifest compilation, in declaration order. */
227
+ provenance?: ManifestSourceProvenance[];
300
228
  diagnostics: TopikContentDiagnostic[];
301
229
  resources: CompiledResource[];
302
230
  payloads: AssetPayload[];
303
231
  semantic: TopikAssetSemanticRecordV1;
304
232
  materialization: TopikMaterializationRecordV1;
233
+ /** Portable document references and their compilation-time validation state. */
234
+ references: CompiledResourceReference[];
305
235
  }
306
236
  type LinkValidationPolicy = "error" | "warning" | "off";
307
237
  interface CompileValidationOptions {
308
- /** How unresolved wiki page links and same-page guide fragments are handled. */
238
+ /** How unresolved document targets and invalid destination fragments are handled. */
309
239
  links?: LinkValidationPolicy;
310
240
  }
311
- declare class CompileError extends Error {
241
+ export declare class CompileError extends Error {
312
242
  readonly diagnostics: TopikContentDiagnostic[];
313
243
  constructor(diagnostics: TopikContentDiagnostic[]);
314
244
  }
315
- declare function isErrorDiagnostic(diagnostic: TopikContentDiagnostic): boolean;
316
- //#endregion
317
- //#region src/compile/guide.d.ts
245
+ export declare function isErrorDiagnostic(diagnostic: TopikContentDiagnostic): boolean;
246
+ /** Optional application-provided catalogue; Topik never fetches targets. */
247
+ interface CompileResourceReferenceTarget {
248
+ type: TopikResourceReference["type"];
249
+ name: string;
250
+ /** Published heading IDs, when known. Without them a fragment remains deferred. */
251
+ headings?: readonly string[];
252
+ }
253
+ interface CompiledResourceReference {
254
+ resource: string;
255
+ sourcePath: string;
256
+ kind: "link" | "card";
257
+ position: string;
258
+ /** The original authored destination, retained for source round trips. */
259
+ href: string;
260
+ reference: TopikResourceReference;
261
+ status: "verified" | "deferred" | "invalid";
262
+ }
263
+ interface CompileResourceLinksInput {
264
+ rootDir: string;
265
+ resources: readonly SourceResource[];
266
+ sourcePathsByResource: Readonly<Record<string, string>>;
267
+ sourceDirectoriesByResource?: Readonly<Record<string, string>>;
268
+ referenceTargets?: readonly CompileResourceReferenceTarget[];
269
+ /** @internal Source round-trip comparison may already contain compiled Asset locators. */
270
+ allowCompiledAssetReferences?: boolean;
271
+ validation?: CompileValidationOptions;
272
+ }
273
+ /** Resolve document identity after all declared sources have been discovered, before Assets. */
274
+ export declare function compileResourceLinks(input: CompileResourceLinksInput): Promise<{
275
+ resources: SourceResource[];
276
+ diagnostics: TopikContentDiagnostic[];
277
+ references: CompiledResourceReference[];
278
+ }>;
318
279
  interface CompileGuidesOptions {
319
280
  dir: string;
281
+ /** Exact config path relative to dir; content is relative to the config directory. */
282
+ configFile?: string;
320
283
  validation?: CompileValidationOptions;
321
284
  assets?: AssetCompilationOptions;
285
+ referenceTargets?: readonly CompileResourceReferenceTarget[];
286
+ }
287
+ interface CompileResourceDiscovery {
288
+ courseNavigation?: CourseNavigationIndex;
289
+ sourceVersion?: 1;
290
+ /** Destination relative to the selected configuration directory, if a config was loaded. */
291
+ assetDirectory?: string;
292
+ diagnostics: CompileResult["diagnostics"];
293
+ resources: SourceResource[];
294
+ sourcePathsByResource: Record<string, string>;
295
+ consumedSourcePaths: string[];
322
296
  }
323
- declare function compileGuides(options: CompileGuidesOptions): Promise<CompileResult>;
324
- //#endregion
325
- //#region src/compile/wiki.d.ts
297
+ export declare function compileGuides(options: CompileGuidesOptions): Promise<CompileResult>;
298
+ interface DiscoverResourceOptions {
299
+ dir: string;
300
+ /** Exact config path relative to dir; content is relative to its directory. */
301
+ configFile?: string;
302
+ }
303
+ type SourceResourceDiscovery = CompileResourceDiscovery;
304
+ /** Read authoring metadata and paths before combining a caller-owned source inventory. */
305
+ export declare function discoverGuideResources(options: DiscoverResourceOptions): Promise<SourceResourceDiscovery>;
306
+ /** Read authoring metadata and paths before combining a caller-owned source inventory. */
307
+ export declare function discoverWikiResources(options: DiscoverResourceOptions): Promise<SourceResourceDiscovery>;
308
+ /** Read Course membership, metadata and paths without compiling links or Assets. */
309
+ export declare function discoverCourseResources(options: DiscoverResourceOptions): Promise<SourceResourceDiscovery>;
326
310
  interface CompileWikiOptions {
327
311
  dir: string;
312
+ /** Exact config path relative to dir; content is relative to the config directory. */
313
+ configFile?: string;
328
314
  validation?: CompileValidationOptions;
329
315
  assets?: AssetCompilationOptions;
316
+ referenceTargets?: readonly CompileResourceReferenceTarget[];
330
317
  }
331
- declare function compileWiki(options: CompileWikiOptions): Promise<CompileResult>;
332
- declare function pagePathToName(wikiId: string, pagePath: string): string;
333
- //#endregion
334
- //#region src/compile/public-errors.d.ts
335
- declare const PUBLIC_COMPILE_ERROR_MESSAGES: {
336
- readonly "config-access-failed": "Configuration file could not be accessed.";
337
- readonly "config-invalid": "Configuration is invalid.";
338
- readonly "config-not-found": "Required configuration file was not found.";
339
- readonly "config-parse-failed": "Configuration file could not be parsed.";
340
- readonly "config-read-failed": "Configuration file could not be read safely.";
341
- readonly "file-not-regular": "Compilation input must be a regular file.";
342
- readonly "file-outside-compilation-root": "Compilation input resolves outside the source root.";
343
- readonly "frontmatter-invalid": "Document frontmatter is invalid.";
344
- readonly "reference-list-invalid": "Document resource references are invalid.";
345
- readonly "wiki-page-not-found": "A configured Wiki page file was not found.";
346
- };
347
- type PublicCompileErrorId = keyof typeof PUBLIC_COMPILE_ERROR_MESSAGES;
348
- declare function publicCompileErrorMessage(id: unknown): string | undefined;
349
- /** Public compiler failure with fixed wording, stable ID, and optional safe relative location. */
350
- declare class PublicCompileError extends Error {
351
- readonly id: PublicCompileErrorId;
352
- readonly location?: string;
353
- constructor(id: PublicCompileErrorId, location?: string);
318
+ export declare function compileWiki(options: CompileWikiOptions): Promise<CompileResult>;
319
+ export declare function pagePathToName(wikiId: string, pagePath: string): string;
320
+ interface CompileCourseOptions {
321
+ dir: string;
322
+ /** Exact configuration path relative to dir; page sources are relative to its directory. */
323
+ configFile?: string;
324
+ validation?: CompileValidationOptions;
325
+ assets?: AssetCompilationOptions;
326
+ referenceTargets?: readonly CompileResourceReferenceTarget[];
327
+ }
328
+ export declare function compileCourse(options: CompileCourseOptions): Promise<CompileResult>;
329
+ interface ProjectAssetNameOptions {
330
+ /** Directory containing the manifest, or an explicitly chosen root for standalone use. */
331
+ projectRoot: string;
332
+ projectNamespace: string;
354
333
  }
355
- //#endregion
356
- //#region src/compile/index.d.ts
334
+ /** Create the project's naming policy without reading or requiring a manifest. */
335
+ export declare function createProjectAssetNameGenerator(options: ProjectAssetNameOptions): AssetNameGenerator;
357
336
  interface CompileOptions {
358
337
  dir: string;
359
338
  validation?: CompileValidationOptions;
360
- assets?: AssetCompilationOptions;
339
+ /** Optional application-supplied inventory for explicit resource references. */
340
+ referenceTargets?: readonly CompileResourceReferenceTarget[];
361
341
  }
362
- declare function compile(options: CompileOptions): Promise<CompileResult>;
342
+ /** Compile exactly the project declared by .topik.yaml in dir. */
343
+ export declare function compile(options: CompileOptions): Promise<CompileResult>;
363
344
  interface LintResult {
364
345
  diagnostics: CompileResult["diagnostics"];
365
346
  }
366
- declare function lint(options: CompileOptions): Promise<LintResult>;
367
- //#endregion
368
- //#region src/validate.d.ts
347
+ export declare function lint(options: CompileOptions): Promise<LintResult>;
369
348
  interface ValidationError {
370
349
  id?: "resource-invalid" | "resource-unsupported-type" | "resource-unsupported-version" | TopikAssetDiagnosticId;
371
350
  resource: string;
@@ -377,74 +356,29 @@ interface ValidationResult {
377
356
  errors: ValidationError[];
378
357
  }
379
358
  /** Validate the resources produced by `compile` and the CLI export. */
380
- declare function validateResources(resources: readonly unknown[]): ValidationResult;
381
- //#endregion
382
- //#region src/wiki-navigation.d.ts
383
- type ResolvedWikiPage = {
384
- /** The compiled WikiPage resource name. */
385
- page: string;
386
- /** The page navigation node from the Wiki resource. */
387
- node: WikiPageNavNode;
388
- /** Public path without a leading slash. */
389
- route: string;
390
- /** Logical Markdown source path without an extension. */
391
- sourcePath: string;
392
- /** Internal navigation containers from outermost to innermost. */
393
- ancestors: readonly WikiNavContainerNode[];
394
- };
395
- type ResolvedWikiNavigation = {
396
- pages: readonly ResolvedWikiPage[];
397
- pageByName: ReadonlyMap<string, ResolvedWikiPage>;
398
- pageByRoute: ReadonlyMap<string, ResolvedWikiPage>;
399
- };
400
- type ResolvedWikiContentLink = {
401
- page: ResolvedWikiPage;
402
- route: string;
403
- hash: string;
404
- };
405
- /** Returns true for tab, dropdown, and group nodes containing navigation children. */
406
- declare function hasWikiNavChildren(node: WikiNavNode): node is WikiNavContainerNode;
407
- declare function isInternalWikiTab(node: WikiNavNode): node is WikiInternalTabNavNode;
408
- declare function isExternalWikiTab(node: WikiNavNode): node is WikiExternalTabNavNode;
409
- declare function isInternalWikiDropdown(node: WikiNavNode): node is WikiInternalDropdownNavNode;
410
- declare function isExternalWikiDropdown(node: WikiNavNode): node is WikiExternalDropdownNavNode;
411
- /** Resolves page routes, source paths, and navigation ancestry from a compiled Wiki tree. */
412
- declare function resolveWikiNavigation(navigation: WikiNavigation | readonly WikiNavNode[]): ResolvedWikiNavigation;
413
- /** Finds the first page node in navigation order, ignoring external destinations. */
414
- declare function findFirstWikiPage(navigation: WikiNavigation | readonly WikiNavNode[]): WikiPageNavNode | null;
415
- /** Returns the internal containers owning a page, or an empty array for an unknown page. */
416
- declare function findWikiPageAncestors(resolved: ResolvedWikiNavigation, pageName: string): readonly WikiNavContainerNode[];
417
- /** Resolves an internal Markdown link against the logical source path of its current page. */
418
- declare function resolveWikiContentHref(href: string, currentPageName: string, resolved: ResolvedWikiNavigation): ResolvedWikiContentLink | null;
419
- declare function joinWikiPath(prefix: string, slug?: string): string;
420
- type InternalWikiTab = WikiInternalTabNavNode;
421
- type ExternalWikiTab = WikiExternalTabNavNode;
422
- type InternalWikiDropdown = WikiInternalDropdownNavNode;
423
- type ExternalWikiDropdown = WikiExternalDropdownNavNode;
424
- type WikiSwitcherNode = WikiTabNavNode | WikiDropdownNavNode;
425
- //#endregion
426
- //#region src/watch.d.ts
359
+ export declare function validateResources(resources: readonly unknown[]): ValidationResult;
427
360
  interface WatchOptions {
428
361
  dir: string;
429
362
  signal?: AbortSignal;
430
- assets?: AssetCompilationOptions;
431
363
  }
432
364
  type UpdateListener = (key: string, resource: Resource) => void;
433
365
  type ErrorListener = (error: Error) => void;
366
+ type PreviewStateListener = (state: PreviewState) => void;
434
367
  interface Watcher {
435
- /** Current compiled resources, keyed by `Type/name`. */
368
+ /** Compatibility inventory; replaced completely before any success notification. */
436
369
  resources: Map<string, Resource>;
437
- /** Current deduplicated local payloads, keyed by compilation-relative output path. */
438
370
  payloads: Map<string, AssetPayload>;
371
+ /** Immutable, complete authoritative state. Treat resources/order/payloads as one commit. */
372
+ readonly state: PreviewState;
373
+ on(event: "preview-state", listener: PreviewStateListener): this;
439
374
  on(event: "update", listener: UpdateListener): this;
440
375
  on(event: "error", listener: ErrorListener): this;
376
+ off(event: "preview-state", listener: PreviewStateListener): this;
441
377
  off(event: "update", listener: UpdateListener): this;
442
378
  off(event: "error", listener: ErrorListener): this;
443
379
  close(): Promise<void>;
444
380
  }
445
- declare function watch(options: WatchOptions): Promise<Watcher>;
446
- //#endregion
447
- //#region src/assets/path.d.ts
381
+ export declare function watch(options: WatchOptions): Promise<Watcher>;
448
382
  interface ValidateTopikPathOptions {
449
383
  bindingRoot?: string;
450
384
  capabilities?: {
@@ -458,26 +392,22 @@ interface ValidTopikPath {
458
392
  collisionKey: string;
459
393
  utf8Bytes: number;
460
394
  }
461
- declare function validateTopikPath(input: string | Uint8Array, options?: ValidateTopikPathOptions): TopikAssetResult<ValidTopikPath>;
462
- declare function computeTopikPathCollisionKey(path: string, options?: ValidateTopikPathOptions): TopikAssetResult<string>;
463
- declare function validateTopikPathSet(paths: readonly string[], options?: ValidateTopikPathOptions): TopikAssetResult<Map<string, string>>;
395
+ export declare function validateTopikPath(input: string | Uint8Array, options?: ValidateTopikPathOptions): TopikAssetResult<ValidTopikPath>;
396
+ export declare function computeTopikPathCollisionKey(path: string, options?: ValidateTopikPathOptions): TopikAssetResult<string>;
397
+ export declare function validateTopikPathSet(paths: readonly string[], options?: ValidateTopikPathOptions): TopikAssetResult<Map<string, string>>;
464
398
  /** Unicode 17 NFKC casefold for topik-path-v1-admitted input. */
465
- declare function toNfkcCasefold(value: string): string;
466
- //#endregion
467
- //#region src/assets/json.d.ts
468
- declare class TopikJsonSyntaxError extends SyntaxError {
399
+ export declare function toNfkcCasefold(value: string): string;
400
+ export declare class TopikJsonSyntaxError extends SyntaxError {
469
401
  readonly offset: number;
470
402
  readonly duplicatePointer?: string | undefined;
471
403
  constructor(message: string, offset: number, duplicatePointer?: string | undefined);
472
404
  }
473
- declare function parseStrictTopikJson(source: string, maxDepth?: number): unknown;
405
+ export declare function parseStrictTopikJson(source: string, maxDepth?: number): unknown;
474
406
  /** RFC 8785 scalar/member rules with Topik's two-space layout and final LF. */
475
- declare function serializeTopikJson(value: unknown): string;
476
- declare function topikJsonDescriptor(): {
407
+ export declare function serializeTopikJson(value: unknown): string;
408
+ export declare function topikJsonDescriptor(): {
477
409
  id: typeof TOPIK_JSON_VERSION;
478
410
  };
479
- //#endregion
480
- //#region src/assets/files.d.ts
481
411
  type PortableAssetFileType = "regular" | "symlink" | "hardlink" | "gitlink" | "device" | "fifo" | "socket" | "special" | "sparse" | "archive-link";
482
412
  interface PortableAssetFileDescriptor {
483
413
  path: string;
@@ -491,21 +421,282 @@ interface PortableAssetFileDescriptor {
491
421
  contentFilter?: string;
492
422
  workingTreeEncoding?: string;
493
423
  }
494
- declare function validatePortableAssetFile(file: PortableAssetFileDescriptor): TopikAssetResult<PortableAssetFileDescriptor>;
495
- declare function validatePortableAssetTree(files: readonly PortableAssetFileDescriptor[]): TopikAssetResult<readonly PortableAssetFileDescriptor[]>;
424
+ export declare function validatePortableAssetFile(file: PortableAssetFileDescriptor): TopikAssetResult<PortableAssetFileDescriptor>;
425
+ export declare function validatePortableAssetTree(files: readonly PortableAssetFileDescriptor[]): TopikAssetResult<readonly PortableAssetFileDescriptor[]>;
496
426
  interface ReadPortableAssetFileOptions {
497
427
  root: string;
498
428
  path: string;
429
+ /** Optional tighter read limit; cannot exceed the portable asset maximum. */
430
+ maxBytes?: number;
499
431
  }
500
432
  /** Filesystem reader using no-follow traversal and stable same-handle identity checks. */
501
- declare function readPortableAssetFile(options: ReadPortableAssetFileOptions): Promise<TopikAssetResult<PortableAssetFileDescriptor>>;
502
- declare function looksLikeGitLfsPointer(bytes: Uint8Array): boolean;
503
- //#endregion
504
- //#region src/assets/media.d.ts
505
- declare const TOPIK_UNRESOLVED_ACTIVE_CONTENT_TYPE: "application/x-topik-active-content";
433
+ export declare function readPortableAssetFile(options: ReadPortableAssetFileOptions): Promise<TopikAssetResult<PortableAssetFileDescriptor>>;
434
+ export declare function looksLikeGitLfsPointer(bytes: Uint8Array): boolean;
435
+ export declare const TOPIK_UNRESOLVED_ACTIVE_CONTENT_TYPE: "application/x-topik-active-content";
506
436
  /** Sniff exact bytes conservatively. Unknown safe bytes remain opaque downloads. */
507
- declare function sniffPortableMediaType(bytes: Uint8Array): string;
508
- declare function isTopikActiveMediaType(mediaType: string): boolean;
509
- declare function isInlineMediaCompatible(mediaType: string, role: string): boolean;
510
- //#endregion
511
- export { ASSET_API_VERSION, ASSET_SCHEMA_ID, ASSET_TYPE, type AssetBlobUri, AssetCompilationError, type AssetCompilationOptions, type AssetCompilationResult, type AssetPayload, type CollectionConfig, type CompileAssetResourcesInput, CompileError, type CompileGuidesOptions, type CompileOptions, type CompileResult, type CompileValidationOptions, type CompileWikiOptions, type CompiledAsset, type CompiledResource, type ContentBearingResource, type ExternalWikiDropdown, type ExternalWikiTab, type GenerateAutomaticAssetNameOptions, type GeneratedAssetName, type InternalWikiDropdown, type InternalWikiTab, type LinkValidationPolicy, type LintResult, type ParsedAsset, type PortableAssetFileDescriptor, type PortableAssetFileType, PublicCompileError, type PublicCompileErrorId, type ReadPortableAssetFileOptions, type ResolvedWikiContentLink, type ResolvedWikiNavigation, type ResolvedWikiPage, type Resource, type ResourceType, type SourceResource, TOPIK_ASSET_CORRELATION_ID_PATTERN, TOPIK_ASSET_DEFAULT_CORRELATION_ID, TOPIK_ASSET_DIAGNOSTIC_IDS, TOPIK_ASSET_LIMITS, TOPIK_ASSET_NAME_VERSION, TOPIK_ASSET_REFERENCE_VERSION, TOPIK_BLOB_OUTPUT_PREFIX, TOPIK_JSON_VERSION, TOPIK_MATERIALIZATION_VERSION, TOPIK_PATH_V1_DESCRIPTOR, TOPIK_PATH_VERSION, TOPIK_UNRESOLVED_ACTIVE_CONTENT_TYPE, type TopikAssetCorrelationId, type TopikAssetDiagnostic, type TopikAssetDiagnosticId, type TopikAssetDiagnosticLocation, type TopikAssetPathDiagnosticReason, type TopikAssetRecoveryCategory, type TopikAssetReferenceMappingV1, type TopikAssetResult, type TopikAssetSemanticRecordV1, TopikJsonSyntaxError, type TopikMaterializationPayloadInput, type TopikMaterializationPayloadV1, type TopikMaterializationRecordV1, type TopikMaterializationResourceInput, type TopikMaterializationResourceV1, type ValidTopikPath, type ValidateTopikPathOptions, type ValidationError, type ValidationResult, type WatchOptions, type Watcher, type WikiConfig, type WikiSwitcherNode, compareTopikAssetIdentities, compile, compileAssetResources, compileGuides, compileWiki, computeTopikPathCollisionKey, correlateTopikAssetResult, createTopikAssetSemanticRecord, createTopikMaterializationRecord, digestTopikAssetSemanticRecord, digestTopikMaterializationRecord, findFirstWikiPage, findWikiPageAncestors, generateAutomaticAssetName, hasWikiNavChildren, isAssetBlobUri, isErrorDiagnostic, isExternalWikiDropdown, isExternalWikiTab, isGeneratedAssetName, isInlineMediaCompatible, isInternalWikiDropdown, isInternalWikiTab, isTopikActiveMediaType, joinWikiPath, lint, looksLikeGitLfsPointer, pagePathToName, parseAsset, parseAssetBlobUri, parseCollectionConfig, parseGeneratedAssetName, parseStrictTopikJson, parseWikiConfig, publicCompileErrorMessage, readPortableAssetFile, resolveWikiContentHref, resolveWikiNavigation, serializeAsset, serializeTopikJson, sniffPortableMediaType, toNfkcCasefold, topikAssetNameDescriptor, topikJsonDescriptor, validateAssetBlobUri, validateAssetValue, validatePortableAssetFile, validatePortableAssetTree, validateResources, validateStableSourceNamespace, validateTopikMaterializationRecord, validateTopikPath, validateTopikPathSet, watch };
437
+ export declare function sniffPortableMediaType(bytes: Uint8Array): string;
438
+ export declare function isTopikActiveMediaType(mediaType: string): boolean;
439
+ export declare function isInlineMediaCompatible(mediaType: string, role: string): boolean;
440
+ interface SourceByteRange {
441
+ start: number;
442
+ end: number;
443
+ }
444
+ interface SourceFieldEvidence {
445
+ selector: string;
446
+ value?: SourceByteRange;
447
+ entry?: SourceByteRange;
448
+ insertion: number;
449
+ }
450
+ interface SourceByteEdit extends SourceByteRange {
451
+ selector: string;
452
+ oldSha256: string;
453
+ replacement: Uint8Array;
454
+ }
455
+ export declare const SOURCE_WRITER_VERSION: "topik-source-writer-v1";
456
+ export declare const SOURCE_PROJECT_LIMITS: {
457
+ readonly maxFiles: 10000;
458
+ readonly maxFileBytes: 268435456;
459
+ readonly maxTreeBytes: 536870912;
460
+ };
461
+ export declare const SOURCE_WRITER_DESCRIPTOR: {
462
+ readonly writer: "topik-source-writer-v1";
463
+ readonly manifest: 1;
464
+ readonly sourceVersions: readonly [0, 1];
465
+ readonly formatter: 1;
466
+ readonly contentSchema: "0.2.2";
467
+ readonly resourceSchema: "v1";
468
+ readonly references: "source-links-v5";
469
+ readonly provenance: 7;
470
+ readonly graph: "authored-resource-bytes-v1";
471
+ readonly packageVersion: string;
472
+ };
473
+ interface SourceTreeFile {
474
+ path: string;
475
+ mode: "100644" | "100755";
476
+ bytes: Uint8Array;
477
+ }
478
+ interface SourceDocumentProvenance {
479
+ resource: string;
480
+ apiVersion: Resource["apiVersion"];
481
+ type: Resource["type"];
482
+ name: string;
483
+ path: string;
484
+ config: string;
485
+ kind: ManifestSourceProvenance["kind"];
486
+ directory: string;
487
+ sourceVersion?: 1;
488
+ sha256: string;
489
+ mode: SourceTreeFile["mode"];
490
+ body?: SourceByteRange;
491
+ frontmatter?: SourceByteRange;
492
+ fields: readonly SourceFieldEvidence[];
493
+ fieldOrigins: readonly SourceFieldOrigin[];
494
+ /** Recognized legacy metadata whose compiled value would lose authored meaning. */
495
+ lossyMetadata?: readonly string[];
496
+ /** Context travels with immutable saved source; a later source move must not reinterpret it. */
497
+ sourceContext: {
498
+ path: string;
499
+ extension: string;
500
+ /** Key in SourceProject.wikiContexts; retain that snapshot with saved content. */
501
+ wiki?: string;
502
+ /** Key in SourceProject.courseContexts for a Course page's immutable saved links. */
503
+ course?: string;
504
+ };
505
+ references: readonly (TopikNavigationReference & {
506
+ target?: string;
507
+ search?: string;
508
+ hash?: string;
509
+ })[];
510
+ /** Complete derived Asset identity closure for this compiled resource. */
511
+ assetReferences: readonly string[];
512
+ }
513
+ interface SourceFieldOrigin {
514
+ field: string;
515
+ origin: "explicit" | "derived" | "inherited" | "default";
516
+ path?: string;
517
+ selector?: string;
518
+ range?: SourceByteRange;
519
+ }
520
+ interface SourceConfigurationProvenance {
521
+ path: string;
522
+ sha256: string;
523
+ mode: SourceTreeFile["mode"];
524
+ fields: readonly SourceFieldEvidence[];
525
+ insertion: number;
526
+ }
527
+ interface SourceProject {
528
+ tree: readonly SourceTreeFile[];
529
+ treeDigest: string;
530
+ manifest: TopikManifest;
531
+ manifestSha256: string;
532
+ compilation: ManifestCompileResult;
533
+ documents: readonly SourceDocumentProvenance[];
534
+ configurations: readonly SourceConfigurationProvenance[];
535
+ wikiContexts: Readonly<Record<string, Wiki>>;
536
+ courseContexts: Readonly<Record<string, CourseReferenceContext>>;
537
+ descriptor: typeof SOURCE_WRITER_DESCRIPTOR;
538
+ }
539
+ export declare function digestSourceTree(tree: readonly SourceTreeFile[]): string;
540
+ /** Seal the exact desired authoring graph without parsing or formatting its content. */
541
+ export declare function digestSourceResourceGraph(resources: readonly Resource[]): string;
542
+ /** Inspection compiles exactly the manifest tree and retains original documents and byte ranges. */
543
+ export declare function readSourceProject(input: {
544
+ tree: readonly SourceTreeFile[];
545
+ }): Promise<SourceProject>;
546
+ type SourceAssetReferenceContexts = Readonly<Record<string, Readonly<Record<string, string>>>>;
547
+ interface SourceInitializationIntent {
548
+ namespace: string;
549
+ source: TopikManifestSource & {
550
+ id: string;
551
+ title: string;
552
+ assetDirectory?: string;
553
+ };
554
+ }
555
+ interface SourceMediaSelection {
556
+ name: string;
557
+ filename: string;
558
+ sha256: string;
559
+ bytes: Uint8Array;
560
+ }
561
+ interface InitializeSourceProjectInput {
562
+ /** Full occupied-path inventory; missing/invalid manifests are never admitted as empty projects. */
563
+ tree: readonly SourceTreeFile[];
564
+ expectedTreeDigest: string;
565
+ packageCohort: string;
566
+ /** This explicit reviewed intent is sealed by the application before planning. */
567
+ intent: SourceInitializationIntent;
568
+ resources: readonly Resource[];
569
+ media?: readonly SourceMediaSelection[];
570
+ /** Immutable Wiki context retained with each saved page body. */
571
+ referenceContexts?: Readonly<Record<string, Wiki>>;
572
+ courseReferenceContexts?: Readonly<Record<string, CourseReferenceContext>>;
573
+ /** Explicit new Guide or CoursePage file paths, independently admitted in createPaths. */
574
+ documentPaths?: Readonly<Record<string, string>>;
575
+ assetReferenceContexts?: SourceAssetReferenceContexts;
576
+ /** Exact expected-absence paths admitted from the complete inventory. */
577
+ createPaths: readonly string[];
578
+ }
579
+ /** Initialization is distinct from adding a source to a valid existing manifest. */
580
+ export declare function initializeSourceProject(input: InitializeSourceProjectInput): Promise<SourcePlanResult>;
581
+ interface AddSourceToProjectInput {
582
+ project: SourceProject;
583
+ expectedTreeDigest: string;
584
+ packageCohort: string;
585
+ source: SourceInitializationIntent["source"];
586
+ resources: readonly Resource[];
587
+ media?: readonly SourceMediaSelection[];
588
+ referenceContexts?: Readonly<Record<string, Wiki>>;
589
+ courseReferenceContexts?: Readonly<Record<string, CourseReferenceContext>>;
590
+ documentPaths?: Readonly<Record<string, string>>;
591
+ assetReferenceContexts?: SourceAssetReferenceContexts;
592
+ createPaths: readonly string[];
593
+ manifestAuthority: SourceSharedAuthority;
594
+ }
595
+ /** Adding a declaration preserves the existing namespace, order and every original source. */
596
+ export declare function addSourceToProject(input: AddSourceToProjectInput): Promise<SourcePlanResult>;
597
+ interface SourcePlanDiagnostic {
598
+ code: string;
599
+ message: string;
600
+ resource?: string;
601
+ path?: string;
602
+ /** One-based lines in the compiled document body, excluding frontmatter. */
603
+ lines?: readonly number[];
604
+ sourceIndex?: number;
605
+ kind?: "wiki" | "collection" | "course";
606
+ config?: string;
607
+ }
608
+ type SourceResourceOperation = {
609
+ kind: "update" | "delete";
610
+ resource: string;
611
+ } | {
612
+ kind: "move";
613
+ resource: string;
614
+ path: string;
615
+ } | {
616
+ kind: "create";
617
+ resource: string;
618
+ config: string;
619
+ path?: string;
620
+ };
621
+ interface SourceExclusiveAuthority {
622
+ path: string;
623
+ sha256: string;
624
+ mode: SourceTreeFile["mode"];
625
+ }
626
+ interface SourceSharedAuthority extends SourceExclusiveAuthority {
627
+ fields: readonly SourceFieldEvidence[];
628
+ }
629
+ interface SourceWriteAuthority {
630
+ /** Resources whose authored or shared referenced facts may change, admitted independently. */
631
+ resources: readonly string[];
632
+ exclusive: readonly SourceExclusiveAuthority[];
633
+ shared: readonly SourceSharedAuthority[];
634
+ create: readonly string[];
635
+ }
636
+ interface SourceFileChange {
637
+ kind: "create" | "update" | "delete";
638
+ path: string;
639
+ base: {
640
+ sha256: string;
641
+ mode: SourceTreeFile["mode"];
642
+ } | null;
643
+ candidate: {
644
+ sha256: string;
645
+ mode: SourceTreeFile["mode"];
646
+ bytes: Uint8Array;
647
+ } | null;
648
+ sharedEdits?: readonly SourceByteEdit[];
649
+ }
650
+ interface SourceUpdatePlan {
651
+ assetMappings: readonly {
652
+ from: string;
653
+ to: string;
654
+ path: string;
655
+ }[];
656
+ descriptor: typeof SOURCE_WRITER_DESCRIPTOR;
657
+ packageCohort: string;
658
+ baseTreeDigest: string;
659
+ desiredGraphDigest: string;
660
+ candidateTreeDigest: string;
661
+ planDigest: string;
662
+ changes: readonly SourceFileChange[];
663
+ candidate: SourceProject;
664
+ affectedResources: readonly string[];
665
+ derivedRepairs: readonly {
666
+ resource: string;
667
+ kind: "navigation" | "reference";
668
+ position?: string;
669
+ before?: string;
670
+ after?: string;
671
+ target?: string;
672
+ }[];
673
+ }
674
+ type SourcePlanResult = {
675
+ ok: true;
676
+ plan: SourceUpdatePlan;
677
+ } | {
678
+ ok: false;
679
+ diagnostics: readonly SourcePlanDiagnostic[];
680
+ };
681
+ interface PlanSourceUpdatesInput {
682
+ project: SourceProject;
683
+ expectedTreeDigest: string;
684
+ packageCohort: string;
685
+ /** Complete project graph, including untouched declarations and derived Assets. */
686
+ desiredResources: readonly Resource[];
687
+ operations: readonly SourceResourceOperation[];
688
+ authority: SourceWriteAuthority;
689
+ /** Explicit reviewed opt-in; reserved legacy keys still block it. */
690
+ optInConfigs?: readonly string[];
691
+ /** Retained portable context of saved authoring content, before previous source repairs. */
692
+ referenceContexts?: Readonly<Record<string, Wiki>>;
693
+ /** Retained Course route/source snapshots keyed by CoursePage identity. */
694
+ courseReferenceContexts?: Readonly<Record<string, CourseReferenceContext>>;
695
+ assetReferenceContexts?: SourceAssetReferenceContexts;
696
+ media?: readonly (SourceMediaSelection & {
697
+ config: string;
698
+ })[];
699
+ }
700
+ /** The complete candidate is compiled before any applicable file changes are returned. */
701
+ export declare function planSourceUpdates(input: PlanSourceUpdatesInput): Promise<SourcePlanResult>;
702
+ export { ASSET_API_VERSION, ASSET_SCHEMA_ID, ASSET_TYPE, type AddSourceToProjectInput, type AssetBlobUri, AssetCompilationError, type AssetCompilationOptions, type AssetCompilationResult, type AssetNameGenerator, type AssetNameInput, type AssetPayload, type CollectionConfig, type CompileAssetResourcesInput, type CompileCourseOptions, type CompileGuidesOptions, type CompileOptions, type CompileResourceLinksInput, type CompileResourceReferenceTarget, type CompileResult, type CompileValidationOptions, type CompileWikiOptions, type CompiledAsset, type CompiledResource, type CompiledResourceReference, type ContentBearingResource, type CourseConfig, type CourseModuleConfig, CourseNavigationIndex, CourseNavigationModule, type CourseReferenceContext, type DiscoverResourceOptions, type ExternalWikiDropdown, type ExternalWikiTab, type GenerateAutomaticAssetNameOptions, type GeneratedAssetName, type InitializeSourceProjectInput, type InternalWikiDropdown, type InternalWikiTab, type LinkValidationPolicy, type LintResult, type ManifestCompileResult, type ManifestSourceDescriptor, type ManifestSourceProvenance, type ParsedAsset, type PlanSourceUpdatesInput, type PortableAssetFileDescriptor, type PortableAssetFileType, PreviewDiagnostic, PreviewPayloadDescriptor, PreviewState, type ProjectAssetNameOptions, type PublicCompileErrorId, type ReadPortableAssetFileOptions, type ResolvedCourseContentLink, type ResolvedCourseContentReference, type ResolvedCourseNavigation, type ResolvedCoursePage, type ResolvedWikiContentLink, type ResolvedWikiContentReference, type ResolvedWikiNavigation, type ResolvedWikiPage, type Resource, type ResourceType, type SourceAssetsConfig, type SourceByteEdit, type SourceByteRange, type SourceConfigurationProvenance, type SourceDocumentProvenance, type SourceExclusiveAuthority, type SourceFieldEvidence, type SourceFieldOrigin, type SourceFileChange, type SourceInitializationIntent, type SourceMediaSelection, type SourcePlanDiagnostic, type SourcePlanResult, type SourceProject, type SourceResource, type SourceResourceDiscovery, type SourceResourceOperation, type SourceSharedAuthority, type SourceTreeFile, type SourceUpdatePlan, type SourceWriteAuthority, TOPIK_ASSET_CORRELATION_ID_PATTERN, TOPIK_ASSET_DEFAULT_CORRELATION_ID, TOPIK_ASSET_DIAGNOSTIC_IDS, TOPIK_ASSET_LIMITS, TOPIK_ASSET_NAME_VERSION, TOPIK_ASSET_REFERENCE_VERSION, TOPIK_BLOB_OUTPUT_PREFIX, TOPIK_JSON_VERSION, TOPIK_MATERIALIZATION_VERSION, TOPIK_PATH_V1_DESCRIPTOR, TOPIK_PATH_VERSION, TOPIK_PREVIEW_PROTOCOL, type TopikAssetCorrelationId, type TopikAssetDiagnostic, type TopikAssetDiagnosticId, type TopikAssetDiagnosticLocation, type TopikAssetPathDiagnosticReason, type TopikAssetRecoveryCategory, type TopikAssetReferenceMappingV1, type TopikAssetResult, type TopikAssetSemanticRecordV1, type TopikManifest, type TopikManifestSource, type TopikMaterializationPayloadInput, type TopikMaterializationPayloadV1, type TopikMaterializationRecordV1, type TopikMaterializationResourceInput, type TopikMaterializationResourceV1, type ValidTopikPath, type ValidateTopikPathOptions, type ValidationError, type ValidationResult, type WatchOptions, type Watcher, type WikiConfig, type WikiSwitcherNode, compareTopikAssetIdentities, compileAssetResources, correlateTopikAssetResult, createTopikAssetSemanticRecord, createTopikMaterializationRecord, digestTopikAssetSemanticRecord, digestTopikMaterializationRecord, findFirstWikiPage, findWikiPageAncestors, generateAutomaticAssetName, hasWikiNavChildren, isAssetBlobUri, isExternalWikiDropdown, isExternalWikiTab, isGeneratedAssetName, isInternalWikiDropdown, isInternalWikiTab, joinWikiPath, parseAsset, parseAssetBlobUri, parseGeneratedAssetName, resolveCourseContentHref, resolveCourseContentReference, resolveCourseNavigation, resolveWikiContentHref, resolveWikiContentReference, resolveWikiNavigation, serializeAsset, topikAssetNameDescriptor, validateAssetBlobUri, validateAssetValue, validateProjectNamespace, validateTopikMaterializationRecord };