@miadi/inquiry-weave 0.16.5 → 0.17.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/README.md +19 -0
- package/dist/artefact-dsl.d.ts +58 -0
- package/dist/artefact-dsl.d.ts.map +1 -0
- package/dist/artefact-dsl.js +129 -0
- package/dist/artefact-dsl.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/lineage-view.d.ts +56 -0
- package/dist/lineage-view.d.ts.map +1 -0
- package/dist/lineage-view.js +141 -0
- package/dist/lineage-view.js.map +1 -0
- package/dist/mcp-server.js +162 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/mint.d.ts +199 -1
- package/dist/mint.d.ts.map +1 -1
- package/dist/mint.js +451 -0
- package/dist/mint.js.map +1 -1
- package/dist/notebook.d.ts +88 -0
- package/dist/notebook.d.ts.map +1 -0
- package/dist/notebook.js +258 -0
- package/dist/notebook.js.map +1 -0
- package/dist/prototype.d.ts +90 -0
- package/dist/prototype.d.ts.map +1 -0
- package/dist/prototype.js +286 -0
- package/dist/prototype.js.map +1 -0
- package/dist/references.d.ts +2 -0
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +2 -0
- package/dist/references.js.map +1 -1
- package/dist/rise-dsl.d.ts +44 -0
- package/dist/rise-dsl.d.ts.map +1 -0
- package/dist/rise-dsl.js +99 -0
- package/dist/rise-dsl.js.map +1 -0
- package/dist/rise-workspaces.d.ts +34 -0
- package/dist/rise-workspaces.d.ts.map +1 -0
- package/dist/rise-workspaces.js +73 -0
- package/dist/rise-workspaces.js.map +1 -0
- package/dist/rispec.d.ts +72 -0
- package/dist/rispec.d.ts.map +1 -0
- package/dist/rispec.js +227 -0
- package/dist/rispec.js.map +1 -0
- package/dist/text-references.d.ts +1 -1
- package/dist/text-references.d.ts.map +1 -1
- package/dist/text-references.js +18 -2
- package/dist/text-references.js.map +1 -1
- package/dist/tracing.d.ts +95 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +302 -0
- package/dist/tracing.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -268,6 +268,25 @@ the next authoring. `MIADI_EPISODE_DOOR=http` sends the MCP's episode tools
|
|
|
268
268
|
through the app at `MIADI_INQUIRY_API_BASE` even on a host that holds the
|
|
269
269
|
chronicle.
|
|
270
270
|
|
|
271
|
+
To read an episode's lineage for a page:
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
import { readEpisodeLineage, resolveLineage } from "@miadi/inquiry-weave"
|
|
275
|
+
|
|
276
|
+
const edges = await readEpisodeLineage(chronicleRoot, "2026-10-10-episode-551-learning-between-sessions")
|
|
277
|
+
// [{ kind: "related-to", label: "relates to", targetValue: "351", text, targetName, targetTitle }]
|
|
278
|
+
|
|
279
|
+
// Or, over a catalog already built:
|
|
280
|
+
const same = resolveLineage(entry, catalog.episodes)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`readEpisodeLineage` reads the folder names, the one manifest asked for, and the
|
|
284
|
+
manifests its edges resolve to. It never builds the whole catalog, and it returns
|
|
285
|
+
what `resolveLineage` returns over that catalog. A path carried with an edge names
|
|
286
|
+
its folder. Otherwise a number or slug resolves only when one folder holds it. When
|
|
287
|
+
several do, the edge keeps its raw `targetValue` and lists them in `candidates`.
|
|
288
|
+
`RELATION_LABELS` holds the words for each kind.
|
|
289
|
+
|
|
271
290
|
## Inquiry issues over MCP
|
|
272
291
|
|
|
273
292
|
`inquiry_list_issues` and `inquiry_get_issue` read the GitHub issues inquiries are
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The artefact schemes — addresses for what an episode holds beside its text
|
|
3
|
+
* (jgwill/Miadi#769, A2/A3 tail; grounding:
|
|
4
|
+
* foundations/resource-addressing-and-terminal-hypermedia/):
|
|
5
|
+
*
|
|
6
|
+
* miadi-notebook:<uuid> a Deep Diver notebook
|
|
7
|
+
* miadi-prototype:<slug> a prototype made from an episode
|
|
8
|
+
* miadi-tracing:<domain>/<resource>/<id>[@<v>] a trace, prompt, session, dataset or score config
|
|
9
|
+
* miadi-trace:<domain>/<id> alias of miadi-tracing:<domain>/trace/<id>
|
|
10
|
+
* miadi-prompt:<domain>/<name>[@<v>] alias of miadi-tracing:<domain>/prompt/<name>[@<v>]
|
|
11
|
+
*
|
|
12
|
+
* An address carries an identity and never a location: no Google URL for a
|
|
13
|
+
* notebook, no provider project id for a trace, no editing URL for a
|
|
14
|
+
* prototype. A door resolves it (`/api/chronicle/resolve`, `/api/chronicle/open`),
|
|
15
|
+
* and the wheel node behind it (`notebook:<uuid>`, `prototype:<slug>`,
|
|
16
|
+
* `tracing:<key>`) holds what the door answers. The grammar follows
|
|
17
|
+
* foundation-dsl: `//` accepted on input, `mc.*` options folded, control
|
|
18
|
+
* characters refused because a reference is printed into terminals.
|
|
19
|
+
*/
|
|
20
|
+
import { type TracingRef } from "@miadi/episodic-memory-schema";
|
|
21
|
+
export declare const MIADI_NOTEBOOK_SCHEME = "miadi-notebook:";
|
|
22
|
+
export declare const MIADI_PROTOTYPE_SCHEME = "miadi-prototype:";
|
|
23
|
+
export declare const MIADI_TRACING_SCHEME = "miadi-tracing:";
|
|
24
|
+
/** Input aliases, rewritten to the tracing scheme on parse. */
|
|
25
|
+
export declare const MIADI_TRACE_ALIAS = "miadi-trace:";
|
|
26
|
+
export declare const MIADI_PROMPT_ALIAS = "miadi-prompt:";
|
|
27
|
+
export type ArtefactKind = "notebook" | "prototype" | "tracing";
|
|
28
|
+
export interface ParsedArtefactUri {
|
|
29
|
+
/** The full original URI, exactly as given. */
|
|
30
|
+
uri: string;
|
|
31
|
+
/** The canonical spelling: the tracing scheme for the aliases, options and fragment preserved. */
|
|
32
|
+
canonical: string;
|
|
33
|
+
kind: ArtefactKind;
|
|
34
|
+
/** The identity: a notebook uuid, a prototype slug, or `<domain>/<resource>/<id>`. */
|
|
35
|
+
id: string;
|
|
36
|
+
/** For a tracing address, its parts. */
|
|
37
|
+
tracing?: TracingRef;
|
|
38
|
+
/** Query params minus the mc.* rendering options. */
|
|
39
|
+
query: Record<string, string>;
|
|
40
|
+
/** mc.* rendering options, prefix stripped (show, label, …). */
|
|
41
|
+
options: Record<string, string>;
|
|
42
|
+
fragment?: string;
|
|
43
|
+
}
|
|
44
|
+
export declare function isArtefactUri(href: string | undefined): boolean;
|
|
45
|
+
/** The canonical address of an artefact without options. */
|
|
46
|
+
export declare function canonicalArtefactRef(kind: ArtefactKind, id: string): string;
|
|
47
|
+
export declare function parseArtefactUri(uri: string): ParsedArtefactUri | null;
|
|
48
|
+
/**
|
|
49
|
+
* Where a chip points: the host's open door with the canonical address, so
|
|
50
|
+
* the reader's browser never carries a Google URL, a provider page or a
|
|
51
|
+
* project id; the door redirects to what the reader may see.
|
|
52
|
+
*/
|
|
53
|
+
export declare function artefactOpenRoute(parsed: Pick<ParsedArtefactUri, "kind" | "id">): string;
|
|
54
|
+
/** The wheel node id an artefact address names. A tracing node is keyed without the prompt version the address may pin. */
|
|
55
|
+
export declare function artefactNodeId(parsed: Pick<ParsedArtefactUri, "kind" | "id" | "tracing">): string;
|
|
56
|
+
/** Every artefact address in a text, as written, in order of first appearance. */
|
|
57
|
+
export declare function extractArtefactUris(text: string): string[];
|
|
58
|
+
//# sourceMappingURL=artefact-dsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artefact-dsl.d.ts","sourceRoot":"","sources":["../src/artefact-dsl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAKL,KAAK,UAAU,EAEhB,MAAM,+BAA+B,CAAA;AAGtC,eAAO,MAAM,qBAAqB,oBAAoB,CAAA;AACtD,eAAO,MAAM,sBAAsB,qBAAqB,CAAA;AACxD,eAAO,MAAM,oBAAoB,mBAAmB,CAAA;AACpD,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,iBAAiB,CAAA;AAC/C,eAAO,MAAM,kBAAkB,kBAAkB,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAA;AAE/D,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAA;IACX,kGAAkG;IAClG,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,YAAY,CAAA;IAClB,sFAAsF;IACtF,EAAE,EAAE,MAAM,CAAA;IACV,wCAAwC;IACxC,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAKD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAE/D;AAUD,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CA6CtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAExF;AAED,2HAA2H;AAC3H,wBAAgB,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,CAGjG;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAc1D"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The artefact schemes — addresses for what an episode holds beside its text
|
|
3
|
+
* (jgwill/Miadi#769, A2/A3 tail; grounding:
|
|
4
|
+
* foundations/resource-addressing-and-terminal-hypermedia/):
|
|
5
|
+
*
|
|
6
|
+
* miadi-notebook:<uuid> a Deep Diver notebook
|
|
7
|
+
* miadi-prototype:<slug> a prototype made from an episode
|
|
8
|
+
* miadi-tracing:<domain>/<resource>/<id>[@<v>] a trace, prompt, session, dataset or score config
|
|
9
|
+
* miadi-trace:<domain>/<id> alias of miadi-tracing:<domain>/trace/<id>
|
|
10
|
+
* miadi-prompt:<domain>/<name>[@<v>] alias of miadi-tracing:<domain>/prompt/<name>[@<v>]
|
|
11
|
+
*
|
|
12
|
+
* An address carries an identity and never a location: no Google URL for a
|
|
13
|
+
* notebook, no provider project id for a trace, no editing URL for a
|
|
14
|
+
* prototype. A door resolves it (`/api/chronicle/resolve`, `/api/chronicle/open`),
|
|
15
|
+
* and the wheel node behind it (`notebook:<uuid>`, `prototype:<slug>`,
|
|
16
|
+
* `tracing:<key>`) holds what the door answers. The grammar follows
|
|
17
|
+
* foundation-dsl: `//` accepted on input, `mc.*` options folded, control
|
|
18
|
+
* characters refused because a reference is printed into terminals.
|
|
19
|
+
*/
|
|
20
|
+
import { isPrototypeSlug, parseNotebookRef, parseTracingRef, tracingReference, tracingNodeId, } from "@miadi/episodic-memory-schema";
|
|
21
|
+
import { OPTION_PREFIX } from "./chronicle-dsl.js";
|
|
22
|
+
export const MIADI_NOTEBOOK_SCHEME = "miadi-notebook:";
|
|
23
|
+
export const MIADI_PROTOTYPE_SCHEME = "miadi-prototype:";
|
|
24
|
+
export const MIADI_TRACING_SCHEME = "miadi-tracing:";
|
|
25
|
+
/** Input aliases, rewritten to the tracing scheme on parse. */
|
|
26
|
+
export const MIADI_TRACE_ALIAS = "miadi-trace:";
|
|
27
|
+
export const MIADI_PROMPT_ALIAS = "miadi-prompt:";
|
|
28
|
+
// [1]=scheme word [2]=path [3]=query [4]=fragment
|
|
29
|
+
const ARTEFACT_URI_RE = /^miadi-(notebook|prototype|tracing|trace|prompt):(?:\/\/)?([^?#\s\u0000-\u001f\u007f-\u009f]{1,400})\/?(?:\?([^#\u0000-\u001f\u007f-\u009f]*))?(?:#([^\u0000-\u001f\u007f-\u009f]*))?$/i;
|
|
30
|
+
export function isArtefactUri(href) {
|
|
31
|
+
return typeof href === "string" && /^miadi-(?:notebook|prototype|tracing|trace|prompt):/i.test(href.trim());
|
|
32
|
+
}
|
|
33
|
+
function safeDecode(s) {
|
|
34
|
+
try {
|
|
35
|
+
return decodeURIComponent(s);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return s;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** The canonical address of an artefact without options. */
|
|
42
|
+
export function canonicalArtefactRef(kind, id) {
|
|
43
|
+
return `${kind === "notebook" ? MIADI_NOTEBOOK_SCHEME : kind === "prototype" ? MIADI_PROTOTYPE_SCHEME : MIADI_TRACING_SCHEME}${id}`;
|
|
44
|
+
}
|
|
45
|
+
export function parseArtefactUri(uri) {
|
|
46
|
+
const trimmed = uri.trim();
|
|
47
|
+
const m = ARTEFACT_URI_RE.exec(trimmed);
|
|
48
|
+
if (!m || !m[1] || !m[2])
|
|
49
|
+
return null;
|
|
50
|
+
const scheme = m[1].toLowerCase();
|
|
51
|
+
const path = m[2];
|
|
52
|
+
let kind;
|
|
53
|
+
let id;
|
|
54
|
+
let tracing;
|
|
55
|
+
if (scheme === "notebook") {
|
|
56
|
+
const ref = parseNotebookRef(path);
|
|
57
|
+
if (!ref)
|
|
58
|
+
return null;
|
|
59
|
+
kind = "notebook";
|
|
60
|
+
id = ref.id;
|
|
61
|
+
}
|
|
62
|
+
else if (scheme === "prototype") {
|
|
63
|
+
if (!isPrototypeSlug(path) || path.includes(".."))
|
|
64
|
+
return null;
|
|
65
|
+
kind = "prototype";
|
|
66
|
+
id = path;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// tracing, or an alias that names the resource by its scheme word
|
|
70
|
+
const key = scheme === "trace" ? path.replace(/^([a-z]+)\//, "$1/trace/") : scheme === "prompt" ? path.replace(/^([a-z]+)\//, "$1/prompt/") : path;
|
|
71
|
+
const ref = parseTracingRef(key);
|
|
72
|
+
if (!ref)
|
|
73
|
+
return null;
|
|
74
|
+
kind = "tracing";
|
|
75
|
+
tracing = ref;
|
|
76
|
+
id = tracingReference(ref.domain, ref.resource, ref.id, ref.version).slice(MIADI_TRACING_SCHEME.length);
|
|
77
|
+
}
|
|
78
|
+
const query = {};
|
|
79
|
+
const options = {};
|
|
80
|
+
for (const pair of (m[3] ?? "").split("&")) {
|
|
81
|
+
if (!pair)
|
|
82
|
+
continue;
|
|
83
|
+
const eq = pair.indexOf("=");
|
|
84
|
+
const key = safeDecode(eq === -1 ? pair : pair.slice(0, eq));
|
|
85
|
+
const value = eq === -1 ? "" : safeDecode(pair.slice(eq + 1));
|
|
86
|
+
if (key.startsWith(OPTION_PREFIX))
|
|
87
|
+
options[key.slice(OPTION_PREFIX.length)] = value;
|
|
88
|
+
else
|
|
89
|
+
query[key] = value;
|
|
90
|
+
}
|
|
91
|
+
const fragment = m[4] || undefined;
|
|
92
|
+
const params = [
|
|
93
|
+
...Object.entries(query).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`),
|
|
94
|
+
...Object.entries(options).map(([k, v]) => `${OPTION_PREFIX}${encodeURIComponent(k)}=${encodeURIComponent(v)}`),
|
|
95
|
+
];
|
|
96
|
+
const canonical = canonicalArtefactRef(kind, id) + (params.length > 0 ? `?${params.join("&")}` : "") + (fragment ? `#${fragment}` : "");
|
|
97
|
+
return { uri: trimmed, canonical, kind, id, ...(tracing ? { tracing } : {}), query, options, ...(fragment ? { fragment } : {}) };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Where a chip points: the host's open door with the canonical address, so
|
|
101
|
+
* the reader's browser never carries a Google URL, a provider page or a
|
|
102
|
+
* project id; the door redirects to what the reader may see.
|
|
103
|
+
*/
|
|
104
|
+
export function artefactOpenRoute(parsed) {
|
|
105
|
+
return `/api/chronicle/open?uri=${encodeURIComponent(canonicalArtefactRef(parsed.kind, parsed.id))}`;
|
|
106
|
+
}
|
|
107
|
+
/** The wheel node id an artefact address names. A tracing node is keyed without the prompt version the address may pin. */
|
|
108
|
+
export function artefactNodeId(parsed) {
|
|
109
|
+
if (parsed.kind === "tracing" && parsed.tracing)
|
|
110
|
+
return tracingNodeId(parsed.tracing.domain, parsed.tracing.resource, parsed.tracing.id);
|
|
111
|
+
return `${parsed.kind}:${parsed.id}`;
|
|
112
|
+
}
|
|
113
|
+
/** Every artefact address in a text, as written, in order of first appearance. */
|
|
114
|
+
export function extractArtefactUris(text) {
|
|
115
|
+
const seen = new Set();
|
|
116
|
+
const out = [];
|
|
117
|
+
const re = /(?<![\w/?=&%.~+:@#!-])miadi-(?:notebook|prototype|tracing|trace|prompt):(?:\/\/)?[A-Za-z0-9._~:/?=&%#+@-]{1,512}/gi;
|
|
118
|
+
// Code is not a reference: fences and spans are blanked before the scan.
|
|
119
|
+
const prose = text.replace(/```[\s\S]*?```/g, " ").replace(/`[^`\n]*`/g, " ");
|
|
120
|
+
for (const m of prose.matchAll(re)) {
|
|
121
|
+
const raw = m[0].replace(/[.,;:)\]]+$/, "");
|
|
122
|
+
if (!seen.has(raw) && parseArtefactUri(raw)) {
|
|
123
|
+
seen.add(raw);
|
|
124
|
+
out.push(raw);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=artefact-dsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artefact-dsl.js","sourceRoot":"","sources":["../src/artefact-dsl.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./issue.js";
|
|
|
9
9
|
export * from "./issue-content.js";
|
|
10
10
|
export * from "./relate.js";
|
|
11
11
|
export * from "./lineage.js";
|
|
12
|
+
export * from "./lineage-view.js";
|
|
12
13
|
export * from "./status.js";
|
|
13
14
|
export * from "./artefact-issue.js";
|
|
14
15
|
export * from "./register.js";
|
|
@@ -23,6 +24,11 @@ export * from "./chronicle-dsl.js";
|
|
|
23
24
|
export * from "./foundation-dsl.js";
|
|
24
25
|
export * from "./markdown-directives.js";
|
|
25
26
|
export * from "./foundation.js";
|
|
27
|
+
export * from "./notebook.js";
|
|
28
|
+
export * from "./prototype.js";
|
|
29
|
+
export * from "./tracing.js";
|
|
30
|
+
export * from "./rispec.js";
|
|
31
|
+
export * from "./rise-workspaces.js";
|
|
26
32
|
export * from "./chronicle-terminal.js";
|
|
27
33
|
export * from "./story-library.js";
|
|
28
34
|
export * from "./git-landing.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./issue.js";
|
|
|
9
9
|
export * from "./issue-content.js";
|
|
10
10
|
export * from "./relate.js";
|
|
11
11
|
export * from "./lineage.js";
|
|
12
|
+
export * from "./lineage-view.js";
|
|
12
13
|
export * from "./status.js";
|
|
13
14
|
export * from "./artefact-issue.js";
|
|
14
15
|
export * from "./register.js";
|
|
@@ -23,6 +24,11 @@ export * from "./chronicle-dsl.js";
|
|
|
23
24
|
export * from "./foundation-dsl.js";
|
|
24
25
|
export * from "./markdown-directives.js";
|
|
25
26
|
export * from "./foundation.js";
|
|
27
|
+
export * from "./notebook.js";
|
|
28
|
+
export * from "./prototype.js";
|
|
29
|
+
export * from "./tracing.js";
|
|
30
|
+
export * from "./rispec.js";
|
|
31
|
+
export * from "./rise-workspaces.js";
|
|
26
32
|
export * from "./chronicle-terminal.js";
|
|
27
33
|
export * from "./story-library.js";
|
|
28
34
|
export * from "./git-landing.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,MAAM,EAAuC,MAAM,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,MAAM,EAAuC,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lineage as a reader sees it: each relation an episode declares, pointed at
|
|
3
|
+
* the folder it names when the chronicle answers with exactly one.
|
|
4
|
+
*
|
|
5
|
+
* `resolveLineage` works over a catalog the caller already holds.
|
|
6
|
+
* `readEpisodeLineage` answers the same question for one episode without
|
|
7
|
+
* building the catalog: it lists the root's folder names, reads the one
|
|
8
|
+
* manifest whose edges are asked for, and reads only the manifests its edges
|
|
9
|
+
* resolve to, for their titles. Over a whole chronicle the two agree.
|
|
10
|
+
*
|
|
11
|
+
* A number or a slug that two folders claim resolves to neither. The chronicle
|
|
12
|
+
* holds such collisions, and the folder name is the key
|
|
13
|
+
* (`chronicle.episode-number-collision`), so an arbitrary pick would send the
|
|
14
|
+
* reader to the wrong episode. The edge keeps its raw value and lists the
|
|
15
|
+
* claimants in `candidates`, so a surface can offer the choice. A path carried
|
|
16
|
+
* with the relation names one folder and settles the edge.
|
|
17
|
+
*/
|
|
18
|
+
import { type EpisodeManifestEntry } from "@miadi/episodic-memory-schema";
|
|
19
|
+
import type { CatalogFs } from "./catalog.js";
|
|
20
|
+
/** How a relation kind reads in a sentence: "E352 continues from E351". */
|
|
21
|
+
export declare const RELATION_LABELS: Readonly<Record<string, string>>;
|
|
22
|
+
/** One lineage edge, ready to render. */
|
|
23
|
+
export interface LineageEdgeView {
|
|
24
|
+
/** The relation kind as the manifest observation names it, e.g. `continues-from`. */
|
|
25
|
+
kind: string;
|
|
26
|
+
/** The kind as words, e.g. "continues from". */
|
|
27
|
+
label: string;
|
|
28
|
+
/** The raw target: an episode number, a slug, a title or a path. */
|
|
29
|
+
targetValue: string;
|
|
30
|
+
/** The folder the edge points at, when exactly one answers. */
|
|
31
|
+
targetName?: string;
|
|
32
|
+
/** That folder's title, or its slug when its manifest names none. */
|
|
33
|
+
targetTitle?: string;
|
|
34
|
+
/** Why the two are related, as `episode.yaml` records it (`relation:`). */
|
|
35
|
+
text?: string;
|
|
36
|
+
/** The folders that claim the target when more than one does, by name. */
|
|
37
|
+
candidates?: string[];
|
|
38
|
+
}
|
|
39
|
+
/** What resolution needs to know of each episode in the chronicle. */
|
|
40
|
+
export type LineageCandidate = Pick<EpisodeManifestEntry, "name" | "number" | "slug" | "title">;
|
|
41
|
+
/**
|
|
42
|
+
* One episode's lineage edges, each pointed at the folder it names when
|
|
43
|
+
* exactly one in `episodes` answers.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveLineage(entry: Pick<EpisodeManifestEntry, "relations">, episodes: readonly LineageCandidate[]): LineageEdgeView[];
|
|
46
|
+
export interface ReadEpisodeLineageOptions {
|
|
47
|
+
fs?: CatalogFs;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* One episode's lineage, resolved against the chronicle, without building the
|
|
51
|
+
* catalog. Equal to `resolveLineage(entry, catalog.episodes)` for the entry
|
|
52
|
+
* `buildChronicleCatalog` would produce. An episode the root does not hold has
|
|
53
|
+
* no edges.
|
|
54
|
+
*/
|
|
55
|
+
export declare function readEpisodeLineage(chronicleRoot: string, episode: string, options?: ReadEpisodeLineageOptions): Promise<LineageEdgeView[]>;
|
|
56
|
+
//# sourceMappingURL=lineage-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineage-view.d.ts","sourceRoot":"","sources":["../src/lineage-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAA8B,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACrG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG7C,2EAA2E;AAC3E,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5D,CAAA;AAED,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAA;IACnB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,sEAAsE;AACtE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;AA8D/F;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,EAC9C,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,eAAe,EAAE,CAGnB;AAOD,MAAM,WAAW,yBAAyB;IACxC,EAAE,CAAC,EAAE,SAAS,CAAA;CACf;AAcD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC,CAuB5B"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lineage as a reader sees it: each relation an episode declares, pointed at
|
|
3
|
+
* the folder it names when the chronicle answers with exactly one.
|
|
4
|
+
*
|
|
5
|
+
* `resolveLineage` works over a catalog the caller already holds.
|
|
6
|
+
* `readEpisodeLineage` answers the same question for one episode without
|
|
7
|
+
* building the catalog: it lists the root's folder names, reads the one
|
|
8
|
+
* manifest whose edges are asked for, and reads only the manifests its edges
|
|
9
|
+
* resolve to, for their titles. Over a whole chronicle the two agree.
|
|
10
|
+
*
|
|
11
|
+
* A number or a slug that two folders claim resolves to neither. The chronicle
|
|
12
|
+
* holds such collisions, and the folder name is the key
|
|
13
|
+
* (`chronicle.episode-number-collision`), so an arbitrary pick would send the
|
|
14
|
+
* reader to the wrong episode. The edge keeps its raw value and lists the
|
|
15
|
+
* claimants in `candidates`, so a surface can offer the choice. A path carried
|
|
16
|
+
* with the relation names one folder and settles the edge.
|
|
17
|
+
*/
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
20
|
+
import { parse } from "yaml";
|
|
21
|
+
import { observeEpisodeYamlManifest } from "@miadi/episodic-memory-schema";
|
|
22
|
+
import { parseEpisodeName } from "./episode.js";
|
|
23
|
+
/** How a relation kind reads in a sentence: "E352 continues from E351". */
|
|
24
|
+
export const RELATION_LABELS = {
|
|
25
|
+
"continues-from": "continues from",
|
|
26
|
+
"branch-of": "branch of",
|
|
27
|
+
"related-to": "relates to",
|
|
28
|
+
};
|
|
29
|
+
/** Path hints are bare folders, absolute paths or `<folder>/episode.yaml`; the last segment naming a folder wins. */
|
|
30
|
+
function byPath(raw, byName) {
|
|
31
|
+
const segments = raw.split("/").filter(Boolean);
|
|
32
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
33
|
+
const hit = byName.get(segments[i]);
|
|
34
|
+
if (hit)
|
|
35
|
+
return hit;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const titleOf = (target) => target.title ?? target.slug;
|
|
40
|
+
function index(episodes) {
|
|
41
|
+
const byName = new Map();
|
|
42
|
+
const byNumber = new Map();
|
|
43
|
+
const bySlug = new Map();
|
|
44
|
+
for (const episode of episodes) {
|
|
45
|
+
byName.set(episode.name, episode);
|
|
46
|
+
if (episode.number !== undefined)
|
|
47
|
+
byNumber.set(episode.number, [...(byNumber.get(episode.number) ?? []), episode]);
|
|
48
|
+
if (episode.slug) {
|
|
49
|
+
const slug = episode.slug.toLowerCase();
|
|
50
|
+
bySlug.set(slug, [...(bySlug.get(slug) ?? []), episode]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { byName, byNumber, bySlug };
|
|
54
|
+
}
|
|
55
|
+
function resolveOne(relation, lookup) {
|
|
56
|
+
const view = {
|
|
57
|
+
kind: relation.kind,
|
|
58
|
+
label: RELATION_LABELS[relation.kind] ?? relation.kind.replace(/-/g, " "),
|
|
59
|
+
targetValue: relation.target.value,
|
|
60
|
+
};
|
|
61
|
+
const text = typeof relation.metadata?.relation === "string" ? relation.metadata.relation.trim() : "";
|
|
62
|
+
if (text)
|
|
63
|
+
view.text = text;
|
|
64
|
+
const hint = (typeof relation.metadata?.path === "string" ? relation.metadata.path : undefined) ??
|
|
65
|
+
(relation.target.kind === "path" ? relation.target.value : undefined);
|
|
66
|
+
const pathHit = hint ? byPath(hint, lookup.byName) : undefined;
|
|
67
|
+
const hits = pathHit
|
|
68
|
+
? [pathHit]
|
|
69
|
+
: relation.target.kind === "episode-number"
|
|
70
|
+
? lookup.byNumber.get(Number(relation.target.value)) ?? []
|
|
71
|
+
: relation.target.kind === "slug"
|
|
72
|
+
? lookup.bySlug.get(relation.target.value.toLowerCase()) ?? []
|
|
73
|
+
: [];
|
|
74
|
+
if (hits.length === 1) {
|
|
75
|
+
view.targetName = hits[0].name;
|
|
76
|
+
const title = titleOf(hits[0]);
|
|
77
|
+
if (title !== undefined)
|
|
78
|
+
view.targetTitle = title;
|
|
79
|
+
}
|
|
80
|
+
else if (hits.length > 1) {
|
|
81
|
+
view.candidates = hits.map((hit) => hit.name).sort();
|
|
82
|
+
}
|
|
83
|
+
return view;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* One episode's lineage edges, each pointed at the folder it names when
|
|
87
|
+
* exactly one in `episodes` answers.
|
|
88
|
+
*/
|
|
89
|
+
export function resolveLineage(entry, episodes) {
|
|
90
|
+
const lookup = index(episodes);
|
|
91
|
+
return entry.relations.map((relation) => resolveOne(relation, lookup));
|
|
92
|
+
}
|
|
93
|
+
const nodeFs = {
|
|
94
|
+
readdir: (dir) => readdir(dir, { withFileTypes: true }),
|
|
95
|
+
readFile: (path) => readFile(path, "utf8"),
|
|
96
|
+
};
|
|
97
|
+
/** A manifest's observation, or undefined when it is missing or unreadable — as the catalog treats it. */
|
|
98
|
+
async function observe(fs, chronicleRoot, name) {
|
|
99
|
+
const relativePath = `${name}/episode.yaml`;
|
|
100
|
+
try {
|
|
101
|
+
return observeEpisodeYamlManifest(parse(await fs.readFile(join(chronicleRoot, name, "episode.yaml"))), {
|
|
102
|
+
relativePath,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* One episode's lineage, resolved against the chronicle, without building the
|
|
111
|
+
* catalog. Equal to `resolveLineage(entry, catalog.episodes)` for the entry
|
|
112
|
+
* `buildChronicleCatalog` would produce. An episode the root does not hold has
|
|
113
|
+
* no edges.
|
|
114
|
+
*/
|
|
115
|
+
export async function readEpisodeLineage(chronicleRoot, episode, options = {}) {
|
|
116
|
+
const fs = options.fs ?? nodeFs;
|
|
117
|
+
const shelf = [];
|
|
118
|
+
for (const entry of await fs.readdir(chronicleRoot)) {
|
|
119
|
+
if (!entry.isDirectory())
|
|
120
|
+
continue;
|
|
121
|
+
const parsed = parseEpisodeName(entry.name);
|
|
122
|
+
if (parsed.number === undefined)
|
|
123
|
+
continue;
|
|
124
|
+
shelf.push({ name: entry.name, number: parsed.number, slug: parsed.slug });
|
|
125
|
+
}
|
|
126
|
+
if (!shelf.some((candidate) => candidate.name === episode))
|
|
127
|
+
return [];
|
|
128
|
+
const observation = await observe(fs, chronicleRoot, episode);
|
|
129
|
+
const edges = resolveLineage({ relations: observation?.relations ?? [] }, shelf);
|
|
130
|
+
const titles = new Map();
|
|
131
|
+
for (const name of new Set(edges.flatMap((edge) => (edge.targetName ? [edge.targetName] : [])))) {
|
|
132
|
+
titles.set(name, (await observe(fs, chronicleRoot, name))?.sourceMetadata.title);
|
|
133
|
+
}
|
|
134
|
+
for (const edge of edges) {
|
|
135
|
+
const title = edge.targetName ? titles.get(edge.targetName) : undefined;
|
|
136
|
+
if (title !== undefined)
|
|
137
|
+
edge.targetTitle = title;
|
|
138
|
+
}
|
|
139
|
+
return edges;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=lineage-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineage-view.js","sourceRoot":"","sources":["../src/lineage-view.ts"],"names":[],"mappings":"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"}
|