@omgbase/core 0.1.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.
Files changed (214) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/cli/eval-matcher.d.ts +13 -0
  3. package/dist/src/cli/eval-matcher.js +36 -0
  4. package/dist/src/core/attach.d.ts +5 -0
  5. package/dist/src/core/attach.js +38 -0
  6. package/dist/src/core/cursor.d.ts +11 -0
  7. package/dist/src/core/cursor.js +35 -0
  8. package/dist/src/core/hash.d.ts +23 -0
  9. package/dist/src/core/hash.js +82 -0
  10. package/dist/src/core/ids.d.ts +6 -0
  11. package/dist/src/core/ids.js +26 -0
  12. package/dist/src/core/index.d.ts +1 -0
  13. package/dist/src/core/index.js +2 -0
  14. package/dist/src/core/ingest.d.ts +43 -0
  15. package/dist/src/core/ingest.js +287 -0
  16. package/dist/src/core/order-key.d.ts +8 -0
  17. package/dist/src/core/order-key.js +72 -0
  18. package/dist/src/core/parse/parse.d.ts +3 -0
  19. package/dist/src/core/parse/parse.js +104 -0
  20. package/dist/src/core/parse/render.d.ts +3 -0
  21. package/dist/src/core/parse/render.js +20 -0
  22. package/dist/src/core/parse/tree.d.ts +8 -0
  23. package/dist/src/core/parse/tree.js +43 -0
  24. package/dist/src/core/parse/types.d.ts +52 -0
  25. package/dist/src/core/parse/types.js +9 -0
  26. package/dist/src/core/read/document.d.ts +107 -0
  27. package/dist/src/core/read/document.js +191 -0
  28. package/dist/src/core/read/nodes.d.ts +47 -0
  29. package/dist/src/core/read/nodes.js +102 -0
  30. package/dist/src/core/read/outline.d.ts +12 -0
  31. package/dist/src/core/read/outline.js +76 -0
  32. package/dist/src/core/read/reader.d.ts +125 -0
  33. package/dist/src/core/read/reader.js +206 -0
  34. package/dist/src/core/read/refs.d.ts +15 -0
  35. package/dist/src/core/read/refs.js +51 -0
  36. package/dist/src/core/store/edges.d.ts +26 -0
  37. package/dist/src/core/store/edges.js +101 -0
  38. package/dist/src/core/store/fts.d.ts +10 -0
  39. package/dist/src/core/store/fts.js +22 -0
  40. package/dist/src/core/store/gc.d.ts +18 -0
  41. package/dist/src/core/store/gc.js +69 -0
  42. package/dist/src/core/store/nodes.d.ts +5 -0
  43. package/dist/src/core/store/nodes.js +57 -0
  44. package/dist/src/core/store/properties.d.ts +38 -0
  45. package/dist/src/core/store/properties.js +177 -0
  46. package/dist/src/core/store/rebuild.d.ts +3 -0
  47. package/dist/src/core/store/rebuild.js +29 -0
  48. package/dist/src/core/store/schema.d.ts +9 -0
  49. package/dist/src/core/store/schema.js +386 -0
  50. package/dist/src/core/store/sections.d.ts +2 -0
  51. package/dist/src/core/store/sections.js +29 -0
  52. package/dist/src/core/store/store.d.ts +24 -0
  53. package/dist/src/core/store/store.js +164 -0
  54. package/dist/src/core/store/writers.d.ts +52 -0
  55. package/dist/src/core/store/writers.js +89 -0
  56. package/dist/src/core/vec.d.ts +10 -0
  57. package/dist/src/core/vec.js +33 -0
  58. package/dist/src/format/adapter.d.ts +97 -0
  59. package/dist/src/format/adapter.js +14 -0
  60. package/dist/src/format/index.d.ts +6 -0
  61. package/dist/src/format/index.js +15 -0
  62. package/dist/src/format/json.d.ts +3 -0
  63. package/dist/src/format/json.js +324 -0
  64. package/dist/src/format/markdown.d.ts +5 -0
  65. package/dist/src/format/markdown.js +217 -0
  66. package/dist/src/format/registry.d.ts +6 -0
  67. package/dist/src/format/registry.js +24 -0
  68. package/dist/src/format/yaml.d.ts +5 -0
  69. package/dist/src/format/yaml.js +413 -0
  70. package/dist/src/graph/extract.d.ts +38 -0
  71. package/dist/src/graph/extract.js +242 -0
  72. package/dist/src/graph/history.d.ts +103 -0
  73. package/dist/src/graph/history.js +210 -0
  74. package/dist/src/graph/inbound-links.d.ts +33 -0
  75. package/dist/src/graph/inbound-links.js +130 -0
  76. package/dist/src/graph/link-destinations.d.ts +22 -0
  77. package/dist/src/graph/link-destinations.js +84 -0
  78. package/dist/src/graph/link-health.d.ts +79 -0
  79. package/dist/src/graph/link-health.js +146 -0
  80. package/dist/src/graph/links.d.ts +23 -0
  81. package/dist/src/graph/links.js +42 -0
  82. package/dist/src/index.d.ts +60 -0
  83. package/dist/src/index.js +70 -0
  84. package/dist/src/mcp/errors.d.ts +17 -0
  85. package/dist/src/mcp/errors.js +18 -0
  86. package/dist/src/mcp/graph.d.ts +63 -0
  87. package/dist/src/mcp/graph.js +212 -0
  88. package/dist/src/mcp/reference.d.ts +1 -0
  89. package/dist/src/mcp/reference.js +227 -0
  90. package/dist/src/mcp/server.d.ts +30 -0
  91. package/dist/src/mcp/server.js +1076 -0
  92. package/dist/src/mcp/stdio.d.ts +13 -0
  93. package/dist/src/mcp/stdio.js +24 -0
  94. package/dist/src/migrate/mrplex.d.ts +27 -0
  95. package/dist/src/migrate/mrplex.js +29 -0
  96. package/dist/src/mutate/apply.d.ts +83 -0
  97. package/dist/src/mutate/apply.js +302 -0
  98. package/dist/src/mutate/doc-store.d.ts +49 -0
  99. package/dist/src/mutate/doc-store.js +71 -0
  100. package/dist/src/mutate/docs.d.ts +60 -0
  101. package/dist/src/mutate/docs.js +232 -0
  102. package/dist/src/mutate/known-ids.d.ts +12 -0
  103. package/dist/src/mutate/known-ids.js +154 -0
  104. package/dist/src/mutate/load.d.ts +3 -0
  105. package/dist/src/mutate/load.js +66 -0
  106. package/dist/src/mutate/lower.d.ts +32 -0
  107. package/dist/src/mutate/lower.js +232 -0
  108. package/dist/src/mutate/macros.d.ts +91 -0
  109. package/dist/src/mutate/macros.js +230 -0
  110. package/dist/src/mutate/ops.d.ts +40 -0
  111. package/dist/src/mutate/ops.js +513 -0
  112. package/dist/src/mutate/opset.d.ts +92 -0
  113. package/dist/src/mutate/opset.js +79 -0
  114. package/dist/src/mutate/plan-update.d.ts +51 -0
  115. package/dist/src/mutate/plan-update.js +187 -0
  116. package/dist/src/mutate/tree.d.ts +46 -0
  117. package/dist/src/mutate/tree.js +167 -0
  118. package/dist/src/oqx/run.d.ts +1 -0
  119. package/dist/src/oqx/run.js +6 -0
  120. package/dist/src/oqx-js/context.d.ts +23 -0
  121. package/dist/src/oqx-js/context.js +564 -0
  122. package/dist/src/oqx-js/planner.d.ts +10 -0
  123. package/dist/src/oqx-js/planner.js +91 -0
  124. package/dist/src/oqx-js/run.d.ts +41 -0
  125. package/dist/src/oqx-js/run.js +332 -0
  126. package/dist/src/oqx-js/sql/translate.d.ts +27 -0
  127. package/dist/src/oqx-js/sql/translate.js +290 -0
  128. package/dist/src/reconcile/crossdoc.d.ts +34 -0
  129. package/dist/src/reconcile/crossdoc.js +76 -0
  130. package/dist/src/reconcile/eval/generator.d.ts +21 -0
  131. package/dist/src/reconcile/eval/generator.js +129 -0
  132. package/dist/src/reconcile/eval/metrics.d.ts +32 -0
  133. package/dist/src/reconcile/eval/metrics.js +74 -0
  134. package/dist/src/reconcile/flatten.d.ts +12 -0
  135. package/dist/src/reconcile/flatten.js +37 -0
  136. package/dist/src/reconcile/phase5.d.ts +8 -0
  137. package/dist/src/reconcile/phase5.js +167 -0
  138. package/dist/src/reconcile/phase6a.d.ts +2 -0
  139. package/dist/src/reconcile/phase6a.js +159 -0
  140. package/dist/src/reconcile/phases.d.ts +28 -0
  141. package/dist/src/reconcile/phases.js +0 -0
  142. package/dist/src/reconcile/reconcile.d.ts +21 -0
  143. package/dist/src/reconcile/reconcile.js +115 -0
  144. package/dist/src/reconcile/similarity.d.ts +7 -0
  145. package/dist/src/reconcile/similarity.js +41 -0
  146. package/dist/src/reconcile/types.d.ts +46 -0
  147. package/dist/src/reconcile/types.js +19 -0
  148. package/dist/src/search/cel/ast.d.ts +74 -0
  149. package/dist/src/search/cel/ast.js +3 -0
  150. package/dist/src/search/cel/compile.d.ts +60 -0
  151. package/dist/src/search/cel/compile.js +836 -0
  152. package/dist/src/search/cel/lexer.d.ts +9 -0
  153. package/dist/src/search/cel/lexer.js +139 -0
  154. package/dist/src/search/cel/parser.d.ts +7 -0
  155. package/dist/src/search/cel/parser.js +219 -0
  156. package/dist/src/search/drain.d.ts +39 -0
  157. package/dist/src/search/drain.js +97 -0
  158. package/dist/src/search/embeddings.d.ts +131 -0
  159. package/dist/src/search/embeddings.js +263 -0
  160. package/dist/src/search/external.d.ts +13 -0
  161. package/dist/src/search/external.js +177 -0
  162. package/dist/src/search/fts-query.d.ts +1 -0
  163. package/dist/src/search/fts-query.js +64 -0
  164. package/dist/src/search/provider.d.ts +17 -0
  165. package/dist/src/search/provider.js +13 -0
  166. package/dist/src/search/resolve.d.ts +18 -0
  167. package/dist/src/search/resolve.js +23 -0
  168. package/dist/src/search/rrf.d.ts +36 -0
  169. package/dist/src/search/rrf.js +84 -0
  170. package/dist/src/search/tasks.d.ts +12 -0
  171. package/dist/src/search/tasks.js +131 -0
  172. package/dist/src/search/text.d.ts +16 -0
  173. package/dist/src/search/text.js +21 -0
  174. package/dist/src/search/vector.d.ts +18 -0
  175. package/dist/src/search/vector.js +49 -0
  176. package/dist/src/sync/admin.d.ts +59 -0
  177. package/dist/src/sync/admin.js +53 -0
  178. package/dist/src/sync/attach.d.ts +13 -0
  179. package/dist/src/sync/attach.js +29 -0
  180. package/dist/src/sync/checkpoint.d.ts +21 -0
  181. package/dist/src/sync/checkpoint.js +52 -0
  182. package/dist/src/sync/driver.d.ts +25 -0
  183. package/dist/src/sync/driver.js +80 -0
  184. package/dist/src/sync/external-source.d.ts +14 -0
  185. package/dist/src/sync/external-source.js +137 -0
  186. package/dist/src/sync/freshness.d.ts +42 -0
  187. package/dist/src/sync/freshness.js +152 -0
  188. package/dist/src/sync/fs-util.d.ts +12 -0
  189. package/dist/src/sync/fs-util.js +55 -0
  190. package/dist/src/sync/git-heuristics.d.ts +6 -0
  191. package/dist/src/sync/git-heuristics.js +16 -0
  192. package/dist/src/sync/observe.d.ts +63 -0
  193. package/dist/src/sync/observe.js +84 -0
  194. package/dist/src/sync/plugin.d.ts +54 -0
  195. package/dist/src/sync/plugin.js +12 -0
  196. package/dist/src/sync/reconciling-ingest.d.ts +12 -0
  197. package/dist/src/sync/reconciling-ingest.js +209 -0
  198. package/dist/src/sync/recovery.d.ts +6 -0
  199. package/dist/src/sync/recovery.js +34 -0
  200. package/dist/src/sync/settings.d.ts +18 -0
  201. package/dist/src/sync/settings.js +58 -0
  202. package/dist/src/sync/sources.d.ts +37 -0
  203. package/dist/src/sync/sources.js +75 -0
  204. package/dist/src/sync/tombstone.d.ts +9 -0
  205. package/dist/src/sync/tombstone.js +55 -0
  206. package/dist/src/sync/watch-lease.d.ts +14 -0
  207. package/dist/src/sync/watch-lease.js +91 -0
  208. package/dist/src/sync/watcher.d.ts +19 -0
  209. package/dist/src/sync/watcher.js +34 -0
  210. package/dist/src/sync/workspace.d.ts +34 -0
  211. package/dist/src/sync/workspace.js +120 -0
  212. package/dist/src/sync/writer-lock.d.ts +16 -0
  213. package/dist/src/sync/writer-lock.js +121 -0
  214. package/package.json +80 -0
