@anokye-labs/kbexplorer-engine 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.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/build-manifest-BT0sY84J.d.ts +239 -0
- package/dist/build-manifest-BkgZUL0E.d.cts +239 -0
- package/dist/chunk-ASLGNOYV.js +220 -0
- package/dist/chunk-BA526FDQ.js +16 -0
- package/dist/chunk-DJ2DBEEK.js +424 -0
- package/dist/chunk-FJ4GTN4U.js +973 -0
- package/dist/chunk-HXAS3BSD.js +187 -0
- package/dist/chunk-IWEURXYH.js +273 -0
- package/dist/chunk-JNQVSNLC.js +55 -0
- package/dist/chunk-MW4BLXVK.js +72 -0
- package/dist/chunk-NOGBKE7C.js +351 -0
- package/dist/chunk-XVI6CBSX.js +412 -0
- package/dist/chunk-YTMIERYM.js +67 -0
- package/dist/github-api-source-KV5HZARH.js +4 -0
- package/dist/index.cjs +6218 -0
- package/dist/index.d.cts +1396 -0
- package/dist/index.d.ts +1396 -0
- package/dist/index.js +2892 -0
- package/dist/node-wasm-VSXBOCPD.js +9 -0
- package/dist/plugin-loader-K4VU6ODV.js +2 -0
- package/dist/repo-data-0JvFdLGv.d.cts +461 -0
- package/dist/repo-data-0JvFdLGv.d.ts +461 -0
- package/dist/sources.cjs +1191 -0
- package/dist/sources.d.cts +194 -0
- package/dist/sources.d.ts +194 -0
- package/dist/sources.js +357 -0
- package/dist/sqlite-graph-store-NH2NHL2B.js +2 -0
- package/dist/sqlite-runtime-CysPjjzX.d.cts +96 -0
- package/dist/sqlite-runtime-CysPjjzX.d.ts +96 -0
- package/dist/store-orchestrator-337XWIXO.js +5 -0
- package/dist/store.cjs +1112 -0
- package/dist/store.d.cts +37 -0
- package/dist/store.d.ts +37 -0
- package/dist/store.js +7 -0
- package/package.json +70 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { KBNode, Source } from '@anokye-labs/kbexplorer-core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimal GitHub API shapes needed by `parser.ts`'s `issueToNode` /
|
|
5
|
+
* `treeToNodes`. These are NOT the full GitHub REST client types — just the
|
|
6
|
+
* fields those two functions actually read. The full client (`fetchFile`,
|
|
7
|
+
* `fetchTree`, `fetchFiles`, `fetchIssues`) lives in kbexplorer-template's
|
|
8
|
+
* `src/api/github.ts`, which has not moved to this package yet (slice 4).
|
|
9
|
+
*/
|
|
10
|
+
/** A GitHub issue or pull request, as returned by the Issues API. */
|
|
11
|
+
interface GHIssue {
|
|
12
|
+
number: number;
|
|
13
|
+
title: string;
|
|
14
|
+
body: string | null;
|
|
15
|
+
state: string;
|
|
16
|
+
html_url: string;
|
|
17
|
+
created_at: string;
|
|
18
|
+
updated_at: string;
|
|
19
|
+
labels: Array<{
|
|
20
|
+
name: string;
|
|
21
|
+
color?: string;
|
|
22
|
+
}>;
|
|
23
|
+
assignees?: Array<{
|
|
24
|
+
login: string;
|
|
25
|
+
}> | null;
|
|
26
|
+
/** The GitHub user who opened the issue/PR (author). Added in slice 2 for PersonProvider/WorkProvider's author-attribution logic — absent from slice 1's parser-only subset. */
|
|
27
|
+
user?: {
|
|
28
|
+
login: string;
|
|
29
|
+
};
|
|
30
|
+
/** Present (and truthy) only when the issue is actually a pull request. */
|
|
31
|
+
pull_request?: unknown;
|
|
32
|
+
}
|
|
33
|
+
/** A single entry in a GitHub repo's git tree, as returned by the Git Trees API. */
|
|
34
|
+
interface GHTreeItem {
|
|
35
|
+
path: string;
|
|
36
|
+
type: 'blob' | 'tree';
|
|
37
|
+
size?: number;
|
|
38
|
+
/** Git file mode (e.g. `'100644'`, `'040000'`). Not read by `treeToNodes` itself. */
|
|
39
|
+
mode?: string;
|
|
40
|
+
/** Blob/tree SHA. Not read by `treeToNodes` itself. */
|
|
41
|
+
sha?: string;
|
|
42
|
+
/** API URL for this tree entry. Not read by `treeToNodes` itself. */
|
|
43
|
+
url?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A GitHub release as returned by the releases API.
|
|
47
|
+
* Drafts are excluded; prerelease flag is preserved.
|
|
48
|
+
*/
|
|
49
|
+
interface GHRelease {
|
|
50
|
+
tag_name: string;
|
|
51
|
+
name: string;
|
|
52
|
+
body: string;
|
|
53
|
+
html_url: string;
|
|
54
|
+
published_at: string;
|
|
55
|
+
prerelease: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A single commit as returned by the Commits API. Added in slice 3 for
|
|
59
|
+
* `sources/repo-data.ts`'s `RepoData.commits` field (consumed by `WorkProvider`).
|
|
60
|
+
*/
|
|
61
|
+
interface GHCommit {
|
|
62
|
+
sha: string;
|
|
63
|
+
commit: {
|
|
64
|
+
message: string;
|
|
65
|
+
author: {
|
|
66
|
+
name: string;
|
|
67
|
+
date: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
html_url: string;
|
|
71
|
+
files?: Array<{
|
|
72
|
+
filename: string;
|
|
73
|
+
status: string;
|
|
74
|
+
}>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface EngineEnv {
|
|
78
|
+
[key: string]: string | boolean | undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Content-model ingestion types (F2 — issue #149).
|
|
83
|
+
*
|
|
84
|
+
* The content model is **schema-driven**: identity/authority comes from
|
|
85
|
+
* `teamops.yaml`, storage layout from `schema/conventions.yaml`, relationships
|
|
86
|
+
* from `schema/edges.yaml`, lifecycle bands from `schema/lifecycle.yaml`, and
|
|
87
|
+
* URN bases from `index/context.jsonld`. The engine reads these files rather
|
|
88
|
+
* than hardcoding any org's structure, so a second org adopts the platform by
|
|
89
|
+
* changing config — not engine code.
|
|
90
|
+
*
|
|
91
|
+
* Hard rules encoded here:
|
|
92
|
+
* - A node's **kind comes from its `@type`**, never from the file path.
|
|
93
|
+
* - **URN bases come from the JSON-LD context only** — never hardcoded.
|
|
94
|
+
*/
|
|
95
|
+
/** Lifecycle band from `schema/lifecycle.yaml` (open — custom bands allowed). */
|
|
96
|
+
type LifecycleBand = 'durable' | 'per-cycle' | 'per-event' | (string & {});
|
|
97
|
+
/** Foreign-key resolution flavor from `schema/edges.yaml`. */
|
|
98
|
+
type FkFlavor = 'scalar' | 'array' | 'composite' | 'alias';
|
|
99
|
+
/** One org declared in `teamops.yaml`. */
|
|
100
|
+
interface OrgDef {
|
|
101
|
+
id: string;
|
|
102
|
+
name?: string | undefined;
|
|
103
|
+
/** Whether this is the home/default org (its entities are stored flat). */
|
|
104
|
+
default?: boolean;
|
|
105
|
+
}
|
|
106
|
+
/** `teamops.yaml` — maps identity to an authority + a default (home) org. */
|
|
107
|
+
interface TeamOps {
|
|
108
|
+
/** Authority host, e.g. `xbox.com` — the URN authority segment. */
|
|
109
|
+
authority: string;
|
|
110
|
+
/** Default/home org id; entities of org-scoped kinds default to it when flat. */
|
|
111
|
+
defaultOrg: string;
|
|
112
|
+
/** All known orgs. */
|
|
113
|
+
orgs: OrgDef[];
|
|
114
|
+
}
|
|
115
|
+
/** Storage + mapping convention for a single kind (from `schema/conventions.yaml`). */
|
|
116
|
+
interface KindConvention {
|
|
117
|
+
/** Kind id (matches the entity's `@type`). */
|
|
118
|
+
kind: string;
|
|
119
|
+
/** Storage root relative to the content-model root (e.g. `squads`). */
|
|
120
|
+
path: string;
|
|
121
|
+
/**
|
|
122
|
+
* Whether this kind is org-scoped. Org-scoped kinds carry an `/{org}` segment
|
|
123
|
+
* in their URN and store the **default org flat** / **non-default orgs nested**
|
|
124
|
+
* in a per-org subdirectory. Authority-scoped kinds omit the org segment.
|
|
125
|
+
*/
|
|
126
|
+
orgScoped: boolean;
|
|
127
|
+
/** Field carrying this kind's alias handle (the target of an `alias` FK). */
|
|
128
|
+
aliasField?: string | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Fields copied verbatim into `data`. When omitted, **all** fields pass
|
|
131
|
+
* through (the default), which keeps the field→data mapping reversible.
|
|
132
|
+
*/
|
|
133
|
+
passthrough?: string[] | undefined;
|
|
134
|
+
/** Sibling-file extension whose content is merged as the node body (e.g. `.md`). */
|
|
135
|
+
companionExt?: string | undefined;
|
|
136
|
+
}
|
|
137
|
+
/** `schema/conventions.yaml` — per-kind storage + mapping. */
|
|
138
|
+
interface Conventions {
|
|
139
|
+
/** Field carrying the kind discriminator. Default `@type`; never path-derived. */
|
|
140
|
+
typeField: string;
|
|
141
|
+
/** Field carrying the entity id. Default `id`. */
|
|
142
|
+
idField: string;
|
|
143
|
+
/** kind → convention. */
|
|
144
|
+
kinds: Record<string, KindConvention>;
|
|
145
|
+
}
|
|
146
|
+
/** One leg of a composite FK (`<a>:<b>` → two edges). */
|
|
147
|
+
interface CompositeLeg {
|
|
148
|
+
/** Target kind for this leg. */
|
|
149
|
+
to: string;
|
|
150
|
+
/** Relation taxonomy label for this leg. */
|
|
151
|
+
relation: string;
|
|
152
|
+
}
|
|
153
|
+
/** A foreign-key edge rule from `schema/edges.yaml`. */
|
|
154
|
+
interface EdgeRule {
|
|
155
|
+
id: string;
|
|
156
|
+
/** Source kind. */
|
|
157
|
+
from: string;
|
|
158
|
+
/** Field on the source entity carrying the foreign key. */
|
|
159
|
+
field: string;
|
|
160
|
+
/** Target kind (omitted for `composite`, which uses `composite[]`). */
|
|
161
|
+
to?: string;
|
|
162
|
+
fk: FkFlavor;
|
|
163
|
+
/** Relation taxonomy label applied to resolved edges. */
|
|
164
|
+
relation: string;
|
|
165
|
+
/** Legs for a `composite` FK, in the order the `<a>:<b>` parts appear. */
|
|
166
|
+
composite?: CompositeLeg[];
|
|
167
|
+
description?: string;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* A derived edge rule — computed from existing edges, not stored on entities.
|
|
171
|
+
* `shared-target`: sources that point at the **same** target of the referenced
|
|
172
|
+
* FK rule (`via`) are linked to each other. Deduped so a pair is stored once.
|
|
173
|
+
*/
|
|
174
|
+
interface DerivedRule {
|
|
175
|
+
id: string;
|
|
176
|
+
type: 'shared-target';
|
|
177
|
+
/** Id of the {@link EdgeRule} whose targets define the grouping. */
|
|
178
|
+
via: string;
|
|
179
|
+
relation: string;
|
|
180
|
+
description?: string;
|
|
181
|
+
}
|
|
182
|
+
/** `schema/edges.yaml` — FK edges + derived + deprecated. */
|
|
183
|
+
interface EdgesSpec {
|
|
184
|
+
edges: EdgeRule[];
|
|
185
|
+
derived: DerivedRule[];
|
|
186
|
+
/** Edge rules whose resolved edges are tagged `deprecated`. */
|
|
187
|
+
deprecated: EdgeRule[];
|
|
188
|
+
}
|
|
189
|
+
/** `schema/lifecycle.yaml` — band → kinds. */
|
|
190
|
+
interface Lifecycle {
|
|
191
|
+
bands: Record<string, string[]>;
|
|
192
|
+
}
|
|
193
|
+
/** Parsed `index/context.jsonld` — CURIE prefix → URN base. */
|
|
194
|
+
interface JsonLdContext {
|
|
195
|
+
/** The `@base` keyword, when present. */
|
|
196
|
+
base?: string | undefined;
|
|
197
|
+
/** prefix → URN base (full, e.g. `kg://xbox.com/squads/`). */
|
|
198
|
+
prefixes: Record<string, string>;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Cross-repo vocabulary / synonym layer (F-cross-repo — issue #153).
|
|
202
|
+
*
|
|
203
|
+
* Maps a per-repo **alias term** (a word one repo uses, e.g. `cell` / `crew`)
|
|
204
|
+
* to a **canonical term** — a kind / CURIE prefix already declared in the
|
|
205
|
+
* JSON-LD {@link JsonLdContext} (e.g. `squad`). It lets the graph unify concepts
|
|
206
|
+
* across repos that use different words while each repo keeps its native label.
|
|
207
|
+
*
|
|
208
|
+
* The map is **data-driven** (declared in `index/vocabulary.jsonld` and/or
|
|
209
|
+
* supplied as a shared overlay independent of any single repo's context) and is
|
|
210
|
+
* a **safe no-op** when empty — output is byte-identical to a build without it.
|
|
211
|
+
*/
|
|
212
|
+
interface Vocabulary {
|
|
213
|
+
/**
|
|
214
|
+
* alias term → canonical term. A self-mapping (alias === canonical) is never
|
|
215
|
+
* stored, so an alias is always a *rename* to some other canonical kind.
|
|
216
|
+
*/
|
|
217
|
+
aliases: Record<string, string>;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* An overlay vocabulary supplied independently of a repo's own files — the
|
|
221
|
+
* cross-repo synonym layer. Either raw `vocabulary.jsonld` content (a string),
|
|
222
|
+
* an already-parsed {@link Vocabulary}, or nothing.
|
|
223
|
+
*/
|
|
224
|
+
type VocabularyOverlay = string | Vocabulary | null | undefined;
|
|
225
|
+
/** The fully-parsed content-model schema. */
|
|
226
|
+
interface ContentModelSchema {
|
|
227
|
+
teamops: TeamOps;
|
|
228
|
+
conventions: Conventions;
|
|
229
|
+
edges: EdgesSpec;
|
|
230
|
+
lifecycle: Lifecycle;
|
|
231
|
+
context: JsonLdContext;
|
|
232
|
+
/** Cross-repo synonym layer; `aliases` is empty when none is declared. */
|
|
233
|
+
vocabulary: Vocabulary;
|
|
234
|
+
}
|
|
235
|
+
/** Severity of a build/schema diagnostic. */
|
|
236
|
+
type DiagnosticLevel = 'info' | 'warn' | 'error';
|
|
237
|
+
/** A diagnostic raised while reading the schema or building the graph. */
|
|
238
|
+
interface Diagnostic {
|
|
239
|
+
level: DiagnosticLevel;
|
|
240
|
+
/** Stable machine code, e.g. `unresolved-ref`, `unknown-prefix`. */
|
|
241
|
+
code: string;
|
|
242
|
+
message: string;
|
|
243
|
+
/** Related id / path / URN for context. */
|
|
244
|
+
ref?: string;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* A flat content-model source: schema files + entity files keyed by path
|
|
248
|
+
* relative to {@link ContentModelSource.root}. This abstraction lets the same
|
|
249
|
+
* builder run against build-time fixtures, the local manifest, and live fetch.
|
|
250
|
+
*/
|
|
251
|
+
interface ContentModelSource {
|
|
252
|
+
/** Root dir name within the repo (e.g. `content-model`). */
|
|
253
|
+
root: string;
|
|
254
|
+
/** path (relative to `root`) → raw file content. */
|
|
255
|
+
files: Record<string, string>;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Node-type registry — the open, data-driven core of the node-type engine.
|
|
260
|
+
*
|
|
261
|
+
* Each node type declares how it participates in the graph: its layer, default
|
|
262
|
+
* cluster, the relations it tends to emit, and which viewer renders it. The
|
|
263
|
+
* registry is consulted by {@link getNodeLayer} (via {@link resolveNodeLayer})
|
|
264
|
+
* and by cluster/legend logic, so adding a brand-new node type requires only a
|
|
265
|
+
* `registerType` call — no edits to the core discriminated unions or render
|
|
266
|
+
* switches.
|
|
267
|
+
*
|
|
268
|
+
* Implementation note: this module imports `KBNode` from
|
|
269
|
+
* `@anokye-labs/kbexplorer-core` **type-only**, so there is no runtime import
|
|
270
|
+
* cycle even though the module augmentation below adds a `layer` field to it.
|
|
271
|
+
*/
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Graph layer taxonomy. Not part of `@anokye-labs/kbexplorer-core` (it's an
|
|
275
|
+
* engine-internal concern, not a core domain type) — defined here since this
|
|
276
|
+
* is the module that resolves it. content-model/register.ts (slice 2) will
|
|
277
|
+
* import it from here too once it migrates.
|
|
278
|
+
*/
|
|
279
|
+
type NodeLayer = 'file' | 'content' | 'work';
|
|
280
|
+
/**
|
|
281
|
+
* Module augmentation: `@anokye-labs/kbexplorer-core`'s `KBNode` does not
|
|
282
|
+
* declare a `layer` field, but `buildGraph()` (`src/graph.ts`, via
|
|
283
|
+
* {@link resolveNodeLayer}) stamps one onto every node at build time, and
|
|
284
|
+
* later-slice consumers (content-model/register.ts) read it back. Augmenting
|
|
285
|
+
* the core type in place — rather than introducing a parallel `EngineNode`
|
|
286
|
+
* type that every call site would need to swap to — keeps `KBNode` the single
|
|
287
|
+
* node shape used throughout this package and its consumers. Flagged upstream
|
|
288
|
+
* (anokye-labs/kbexplorer-template#472) in case `@anokye-labs/kbexplorer-core`
|
|
289
|
+
* should grow this field natively in a future version.
|
|
290
|
+
*/
|
|
291
|
+
declare module '@anokye-labs/kbexplorer-core' {
|
|
292
|
+
interface KBNode {
|
|
293
|
+
/** Graph layer this node belongs to, stamped by `buildGraph()`. */
|
|
294
|
+
layer?: NodeLayer;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/** A registered node type and how it participates in the graph. */
|
|
298
|
+
interface NodeTypeDefinition {
|
|
299
|
+
/** Type id — matches a node's `entityType` or, for built-ins, its `source.type`. */
|
|
300
|
+
id: string;
|
|
301
|
+
/** Human-readable label (defaults to a humanized id). */
|
|
302
|
+
label?: string;
|
|
303
|
+
/** Graph layer this type belongs to. Defaults to `'file'` when unset. */
|
|
304
|
+
layer?: NodeLayer;
|
|
305
|
+
/** Default cluster id for nodes of this type (used when a node omits its cluster). */
|
|
306
|
+
cluster?: string;
|
|
307
|
+
/** Relation kinds this type commonly emits (informational; surfaced to the legend). */
|
|
308
|
+
relations?: string[];
|
|
309
|
+
/**
|
|
310
|
+
* Viewer key used to resolve a renderer from the viewer registry. Defaults to
|
|
311
|
+
* the type `id`. The viewer registry falls back to the generic viewer when no
|
|
312
|
+
* component is registered for the key.
|
|
313
|
+
*/
|
|
314
|
+
viewer?: string;
|
|
315
|
+
/** Short description of the type (documentation aid). */
|
|
316
|
+
description?: string;
|
|
317
|
+
/**
|
|
318
|
+
* Optional discovery hook — given raw upstream records, decide which become
|
|
319
|
+
* nodes of this type. Reserved for content-model ingestion (F2/F3); the
|
|
320
|
+
* foundation only stores it.
|
|
321
|
+
*/
|
|
322
|
+
discover?: (records: unknown[]) => unknown[];
|
|
323
|
+
/**
|
|
324
|
+
* Optional mapping hook — turn a single upstream record into a partial node.
|
|
325
|
+
* Reserved for ingestion (F2/F3); the foundation only stores it.
|
|
326
|
+
*/
|
|
327
|
+
map?: (record: unknown) => Partial<KBNode>;
|
|
328
|
+
}
|
|
329
|
+
/** Register (or replace) a node type. */
|
|
330
|
+
declare function registerType(def: NodeTypeDefinition): void;
|
|
331
|
+
/** Resolve a node type by id. Returns `undefined` for unknown ids. */
|
|
332
|
+
declare function resolveType(id: string | undefined): NodeTypeDefinition | undefined;
|
|
333
|
+
/** Whether a node type id is registered. */
|
|
334
|
+
declare function hasType(id: string): boolean;
|
|
335
|
+
/** All registered node types. */
|
|
336
|
+
declare function getRegisteredTypes(): NodeTypeDefinition[];
|
|
337
|
+
/** (Re)register the built-in source types. Idempotent. */
|
|
338
|
+
declare function registerBuiltInNodeTypes(): void;
|
|
339
|
+
/** Clear the registry back to just the built-ins. Intended for tests. */
|
|
340
|
+
declare function resetNodeTypeRegistry(): void;
|
|
341
|
+
/**
|
|
342
|
+
* Resolve a node's graph layer via the registry.
|
|
343
|
+
*
|
|
344
|
+
* Precedence: the node's `entityType` definition → its `source.type`
|
|
345
|
+
* definition → `'file'`. This preserves the historical mapping for built-in
|
|
346
|
+
* source types while letting registered entity types override the layer.
|
|
347
|
+
*/
|
|
348
|
+
declare function resolveNodeLayer(node: KBNode): NodeLayer;
|
|
349
|
+
/**
|
|
350
|
+
* Resolve the default cluster for a node from its type, when the node does not
|
|
351
|
+
* already declare one. Returns `undefined` when nothing is registered.
|
|
352
|
+
*/
|
|
353
|
+
declare function resolveTypeCluster(node: Pick<KBNode, 'entityType'> & {
|
|
354
|
+
source: {
|
|
355
|
+
type: string;
|
|
356
|
+
};
|
|
357
|
+
}): string | undefined;
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Normalized repo-data bundle (Phase 4 / F4 #318).
|
|
361
|
+
*
|
|
362
|
+
* The local and remote loaders historically differed only in *how* they
|
|
363
|
+
* obtained raw repository data — a pre-built manifest import vs live GitHub API
|
|
364
|
+
* calls — and then wired the *same* providers from it. {@link RepoData} is the
|
|
365
|
+
* normalized superset both acquisition paths produce, so a single
|
|
366
|
+
* `loadKnowledgeBase(source, config)` can wire providers once.
|
|
367
|
+
*
|
|
368
|
+
* A {@link RepoSource} is the system-of-record adapter: it both implements the
|
|
369
|
+
* pure {@link Source} contract from `@anokye-labs/kbexplorer-core` (self-
|
|
370
|
+
* describing, situationally-afforded {@link Resource}s) and exposes
|
|
371
|
+
* {@link RepoSource.getRepoData} — the engine-facing accessor the loader
|
|
372
|
+
* consumes to build the graph.
|
|
373
|
+
*/
|
|
374
|
+
|
|
375
|
+
/** Pull request shape consumed by the work + person providers (superset). */
|
|
376
|
+
interface RepoPullRequest {
|
|
377
|
+
number: number;
|
|
378
|
+
title: string;
|
|
379
|
+
body: string;
|
|
380
|
+
state: string;
|
|
381
|
+
labels: Array<{
|
|
382
|
+
name: string;
|
|
383
|
+
color: string;
|
|
384
|
+
}>;
|
|
385
|
+
html_url: string;
|
|
386
|
+
created_at: string;
|
|
387
|
+
updated_at: string;
|
|
388
|
+
head_branch?: string;
|
|
389
|
+
/** GitHub user who opened the PR (present from the API; absent from a manifest). */
|
|
390
|
+
user?: {
|
|
391
|
+
login: string;
|
|
392
|
+
};
|
|
393
|
+
/** Assignees (present from the API; absent from a manifest). */
|
|
394
|
+
assignees?: Array<{
|
|
395
|
+
login: string;
|
|
396
|
+
}>;
|
|
397
|
+
}
|
|
398
|
+
/** Repository metadata consumed by the work provider. */
|
|
399
|
+
interface RepoMetadata {
|
|
400
|
+
name: string;
|
|
401
|
+
description: string;
|
|
402
|
+
html_url: string;
|
|
403
|
+
/** Repo homepage URL (blank when unset). Matches the old generator's 12-key `fetchRepoMetadata` shape. */
|
|
404
|
+
homepage: string;
|
|
405
|
+
default_branch: string;
|
|
406
|
+
stargazers_count: number;
|
|
407
|
+
forks_count: number;
|
|
408
|
+
private: boolean;
|
|
409
|
+
topics: string[];
|
|
410
|
+
primary_language: string;
|
|
411
|
+
languages: Array<{
|
|
412
|
+
name: string;
|
|
413
|
+
size: number;
|
|
414
|
+
}>;
|
|
415
|
+
owner: {
|
|
416
|
+
login: string;
|
|
417
|
+
avatar_url: string;
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* The normalized raw-data bundle a {@link RepoSource} hands the loader. Optional
|
|
422
|
+
* fields degrade gracefully: a source that cannot supply them (e.g. the API
|
|
423
|
+
* source has no `nodemapRaw` yet) leaves them empty/null and the matching
|
|
424
|
+
* provider becomes a safe no-op — keeping output byte-identical per source.
|
|
425
|
+
*/
|
|
426
|
+
interface RepoData {
|
|
427
|
+
/** owner/name slug for file-node identity. */
|
|
428
|
+
repo: string;
|
|
429
|
+
tree: GHTreeItem[];
|
|
430
|
+
authoredContent: Record<string, string>;
|
|
431
|
+
nodemapRaw: string | null;
|
|
432
|
+
nodemapFiles?: Record<string, string>;
|
|
433
|
+
nodemapDirs?: Record<string, GHTreeItem[]>;
|
|
434
|
+
/** Glob lookup over authored/nodemap files (empty for sources without one). */
|
|
435
|
+
listFiles: (pattern: string) => Promise<string[]>;
|
|
436
|
+
issues: GHIssue[];
|
|
437
|
+
pullRequests: RepoPullRequest[];
|
|
438
|
+
commits: GHCommit[];
|
|
439
|
+
branches: Array<{
|
|
440
|
+
name: string;
|
|
441
|
+
protected: boolean;
|
|
442
|
+
}>;
|
|
443
|
+
repoMetadata: RepoMetadata | null;
|
|
444
|
+
releases: GHRelease[];
|
|
445
|
+
structuralFiles: Record<string, string>;
|
|
446
|
+
structuredNodeMapRaw: string | null;
|
|
447
|
+
contentModel: ContentModelSource | null;
|
|
448
|
+
readme: string | null;
|
|
449
|
+
themeFileRaw?: string | null;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* A system-of-record adapter. Implements the pure {@link Source} contract (the
|
|
453
|
+
* navigable, situationally-afforded resource surface) and exposes the
|
|
454
|
+
* engine-facing {@link getRepoData} the loader consumes.
|
|
455
|
+
*/
|
|
456
|
+
interface RepoSource extends Source {
|
|
457
|
+
/** Produce the normalized data bundle the provider pipeline consumes. */
|
|
458
|
+
getRepoData(): Promise<RepoData>;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export { type ContentModelSchema as C, type Diagnostic as D, type EngineEnv as E, type FkFlavor as F, type GHIssue as G, type JsonLdContext as J, type KindConvention as K, type Lifecycle as L, type NodeLayer as N, type OrgDef as O, type RepoSource as R, type TeamOps as T, type VocabularyOverlay as V, type ContentModelSource as a, type GHTreeItem as b, type GHRelease as c, type RepoData as d, type CompositeLeg as e, type Conventions as f, type DerivedRule as g, type DiagnosticLevel as h, type EdgeRule as i, type EdgesSpec as j, type GHCommit as k, type LifecycleBand as l, type NodeTypeDefinition as m, type Vocabulary as n, getRegisteredTypes as o, hasType as p, registerType as q, registerBuiltInNodeTypes as r, resetNodeTypeRegistry as s, resolveNodeLayer as t, resolveType as u, resolveTypeCluster as v, type RepoMetadata as w, type RepoPullRequest as x };
|