@@ -0,0 +1,89 @@
1
+ import { sha256, serializeTreeEntries } from "../hash.js";
2
+ import { mintId } from "../ids.js";
3
+ /** Assign fresh minted ids to a parsed block tree (Stage-1 re-mint path). */
4
+ export function assignIds(blocks) {
5
+ return blocks.map((b) => ({
6
+ blockId: mintId("b"),
7
+ type: b.type,
8
+ raw: b.raw,
9
+ trivia: b.trivia,
10
+ attrs: b.attrs,
11
+ children: assignIds(b.children),
12
+ }));
13
+ }
14
+ /** Content-address raw text into blobs; returns hex hash. Dedups. */
15
+ export function putBlob(db, text) {
16
+ const bytes = Buffer.from(text, "utf8");
17
+ const hash = sha256(bytes);
18
+ db.prepare("INSERT OR IGNORE INTO blobs (hash, bytes, size) VALUES (?, ?, ?)").run(hash, bytes, bytes.length);
19
+ return hash.toString("hex");
20
+ }
21
+ /** Content-address a tree node's entries; returns hex hash. Dedups. */
22
+ export function putTreeNode(db, entries) {
23
+ const serialized = serializeTreeEntries(entries);
24
+ const hash = sha256(serialized);
25
+ db.prepare("INSERT OR IGNORE INTO tree_nodes (hash, entries) VALUES (?, ?)").run(hash, serialized);
26
+ return hash.toString("hex");
27
+ }
28
+ /**
29
+ * Encode a list of sibling blocks into a Merkle tree node bottom-up, writing
30
+ * blobs (raw + trivia) and child tree nodes. Returns the node's hex hash.
31
+ * Structural sharing: unchanged subtrees produce identical hashes and are not
32
+ * re-inserted.
33
+ */
34
+ export function writeBlockTree(db, blocks) {
35
+ const entries = blocks.map((b) => {
36
+ const rawHashHex = putBlob(db, b.raw);
37
+ const triviaHashHex = b.trivia.length > 0 ? putBlob(db, b.trivia) : null;
38
+ const childTreeHashHex = b.children.length > 0 ? writeBlockTree(db, b.children) : null;
39
+ return {
40
+ blockId: b.blockId,
41
+ rawHashHex,
42
+ childTreeHashHex,
43
+ type: b.type,
44
+ attrs: b.attrs,
45
+ triviaHashHex,
46
+ };
47
+ });
48
+ return putTreeNode(db, entries);
49
+ }
50
+ /** Append a commit; assigns the per-repo total-order seq. */
51
+ export function newCommit(db, input) {
52
+ const commitId = mintId("c");
53
+ const row = db
54
+ .prepare("SELECT COALESCE(MAX(seq),0)+1 AS seq FROM commits WHERE repo_id = ?")
55
+ .get(input.repoId);
56
+ db.prepare(`INSERT INTO commits (commit_id, repo_id, seq, ts, origin, actor, reason, checkpoint_id, ops)
57
+ VALUES (@commitId, @repoId, @seq, @ts, @origin, @actor, @reason, @checkpointId, @ops)`).run({
58
+ commitId,
59
+ repoId: input.repoId,
60
+ seq: row.seq,
61
+ ts: input.ts,
62
+ origin: input.origin,
63
+ actor: input.actor ?? null,
64
+ reason: input.reason ?? null,
65
+ checkpointId: input.checkpointId ?? null,
66
+ ops: input.ops ?? null,
67
+ });
68
+ return { commitId, seq: row.seq };
69
+ }
70
+ /** Append a revision; assigns the per-document monotonic seq. */
71
+ export function writeRevision(db, input) {
72
+ const revId = mintId("r");
73
+ const row = db
74
+ .prepare("SELECT COALESCE(MAX(seq),0)+1 AS seq FROM revisions WHERE doc_id = ?")
75
+ .get(input.docId);
76
+ db.prepare(`INSERT INTO revisions (rev_id, doc_id, seq, root_tree, frontmatter_blob, rendered_hash, path, commit_id)
77
+ VALUES (@revId, @docId, @seq, @rootTree, @frontmatterBlob, @renderedHash, @path, @commitId)`).run({
78
+ revId,
79
+ docId: input.docId,
80
+ seq: row.seq,
81
+ rootTree: Buffer.from(input.rootTreeHex, "hex"),
82
+ frontmatterBlob: input.frontmatterBlobHex ? Buffer.from(input.frontmatterBlobHex, "hex") : null,
83
+ renderedHash: input.renderedHash,
84
+ path: input.path,
85
+ commitId: input.commitId,
86
+ });
87
+ return { revId, seq: row.seq };
88
+ }
89
+ //# sourceMappingURL=writers.js.map
@@ -0,0 +1,10 @@
1
+ /** Cosine similarity of two equal-length embedding vectors. 0 when either is a
2
+ * zero vector (undefined direction) — the neutral, non-matching score. */
3
+ export declare function cosineFloat32(a: Float32Array, b: Float32Array): number;
4
+ /** Reinterpret a stored/bound BLOB as a Float32 vector (a zero-copy view). */
5
+ export declare function blobToFloat32(buf: Uint8Array): Float32Array;
6
+ /** A Buffer view over a Float32 vector's bytes, for binding as a SQL BLOB. */
7
+ export declare function float32ToBlob(vec: Float32Array): Buffer;
8
+ /** Cosine over two BLOBs (the `cosine` UDF body). NULL-safe: a missing operand
9
+ * (no embedding row) yields NULL so the score is absent, not a spurious 0. */
10
+ export declare function cosineBytes(a: Uint8Array | null, b: Uint8Array | null): number | null;
@@ -0,0 +1,33 @@
1
+ // Vector math shared by the brute-force semantic search (search/vector.ts) and
2
+ // the `cosine` SQLite UDF (store.ts) that OQX's `semantic()` scalar compiles to.
3
+ // Embedding vectors are stored/bound as little-endian Float32 BLOBs.
4
+ /** Cosine similarity of two equal-length embedding vectors. 0 when either is a
5
+ * zero vector (undefined direction) — the neutral, non-matching score. */
6
+ export function cosineFloat32(a, b) {
7
+ let dot = 0, na = 0, nb = 0;
8
+ const n = Math.min(a.length, b.length);
9
+ for (let i = 0; i < n; i++) {
10
+ dot += a[i] * b[i];
11
+ na += a[i] * a[i];
12
+ nb += b[i] * b[i];
13
+ }
14
+ if (na === 0 || nb === 0)
15
+ return 0;
16
+ return dot / (Math.sqrt(na) * Math.sqrt(nb));
17
+ }
18
+ /** Reinterpret a stored/bound BLOB as a Float32 vector (a zero-copy view). */
19
+ export function blobToFloat32(buf) {
20
+ return new Float32Array(buf.buffer, buf.byteOffset, Math.floor(buf.byteLength / 4));
21
+ }
22
+ /** A Buffer view over a Float32 vector's bytes, for binding as a SQL BLOB. */
23
+ export function float32ToBlob(vec) {
24
+ return Buffer.from(vec.buffer, vec.byteOffset, vec.byteLength);
25
+ }
26
+ /** Cosine over two BLOBs (the `cosine` UDF body). NULL-safe: a missing operand
27
+ * (no embedding row) yields NULL so the score is absent, not a spurious 0. */
28
+ export function cosineBytes(a, b) {
29
+ if (!a || !b)
30
+ return null;
31
+ return cosineFloat32(blobToFloat32(a), blobToFloat32(b));
32
+ }
33
+ //# sourceMappingURL=vec.js.map
@@ -0,0 +1,97 @@
1
+ import type { BlockTree, RawBlock, ExtractedLink } from "../core/parse/types.js";
2
+ export declare const enum AdapterCapability {
3
+ Parse = "parse",
4
+ Render = "render",
5
+ ExtractEdges = "extract_edges",
6
+ ProjectNodes = "project_nodes",
7
+ ExtractMetadata = "extract_metadata",
8
+ ComputeProperties = "compute_properties",
9
+ StructuralMutation = "structural_mutation",
10
+ SemanticChunking = "semantic_chunking"
11
+ }
12
+ export interface ProjectedNode {
13
+ kind: string;
14
+ name?: string | undefined;
15
+ value?: string | undefined;
16
+ blockId: string;
17
+ spanStart?: number | undefined;
18
+ spanEnd?: number | undefined;
19
+ attrs?: Record<string, unknown> | undefined;
20
+ }
21
+ export interface EmbeddingChunk {
22
+ blockId: string;
23
+ text: string;
24
+ context?: string;
25
+ }
26
+ /** The block-scoped context an editable node property is rewritten against. */
27
+ export interface NodeEditContext {
28
+ /** The block's current raw bytes (what the edit rewrites). */
29
+ blockRaw: string;
30
+ /** The node's byte span within blockRaw (null when unrecorded — see spans). */
31
+ span: {
32
+ start: number;
33
+ end: number;
34
+ } | null;
35
+ /** The node's current name/value/attrs, for editors that need them. */
36
+ node: {
37
+ kind: string;
38
+ name?: string | undefined;
39
+ value?: string | undefined;
40
+ attrs: Record<string, unknown>;
41
+ };
42
+ }
43
+ /**
44
+ * The result of a node-property edit: how it maps onto a block `update` op.
45
+ * `markdown` replaces the block's bytes; `attrs` sets typed block attributes
46
+ * (e.g. a task's `checked`). Editors return exactly one.
47
+ */
48
+ export type NodeEditResult = {
49
+ markdown: string;
50
+ } | {
51
+ attrs: Record<string, unknown>;
52
+ };
53
+ /** Rewrite one editable property of a node into a block update (node-editability). */
54
+ export type NodeEditor = (ctx: NodeEditContext, newValue: string) => NodeEditResult;
55
+ /**
56
+ * Per-node-kind editable properties (node-editability). An adapter declares, for
57
+ * a node kind, which properties can be set and how each compiles down to a block
58
+ * `update` — so a caller edits a link's text or a task's checkbox surgically
59
+ * while the write still goes through the block. Nodes stay read-only projections;
60
+ * this is the affordance layer, not a second source of truth.
61
+ */
62
+ export type NodeEditors = Record<string, Record<string, NodeEditor>>;
63
+ export interface ReconcileHints {
64
+ anchorEvidenceKeys?: string[];
65
+ smallBlockTokens?: number;
66
+ }
67
+ export interface AdapterEdge {
68
+ srcBlock: string | null;
69
+ srcField: string | null;
70
+ predicate: string;
71
+ dstKind: "document" | "block" | "external" | "collection";
72
+ target: string;
73
+ anchor: string | null;
74
+ provenance: string;
75
+ }
76
+ export interface FormatAdapter {
77
+ readonly format: string;
78
+ readonly extensions: string[];
79
+ readonly capabilities: ReadonlySet<AdapterCapability>;
80
+ parse(source: string): BlockTree;
81
+ render?(tree: BlockTree): string;
82
+ extractEdges?(blocks: RawBlock[], metadata?: Record<string, unknown>): AdapterEdge[];
83
+ projectNodes?(blocks: RawBlock[]): ProjectedNode[];
84
+ extractMetadata?(source: string): Record<string, unknown> | null;
85
+ /**
86
+ * Computed properties (properties-table §4): engine-derived facts surfaced
87
+ * as `$`-intrinsics ($title, $tags, ...), distinct from authored frontmatter/
88
+ * inline keys. Each entry is a $-prefixed key mapped to a scalar or a list of
89
+ * scalars. Stored as source='computed' property rows.
90
+ */
91
+ computeProperties?(blocks: RawBlock[], metadata: Record<string, unknown>): Record<string, unknown>;
92
+ reconcileHints?(): ReconcileHints;
93
+ chunkForEmbedding?(blocks: RawBlock[]): EmbeddingChunk[];
94
+ /** Editable node properties, keyed by node kind then property (node-editability). */
95
+ nodeEditors?: NodeEditors;
96
+ }
97
+ export type { BlockTree, RawBlock, ExtractedLink };
@@ -0,0 +1,14 @@
1
+ // Format adapter contract. Each format (markdown, yaml, json, …) implements
2
+ // this interface to participate in the omgbase versioned block graph.
3
+ export var AdapterCapability;
4
+ (function (AdapterCapability) {
5
+ AdapterCapability["Parse"] = "parse";
6
+ AdapterCapability["Render"] = "render";
7
+ AdapterCapability["ExtractEdges"] = "extract_edges";
8
+ AdapterCapability["ProjectNodes"] = "project_nodes";
9
+ AdapterCapability["ExtractMetadata"] = "extract_metadata";
10
+ AdapterCapability["ComputeProperties"] = "compute_properties";
11
+ AdapterCapability["StructuralMutation"] = "structural_mutation";
12
+ AdapterCapability["SemanticChunking"] = "semantic_chunking";
13
+ })(AdapterCapability || (AdapterCapability = {}));
14
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1,6 @@
1
+ export type { FormatAdapter, AdapterEdge, ProjectedNode, EmbeddingChunk, ReconcileHints, } from "./adapter.js";
2
+ export { AdapterCapability } from "./adapter.js";
3
+ export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat, } from "./registry.js";
4
+ export { markdownAdapter, MARKDOWN_FORMAT } from "./markdown.js";
5
+ export { yamlAdapter, YAML_FORMAT } from "./yaml.js";
6
+ export { jsonAdapter, JSON_FORMAT } from "./json.js";
@@ -0,0 +1,15 @@
1
+ // Format adapter system. Importing this module registers the built-in adapters.
2
+ export { AdapterCapability } from "./adapter.js";
3
+ export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat, } from "./registry.js";
4
+ export { markdownAdapter, MARKDOWN_FORMAT } from "./markdown.js";
5
+ export { yamlAdapter, YAML_FORMAT } from "./yaml.js";
6
+ export { jsonAdapter, JSON_FORMAT } from "./json.js";
7
+ // Register built-in adapters.
8
+ import { registerAdapter } from "./registry.js";
9
+ import { markdownAdapter } from "./markdown.js";
10
+ import { yamlAdapter } from "./yaml.js";
11
+ import { jsonAdapter } from "./json.js";
12
+ registerAdapter(markdownAdapter);
13
+ registerAdapter(yamlAdapter);
14
+ registerAdapter(jsonAdapter);
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ import { type FormatAdapter } from "./adapter.js";
2
+ export declare const JSON_FORMAT = "json";
3
+ export declare const jsonAdapter: FormatAdapter;
@@ -0,0 +1,324 @@
1
+ // JSON format adapter. Decomposes JSON files into blocks with json:-prefixed
2
+ // kinds, extracts $ref/$schema edges, and projects the root object as metadata.
3
+ // Read-only: no StructuralMutation (JSON formatting is not reliably preserved).
4
+ import { AdapterCapability } from "./adapter.js";
5
+ import { normalizeText } from "../core/hash.js";
6
+ export const JSON_FORMAT = "json";
7
+ const K = {
8
+ object: "json:object",
9
+ property: "json:property",
10
+ array: "json:array",
11
+ item: "json:item",
12
+ scalar: "json:scalar",
13
+ };
14
+ function span(start, end) {
15
+ return { start, end };
16
+ }
17
+ function emptyBlock(kind, s, raw) {
18
+ return {
19
+ type: kind,
20
+ span: s,
21
+ raw,
22
+ text: normalizeText(raw),
23
+ attrs: {},
24
+ children: [],
25
+ trivia: "",
26
+ anchors: [],
27
+ outLinks: [],
28
+ };
29
+ }
30
+ function parseJsonStructure(source) {
31
+ let pos = 0;
32
+ function skipWhitespace() {
33
+ while (pos < source.length && /\s/.test(source[pos]))
34
+ pos++;
35
+ }
36
+ function parseValue() {
37
+ skipWhitespace();
38
+ if (pos >= source.length)
39
+ return null;
40
+ const ch = source[pos];
41
+ if (ch === "{")
42
+ return parseObject();
43
+ if (ch === "[")
44
+ return parseArray();
45
+ if (ch === '"')
46
+ return parseString();
47
+ if (ch === "-" || (ch >= "0" && ch <= "9"))
48
+ return parseNumber();
49
+ if (source.startsWith("true", pos)) {
50
+ const n = { kind: "boolean", start: pos, end: pos + 4, value: true };
51
+ pos += 4;
52
+ return n;
53
+ }
54
+ if (source.startsWith("false", pos)) {
55
+ const n = { kind: "boolean", start: pos, end: pos + 5, value: false };
56
+ pos += 5;
57
+ return n;
58
+ }
59
+ if (source.startsWith("null", pos)) {
60
+ const n = { kind: "null", start: pos, end: pos + 4, value: null };
61
+ pos += 4;
62
+ return n;
63
+ }
64
+ return null;
65
+ }
66
+ function parseString() {
67
+ const start = pos;
68
+ pos++; // skip opening "
69
+ while (pos < source.length) {
70
+ if (source[pos] === "\\") {
71
+ pos += 2;
72
+ continue;
73
+ }
74
+ if (source[pos] === '"') {
75
+ pos++;
76
+ break;
77
+ }
78
+ pos++;
79
+ }
80
+ const raw = source.slice(start, pos);
81
+ let value;
82
+ try {
83
+ value = JSON.parse(raw);
84
+ }
85
+ catch {
86
+ value = raw.slice(1, -1);
87
+ }
88
+ return { kind: "string", start, end: pos, value };
89
+ }
90
+ function parseNumber() {
91
+ const start = pos;
92
+ if (source[pos] === "-")
93
+ pos++;
94
+ while (pos < source.length && source[pos] >= "0" && source[pos] <= "9")
95
+ pos++;
96
+ if (pos < source.length && source[pos] === ".") {
97
+ pos++;
98
+ while (pos < source.length && source[pos] >= "0" && source[pos] <= "9")
99
+ pos++;
100
+ }
101
+ if (pos < source.length && (source[pos] === "e" || source[pos] === "E")) {
102
+ pos++;
103
+ if (pos < source.length && (source[pos] === "+" || source[pos] === "-"))
104
+ pos++;
105
+ while (pos < source.length && source[pos] >= "0" && source[pos] <= "9")
106
+ pos++;
107
+ }
108
+ const value = Number(source.slice(start, pos));
109
+ return { kind: "number", start, end: pos, value };
110
+ }
111
+ function parseObject() {
112
+ const start = pos;
113
+ pos++; // skip {
114
+ const children = [];
115
+ skipWhitespace();
116
+ while (pos < source.length && source[pos] !== "}") {
117
+ skipWhitespace();
118
+ const keyNode = parseString();
119
+ const key = keyNode.value;
120
+ skipWhitespace();
121
+ if (pos < source.length && source[pos] === ":")
122
+ pos++;
123
+ skipWhitespace();
124
+ const propStart = keyNode.start;
125
+ const val = parseValue();
126
+ const propEnd = val ? val.end : pos;
127
+ const child = {
128
+ kind: "object",
129
+ start: propStart,
130
+ end: propEnd,
131
+ key,
132
+ value: val?.value,
133
+ children: val?.children,
134
+ };
135
+ children.push(child);
136
+ skipWhitespace();
137
+ if (pos < source.length && source[pos] === ",")
138
+ pos++;
139
+ }
140
+ if (pos < source.length)
141
+ pos++; // skip }
142
+ return { kind: "object", start, end: pos, children };
143
+ }
144
+ function parseArray() {
145
+ const start = pos;
146
+ pos++; // skip [
147
+ const children = [];
148
+ skipWhitespace();
149
+ let index = 0;
150
+ while (pos < source.length && source[pos] !== "]") {
151
+ skipWhitespace();
152
+ const val = parseValue();
153
+ if (val) {
154
+ val.key = String(index);
155
+ children.push(val);
156
+ }
157
+ index++;
158
+ skipWhitespace();
159
+ if (pos < source.length && source[pos] === ",")
160
+ pos++;
161
+ }
162
+ if (pos < source.length)
163
+ pos++; // skip ]
164
+ return { kind: "array", start, end: pos, children };
165
+ }
166
+ return parseValue();
167
+ }
168
+ function jsonNodeToBlocks(node, source) {
169
+ if (node.kind === "object" && node.children) {
170
+ return node.children.map((child) => {
171
+ const raw = source.slice(child.start, child.end);
172
+ const block = emptyBlock(K.property, span(child.start, child.end), raw);
173
+ block.attrs = { key: child.key ?? "" };
174
+ if (child.children) {
175
+ block.children = child.children.map((sub) => {
176
+ const subRaw = source.slice(sub.start, sub.end);
177
+ const subBlock = emptyBlock(sub.kind === "object" ? K.object :
178
+ sub.kind === "array" ? K.array : K.scalar, span(sub.start, sub.end), subRaw);
179
+ subBlock.attrs = { key: sub.key ?? "" };
180
+ return subBlock;
181
+ });
182
+ }
183
+ return block;
184
+ });
185
+ }
186
+ if (node.kind === "array" && node.children) {
187
+ return node.children.map((child, i) => {
188
+ const raw = source.slice(child.start, child.end);
189
+ const block = emptyBlock(K.item, span(child.start, child.end), raw);
190
+ block.attrs = { index: i };
191
+ return block;
192
+ });
193
+ }
194
+ // Scalar root: single block.
195
+ return [emptyBlock(K.scalar, span(node.start, node.end), source.slice(node.start, node.end))];
196
+ }
197
+ function buildTree(source) {
198
+ const root = parseJsonStructure(source);
199
+ if (!root) {
200
+ // Unparseable: one opaque block.
201
+ const block = emptyBlock("json:opaque", span(0, source.length), source);
202
+ return { source, leadingTrivia: "", children: [block] };
203
+ }
204
+ const children = jsonNodeToBlocks(root, source);
205
+ const leadingTrivia = children.length === 0 ? source : source.slice(0, children[0].span.start);
206
+ for (let i = 0; i < children.length; i++) {
207
+ const block = children[i];
208
+ const next = children[i + 1];
209
+ const triviaEnd = next ? next.span.start : source.length;
210
+ block.trivia = source.slice(block.span.end, triviaEnd);
211
+ }
212
+ return { source, leadingTrivia, children };
213
+ }
214
+ function isExternalUri(s) {
215
+ return /^https?:\/\//.test(s);
216
+ }
217
+ function extractJsonEdges(obj, parentKey, edges, seen) {
218
+ function push(e) {
219
+ const k = `${e.predicate}|${e.target}|${e.provenance}`;
220
+ if (seen.has(k))
221
+ return;
222
+ seen.add(k);
223
+ edges.push(e);
224
+ }
225
+ if (typeof obj === "string") {
226
+ if (parentKey === "$ref") {
227
+ const target = obj.startsWith("#") ? "" : obj.split("#")[0];
228
+ if (target) {
229
+ push({
230
+ srcBlock: null, srcField: "$ref", predicate: "references",
231
+ dstKind: isExternalUri(target) ? "external" : "document",
232
+ target, anchor: obj.includes("#") ? obj.split("#")[1] : null,
233
+ provenance: "json_ref",
234
+ });
235
+ }
236
+ }
237
+ else if (parentKey === "$schema") {
238
+ push({
239
+ srcBlock: null, srcField: "$schema", predicate: "schema",
240
+ dstKind: isExternalUri(obj) ? "external" : "document",
241
+ target: obj, anchor: null, provenance: "json_schema",
242
+ });
243
+ }
244
+ else if ((obj.startsWith("./") || obj.startsWith("../") || obj.startsWith("/")) && !obj.includes(" ")) {
245
+ push({
246
+ srcBlock: null, srcField: parentKey, predicate: parentKey,
247
+ dstKind: "document", target: obj, anchor: null, provenance: "json_ref",
248
+ });
249
+ }
250
+ }
251
+ else if (Array.isArray(obj)) {
252
+ for (const item of obj)
253
+ extractJsonEdges(item, parentKey, edges, seen);
254
+ }
255
+ else if (obj && typeof obj === "object") {
256
+ for (const [k, v] of Object.entries(obj)) {
257
+ extractJsonEdges(v, k, edges, seen);
258
+ }
259
+ }
260
+ }
261
+ export const jsonAdapter = {
262
+ format: JSON_FORMAT,
263
+ extensions: [".json"],
264
+ capabilities: new Set([
265
+ AdapterCapability.Parse,
266
+ AdapterCapability.Render,
267
+ AdapterCapability.ExtractEdges,
268
+ AdapterCapability.ExtractMetadata,
269
+ AdapterCapability.ProjectNodes,
270
+ AdapterCapability.StructuralMutation,
271
+ ]),
272
+ parse(source) {
273
+ return buildTree(source);
274
+ },
275
+ render(tree) {
276
+ const out = [tree.leadingTrivia];
277
+ for (const block of tree.children) {
278
+ out.push(block.dirty ? block.raw : block.raw);
279
+ out.push(block.trivia);
280
+ }
281
+ return out.join("");
282
+ },
283
+ projectNodes(blocks) {
284
+ const nodes = [];
285
+ const walk = (list) => {
286
+ for (const b of list) {
287
+ const key = b.attrs.key ?? "";
288
+ const id = b.blockId ?? "";
289
+ if (b.type === "json:property" && key === "$ref") {
290
+ const val = b.text.replace(/^"[^"]*"\s*:\s*/, "").replace(/^"|"$/g, "").trim();
291
+ nodes.push({ kind: "json:ref", name: "$ref", value: val, blockId: id });
292
+ }
293
+ if (b.type === "json:property" && key === "$schema") {
294
+ const val = b.text.replace(/^"[^"]*"\s*:\s*/, "").replace(/^"|"$/g, "").trim();
295
+ nodes.push({ kind: "json:schema", name: "$schema", value: val, blockId: id });
296
+ }
297
+ if (b.children.length > 0)
298
+ walk(b.children);
299
+ }
300
+ };
301
+ walk(blocks);
302
+ return nodes;
303
+ },
304
+ extractEdges(_blocks, metadata) {
305
+ if (!metadata)
306
+ return [];
307
+ const edges = [];
308
+ extractJsonEdges(metadata, "", edges, new Set());
309
+ return edges;
310
+ },
311
+ extractMetadata(source) {
312
+ try {
313
+ const parsed = JSON.parse(source);
314
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
315
+ return parsed;
316
+ }
317
+ return null;
318
+ }
319
+ catch {
320
+ return null;
321
+ }
322
+ },
323
+ };
324
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1,5 @@
1
+ import { type FormatAdapter } from "./adapter.js";
2
+ import { assertFullCoverage } from "../core/parse/tree.js";
3
+ export declare const MARKDOWN_FORMAT = "markdown";
4
+ export declare const markdownAdapter: FormatAdapter;
5
+ export { assertFullCoverage };