@miadi/episodic-memory-schema 0.11.1 → 0.13.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 CHANGED
@@ -182,6 +182,14 @@ modifies source material.
182
182
  - **Reviews held by an episode.** `parseReviewRef`, `readEpisodeReviews`, `reviewNodeId` and
183
183
  `EpisodeReviewEntry` type a Miadi review inside `episode.yaml` (`reviews:`), with its
184
184
  `review:<uuid>` node id. Pure: no fs, no fetch.
185
+ - **Screenwalks.** `ScreenwalkRecord` types a screenwalk, a recording of a person working live
186
+ with agent sessions, as an episode holds it in `captures/screenwalk-<id>/screenwalk.json`: its
187
+ id is the stamp the person names when recording starts (`miadi-screenwalk:<yymmddHHMM>`), and
188
+ it gathers the sessions on screen with their ledgers, the video, the review, transcriptions,
189
+ witness closings and outputs (dialogue, chapters, shorts). `toScreenwalkRecord` also reads the
190
+ screenwalk `capture.json` files written by hand before the record existed, `isScreenwalkRecord`
191
+ guards the written form, and `@miadi/episodic-memory-schema/schema/screenwalk` is its JSON
192
+ Schema. Pure: no fs, no fetch.
185
193
 
186
194
  ## Versioning
187
195
 
@@ -0,0 +1,85 @@
1
+ /**
2
+ * The chronicle FOUNDATION contract — a foundation packet held by an episode.
3
+ *
4
+ * A foundation packet is academic grounding (`foundations/<slug>/` in a repo,
5
+ * distributed in `@miadi/foundations`). Its address is
6
+ * `miadi-foundation:<slug>`. An episode holds one the way it holds a review
7
+ * (jgwill/Miadi#630): the packet is one reusable node on the wheel
8
+ * (`foundation:<slug>`), the episode relates to it with an edge naming what it
9
+ * uses the packet for, and the episode keeps its own record of the version it
10
+ * read. Packets get corrected; the version is what the episode stood on.
11
+ *
12
+ * An episode can also hold a small foundation of its own, written inside the
13
+ * vessel under `foundations/<topic>/`. That packet belongs to the episode: its
14
+ * address is `miadi-chronicle:<episode>/foundations/<topic>`, and its wheel
15
+ * node is keyed by the episode folder so two episodes can each hold a topic of
16
+ * the same name.
17
+ *
18
+ * Manifest shape (`episode.yaml`):
19
+ *
20
+ * foundations:
21
+ * - slug: resource-addressing-and-terminal-hypermedia
22
+ * source: package
23
+ * version: 0.1.6
24
+ * title: Resource Addressing & Terminal Hypermedia
25
+ * relation: grounded-by
26
+ * added: '2026-10-02T10:30:00.000Z'
27
+ * - slug: screenwalk-media-type
28
+ * source: episode
29
+ * path: foundations/screenwalk-media-type
30
+ *
31
+ * A `miadi-foundation:<slug>` string in `references:` is read as a held
32
+ * packet too. Pure — no fs, no fetch. Ref: jgwill/Miadi#713, jgwill/Miadi#548.
33
+ */
34
+ /** The address scheme of a distributed foundation packet. */
35
+ export declare const FOUNDATION_REFERENCE_PREFIX = "miadi-foundation:";
36
+ /** Wheel node ids for foundations: `foundation:<slug>`. */
37
+ export declare const FOUNDATION_NODE_PREFIX = "foundation:";
38
+ /** The wheel metadata kind a foundation node carries. */
39
+ export declare const FOUNDATION_NODE_KIND = "miadi_foundation";
40
+ /** Where an episode keeps the small foundations it authors itself. */
41
+ export declare const EPISODE_FOUNDATIONS_DIR = "foundations";
42
+ /** What an episode uses a packet for when nobody said: "Episode grounded-by Foundation". */
43
+ export declare const DEFAULT_FOUNDATION_RELATION = "grounded-by";
44
+ /** `package`: a packet from `@miadi/foundations`. `episode`: a packet inside this episode's vessel. */
45
+ export type FoundationSource = "package" | "episode";
46
+ export declare function isFoundationSlug(value: unknown): value is string;
47
+ /**
48
+ * The wheel node id of a held packet. A distributed packet is one node shared
49
+ * by every episode; an episode's own packet is keyed by the episode folder.
50
+ */
51
+ export declare function foundationNodeId(slug: string, episodeFolder?: string): string;
52
+ /** The slug a `miadi-foundation:` reference names, or null. `//` is accepted on input. */
53
+ export declare function foundationSlugOf(reference: unknown): string | null;
54
+ /** One foundation as an episode records it. */
55
+ export interface EpisodeFoundationEntry {
56
+ /** The packet directory name. */
57
+ slug: string;
58
+ source: FoundationSource;
59
+ /** The `@miadi/foundations` version read (source `package`). */
60
+ version?: string;
61
+ title?: string;
62
+ /** Vessel-relative directory of an episode's own packet (source `episode`). */
63
+ path?: string;
64
+ /** What the episode uses the packet for: completes "Episode <relation> Foundation". */
65
+ relation?: string;
66
+ /** ISO timestamp the packet entered the episode. */
67
+ added?: string;
68
+ }
69
+ export interface ObservedEpisodeFoundation extends EpisodeFoundationEntry {
70
+ /** `foundations` for a structured entry, `references` for a `miadi-foundation:` citation. */
71
+ declared: "foundations" | "references";
72
+ }
73
+ /** The entry's keys in the order the manifest writes them. */
74
+ export declare const FOUNDATION_ENTRY_KEYS: readonly ["slug", "source", "version", "title", "path", "relation", "added"];
75
+ /** An episode's own packet lives under `foundations/<slug>`, and nowhere else. */
76
+ export declare function episodeFoundationPath(slug: string): string;
77
+ /** Tolerant reader for one `foundations:` item. Null when it names no packet. */
78
+ export declare function toEpisodeFoundationEntry(raw: unknown): EpisodeFoundationEntry | null;
79
+ /**
80
+ * Every foundation a parsed `episode.yaml` holds: the structured
81
+ * `foundations:` list first, then `miadi-foundation:` citations in
82
+ * `references:` that the list does not already name. One entry per packet.
83
+ */
84
+ export declare function readEpisodeFoundations(manifest: unknown): ObservedEpisodeFoundation[];
85
+ //# sourceMappingURL=episode-foundation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"episode-foundation.d.ts","sourceRoot":"","sources":["../src/episode-foundation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,2BAA2B,sBAAsB,CAAA;AAE9D,2DAA2D;AAC3D,eAAO,MAAM,sBAAsB,gBAAgB,CAAA;AAEnD,yDAAyD;AACzD,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AAEtD,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,gBAAgB,CAAA;AAEpD,4FAA4F;AAC5F,eAAO,MAAM,2BAA2B,gBAAgB,CAAA;AAExD,uGAAuG;AACvG,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,CAAA;AAKpD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEhE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIlE;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,gBAAgB,CAAA;IACxB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACvE,6FAA6F;IAC7F,QAAQ,EAAE,aAAa,GAAG,YAAY,CAAA;CACvC;AAED,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,8EAA+E,CAAA;AAOjH,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,sBAAsB,GAAG,IAAI,CAuBpF;AAID;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,yBAAyB,EAAE,CAoBrF"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * The chronicle FOUNDATION contract — a foundation packet held by an episode.
3
+ *
4
+ * A foundation packet is academic grounding (`foundations/<slug>/` in a repo,
5
+ * distributed in `@miadi/foundations`). Its address is
6
+ * `miadi-foundation:<slug>`. An episode holds one the way it holds a review
7
+ * (jgwill/Miadi#630): the packet is one reusable node on the wheel
8
+ * (`foundation:<slug>`), the episode relates to it with an edge naming what it
9
+ * uses the packet for, and the episode keeps its own record of the version it
10
+ * read. Packets get corrected; the version is what the episode stood on.
11
+ *
12
+ * An episode can also hold a small foundation of its own, written inside the
13
+ * vessel under `foundations/<topic>/`. That packet belongs to the episode: its
14
+ * address is `miadi-chronicle:<episode>/foundations/<topic>`, and its wheel
15
+ * node is keyed by the episode folder so two episodes can each hold a topic of
16
+ * the same name.
17
+ *
18
+ * Manifest shape (`episode.yaml`):
19
+ *
20
+ * foundations:
21
+ * - slug: resource-addressing-and-terminal-hypermedia
22
+ * source: package
23
+ * version: 0.1.6
24
+ * title: Resource Addressing & Terminal Hypermedia
25
+ * relation: grounded-by
26
+ * added: '2026-10-02T10:30:00.000Z'
27
+ * - slug: screenwalk-media-type
28
+ * source: episode
29
+ * path: foundations/screenwalk-media-type
30
+ *
31
+ * A `miadi-foundation:<slug>` string in `references:` is read as a held
32
+ * packet too. Pure — no fs, no fetch. Ref: jgwill/Miadi#713, jgwill/Miadi#548.
33
+ */
34
+ /** The address scheme of a distributed foundation packet. */
35
+ export const FOUNDATION_REFERENCE_PREFIX = "miadi-foundation:";
36
+ /** Wheel node ids for foundations: `foundation:<slug>`. */
37
+ export const FOUNDATION_NODE_PREFIX = "foundation:";
38
+ /** The wheel metadata kind a foundation node carries. */
39
+ export const FOUNDATION_NODE_KIND = "miadi_foundation";
40
+ /** Where an episode keeps the small foundations it authors itself. */
41
+ export const EPISODE_FOUNDATIONS_DIR = "foundations";
42
+ /** What an episode uses a packet for when nobody said: "Episode grounded-by Foundation". */
43
+ export const DEFAULT_FOUNDATION_RELATION = "grounded-by";
44
+ // A packet directory name: no separator, no leading dot, never `..`.
45
+ const SLUG = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
46
+ export function isFoundationSlug(value) {
47
+ return typeof value === "string" && SLUG.test(value) && !value.includes("..");
48
+ }
49
+ /**
50
+ * The wheel node id of a held packet. A distributed packet is one node shared
51
+ * by every episode; an episode's own packet is keyed by the episode folder.
52
+ */
53
+ export function foundationNodeId(slug, episodeFolder) {
54
+ return episodeFolder ? `${FOUNDATION_NODE_PREFIX}${episodeFolder}/${slug}` : `${FOUNDATION_NODE_PREFIX}${slug}`;
55
+ }
56
+ /** The slug a `miadi-foundation:` reference names, or null. `//` is accepted on input. */
57
+ export function foundationSlugOf(reference) {
58
+ if (typeof reference !== "string")
59
+ return null;
60
+ const m = /^miadi-foundation:(?:\/\/)?([^/?#\s]+)/i.exec(reference.trim());
61
+ return m && isFoundationSlug(m[1]) ? m[1] : null;
62
+ }
63
+ /** The entry's keys in the order the manifest writes them. */
64
+ export const FOUNDATION_ENTRY_KEYS = ["slug", "source", "version", "title", "path", "relation", "added"];
65
+ function text(value) {
66
+ if (typeof value === "number" && Number.isFinite(value))
67
+ return String(value);
68
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
69
+ }
70
+ /** An episode's own packet lives under `foundations/<slug>`, and nowhere else. */
71
+ export function episodeFoundationPath(slug) {
72
+ return `${EPISODE_FOUNDATIONS_DIR}/${slug}`;
73
+ }
74
+ /** Tolerant reader for one `foundations:` item. Null when it names no packet. */
75
+ export function toEpisodeFoundationEntry(raw) {
76
+ if (typeof raw === "string") {
77
+ const slug = foundationSlugOf(raw) ?? (isFoundationSlug(raw.trim()) ? raw.trim() : null);
78
+ return slug ? { slug, source: "package" } : null;
79
+ }
80
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw))
81
+ return null;
82
+ const r = raw;
83
+ const slug = text(r.slug);
84
+ if (!isFoundationSlug(slug))
85
+ return null;
86
+ const source = r.source === "episode" ? "episode" : "package";
87
+ const entry = { slug, source };
88
+ const version = text(r.version);
89
+ if (version && source === "package")
90
+ entry.version = version;
91
+ const title = text(r.title);
92
+ if (title)
93
+ entry.title = title;
94
+ // The path is declared by the source, never taken from the file: an
95
+ // episode's packet is `foundations/<slug>`, whatever a hand edit wrote.
96
+ if (source === "episode")
97
+ entry.path = episodeFoundationPath(slug);
98
+ const relation = text(r.relation);
99
+ if (relation)
100
+ entry.relation = relation;
101
+ const added = r.added instanceof Date ? r.added.toISOString() : text(r.added);
102
+ if (added)
103
+ entry.added = added;
104
+ return entry;
105
+ }
106
+ const keyOf = (entry) => `${entry.source}:${entry.slug}`;
107
+ /**
108
+ * Every foundation a parsed `episode.yaml` holds: the structured
109
+ * `foundations:` list first, then `miadi-foundation:` citations in
110
+ * `references:` that the list does not already name. One entry per packet.
111
+ */
112
+ export function readEpisodeFoundations(manifest) {
113
+ if (typeof manifest !== "object" || manifest === null)
114
+ return [];
115
+ const m = manifest;
116
+ const out = [];
117
+ const seen = new Set();
118
+ for (const item of Array.isArray(m.foundations) ? m.foundations : []) {
119
+ const entry = toEpisodeFoundationEntry(item);
120
+ if (!entry || seen.has(keyOf(entry)))
121
+ continue;
122
+ seen.add(keyOf(entry));
123
+ out.push({ ...entry, declared: "foundations" });
124
+ }
125
+ for (const reference of Array.isArray(m.references) ? m.references : []) {
126
+ const slug = foundationSlugOf(reference);
127
+ if (!slug)
128
+ continue;
129
+ const entry = { slug, source: "package" };
130
+ if (seen.has(keyOf(entry)))
131
+ continue;
132
+ seen.add(keyOf(entry));
133
+ out.push({ ...entry, declared: "references" });
134
+ }
135
+ return out;
136
+ }
137
+ //# sourceMappingURL=episode-foundation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"episode-foundation.js","sourceRoot":"","sources":["../src/episode-foundation.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -32,4 +32,16 @@ export type { AttentionItem, AttentionStore, ParsedAttentionStore, } from "./att
32
32
  */
33
33
  export { REVIEW_SERVICE_BASE_URL, REVIEW_REFERENCE_PREFIX, REVIEW_NODE_PREFIX, REVIEW_NODE_KIND, REVIEW_ENTRY_KEYS, isReviewId, reviewNodeId, reviewReference, reviewPageUrl, reviewJsonUrl, parseReviewRef, toEpisodeReviewEntry, readEpisodeReviews, } from "./episode-review.js";
34
34
  export type { ReviewRef, EpisodeReviewEntry, ObservedEpisodeReview } from "./episode-review.js";
35
+ /**
36
+ * A foundation packet held by an episode — the `foundations:` list in
37
+ * `episode.yaml`, and the wheel node kind it projects to (jgwill/Miadi#713).
38
+ */
39
+ export { FOUNDATION_REFERENCE_PREFIX, FOUNDATION_NODE_PREFIX, FOUNDATION_NODE_KIND, FOUNDATION_ENTRY_KEYS, EPISODE_FOUNDATIONS_DIR, DEFAULT_FOUNDATION_RELATION, isFoundationSlug, foundationNodeId, foundationSlugOf, episodeFoundationPath, toEpisodeFoundationEntry, readEpisodeFoundations, } from "./episode-foundation.js";
40
+ export type { FoundationSource, EpisodeFoundationEntry, ObservedEpisodeFoundation } from "./episode-foundation.js";
41
+ /**
42
+ * The screenwalk record: a recording of a person working live with agent sessions, held in an
43
+ * episode as `captures/screenwalk-<id>/screenwalk.json` (Episode 550, jgwill/Miadi#707).
44
+ */
45
+ export { SCREENWALK_REFERENCE_PREFIX, SCREENWALK_FOLDER_PREFIX, SCREENWALK_FILE, SCREENWALK_STATES, SCREENWALK_OUTPUT_KINDS, SCREENWALK_RECORD_KEYS, LEGACY_SCREENWALK_KEYS, isScreenwalkState, isScreenwalkId, screenwalkReference, screenwalkFolder, screenwalkPath, parseScreenwalkRef, parseScreenwalkStamp, deriveScreenwalkState, toScreenwalkRecord, isScreenwalkRecord, } from "./screenwalk.js";
46
+ export type { ScreenwalkState, ScreenwalkRef, ScreenwalkStamp, ScreenwalkRecording, ScreenwalkVideo, ScreenwalkReview, ScreenwalkSession, ScreenwalkClosing, ScreenwalkTranscription, ScreenwalkOutputKind, ScreenwalkOutput, ScreenwalkRecord, } from "./screenwalk.js";
35
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,+BAA+B,CAAA;AAE7C;;;;GAIG;AACH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,YAAY,GACb,MAAM,sBAAsB,CAAA;AAE7B;;;GAGG;AACH,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAEjE;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AAEvB;;;GAGG;AACH,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,+BAA+B,CAAA;AAE7C;;;;GAIG;AACH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,YAAY,GACb,MAAM,sBAAsB,CAAA;AAE7B;;;GAGG;AACH,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAEjE;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AAEvB;;;GAGG;AACH,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAE/F;;;GAGG;AACH,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AAElH;;;GAGG;AACH,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,eAAe,EACf,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,iBAAiB,CAAA"}
package/dist/index.js CHANGED
@@ -29,4 +29,14 @@ export { ATTENTION_FILE, ATTENTION_SCHEMA_VERSION, toAttentionItem, parseAttenti
29
29
  * shape Episode 345 set (jgwill/Miadi#630).
30
30
  */
31
31
  export { REVIEW_SERVICE_BASE_URL, REVIEW_REFERENCE_PREFIX, REVIEW_NODE_PREFIX, REVIEW_NODE_KIND, REVIEW_ENTRY_KEYS, isReviewId, reviewNodeId, reviewReference, reviewPageUrl, reviewJsonUrl, parseReviewRef, toEpisodeReviewEntry, readEpisodeReviews, } from "./episode-review.js";
32
+ /**
33
+ * A foundation packet held by an episode — the `foundations:` list in
34
+ * `episode.yaml`, and the wheel node kind it projects to (jgwill/Miadi#713).
35
+ */
36
+ export { FOUNDATION_REFERENCE_PREFIX, FOUNDATION_NODE_PREFIX, FOUNDATION_NODE_KIND, FOUNDATION_ENTRY_KEYS, EPISODE_FOUNDATIONS_DIR, DEFAULT_FOUNDATION_RELATION, isFoundationSlug, foundationNodeId, foundationSlugOf, episodeFoundationPath, toEpisodeFoundationEntry, readEpisodeFoundations, } from "./episode-foundation.js";
37
+ /**
38
+ * The screenwalk record: a recording of a person working live with agent sessions, held in an
39
+ * episode as `captures/screenwalk-<id>/screenwalk.json` (Episode 550, jgwill/Miadi#707).
40
+ */
41
+ export { SCREENWALK_REFERENCE_PREFIX, SCREENWALK_FOLDER_PREFIX, SCREENWALK_FILE, SCREENWALK_STATES, SCREENWALK_OUTPUT_KINDS, SCREENWALK_RECORD_KEYS, LEGACY_SCREENWALK_KEYS, isScreenwalkState, isScreenwalkId, screenwalkReference, screenwalkFolder, screenwalkPath, parseScreenwalkRef, parseScreenwalkStamp, deriveScreenwalkState, toScreenwalkRecord, isScreenwalkRecord, } from "./screenwalk.js";
32
42
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,+BAA+B,CAAA;AAE7C;;;;GAIG;AACH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,YAAY,GACb,MAAM,sBAAsB,CAAA;AAE7B;;;GAGG;AACH,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAG7B;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AAOvB;;;GAGG;AACH,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,+BAA+B,CAAA;AAE7C;;;;GAIG;AACH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,YAAY,GACb,MAAM,sBAAsB,CAAA;AAE7B;;;GAGG;AACH,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAG7B;;;GAGG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AAOvB;;;GAGG;AACH,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAG5B;;;GAGG;AACH,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,yBAAyB,CAAA;AAGhC;;;GAGG;AACH,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * The chronicle SCREENWALK record — a recording of a person working live with agent
3
+ * sessions, with their voices, held by an episode.
4
+ *
5
+ * Episode 550 ("The Screenwalk as a Media Type") drew the type before any code held it, in
6
+ * `diagrams/screenwalk.erdf.json`: an Episode holds Screenwalks; a Screenwalk witnesses
7
+ * sessions, ends with witness closings, is read as one Review and is teased by Shorts. Its
8
+ * states are the episode's two machines, `screenwalk.smdf.json` (NotStarted to
9
+ * InConversation) and the media cycle that continues after Reviewed.
10
+ *
11
+ * File: `captures/screenwalk-<id>/screenwalk.json` in the episode vessel, beside the seat
12
+ * ledgers. `capture.json` stays the descriptor of a phone audio take (`@miadi/episode-capture`),
13
+ * whose reader skips every other shape. The screenwalk `capture.json` files written by hand
14
+ * before this record existed are read by `toScreenwalkRecord` and converted.
15
+ *
16
+ * The id is the stamp the person writes when they press record, `yymmddHHMM`
17
+ * (`miadi-screenwalk:2610061207`). The first records used `yymmdd-NNN`. The stamp is the
18
+ * minute the person named. `recording.started` is where the uploaded video's clock begins,
19
+ * which can differ from it (a retake).
20
+ *
21
+ * Shape (`screenwalk.json`):
22
+ *
23
+ * { "screenwalk": "2610061207", "reference": "miadi-screenwalk:2610061207",
24
+ * "state": "Reviewed", "episode": "2026-10-01-episode-550-…", "stamp": "2026-10-06T12:07",
25
+ * "recording": { "started": "…", "length": "about 24:30", "evidence": "…", "retake": "…" },
26
+ * "video": { "url": "https://youtu.be/…", "title": "…" },
27
+ * "review": { "id": "6a2b5b59-…", "version": 1 },
28
+ * "related": [], "sessions": [{ "session_id": "…", "name": "…", "ledger": "seat-….md" }],
29
+ * "closings": [], "transcriptions": [{ "file": "…", "source": "…", "coverage": "…" }],
30
+ * "outputs": [], "finding": "…" }
31
+ *
32
+ * Pure — no fs, no fetch. Reading and writing the file is the consumer's. Ref: jgwill/Miadi#707.
33
+ */
34
+ /** The portable reference form: `miadi-screenwalk:<id>`. `miadi-screenwalk://<id>` is read too. */
35
+ export declare const SCREENWALK_REFERENCE_PREFIX = "miadi-screenwalk:";
36
+ /** The folder a screenwalk lives in, under the vessel's `captures/`: `screenwalk-<id>`. */
37
+ export declare const SCREENWALK_FOLDER_PREFIX = "screenwalk-";
38
+ /** The record's file inside its folder. */
39
+ export declare const SCREENWALK_FILE = "screenwalk.json";
40
+ /**
41
+ * Every state a screenwalk can be in: Episode 550's `screenwalk.smdf.json`, then the media
42
+ * cycle that continues it after Reviewed (`screenwalk-media-cycle.smdf.json`).
43
+ */
44
+ export declare const SCREENWALK_STATES: readonly ["NotStarted", "Recording", "Witnessing", "ClosingDrafted", "Played", "Revising", "Recorded", "Published", "Reviewed", "Chronicled", "InConversation", "Enriched", "Notebooked", "MediaGenerated", "Watched", "HeldInCircle", "ScriptedNext"];
45
+ export type ScreenwalkState = (typeof SCREENWALK_STATES)[number];
46
+ export declare function isScreenwalkState(value: unknown): value is ScreenwalkState;
47
+ export declare function isScreenwalkId(value: unknown): value is string;
48
+ export declare function screenwalkReference(id: string): string;
49
+ export declare function screenwalkFolder(id: string): string;
50
+ /** The record's path inside an episode vessel, relative to the vessel. */
51
+ export declare function screenwalkPath(id: string): string;
52
+ export interface ScreenwalkRef {
53
+ id: string;
54
+ /** `miadi-screenwalk:<id>`. */
55
+ reference: string;
56
+ /** `screenwalk-<id>`, the folder under `captures/`. */
57
+ folder: string;
58
+ }
59
+ /**
60
+ * Read a screenwalk reference: `miadi-screenwalk:<id>`, `miadi-screenwalk://<id>`, a folder
61
+ * name `screenwalk-<id>`, or a bare id. Null for anything else.
62
+ */
63
+ export declare function parseScreenwalkRef(input: unknown): ScreenwalkRef | null;
64
+ export interface ScreenwalkStamp {
65
+ /** `YYYY-MM-DD`. */
66
+ date: string;
67
+ /** `HH:MM`, present when the id carries an hour. An id with an hour and no minute gives `HH:00`. */
68
+ time?: string;
69
+ precision: "day" | "hour" | "minute";
70
+ }
71
+ /**
72
+ * The date and time an id names, read from its leading digits (`yymmdd`, `yymmddHH`,
73
+ * `yymmddHHMM`). Local time, as the person wrote it. Null when the digits are not a date.
74
+ */
75
+ export declare function parseScreenwalkStamp(id: string): ScreenwalkStamp | null;
76
+ export interface ScreenwalkRecording {
77
+ /** Where the uploaded video's clock begins, ISO or as the evidence states it. */
78
+ started?: string;
79
+ /** The video's length as measured, e.g. `about 24:30`. */
80
+ length?: string;
81
+ /** How `started` was established. */
82
+ evidence?: string;
83
+ /** Why the video differs from the recording the stamp named, when it does. */
84
+ retake?: string;
85
+ }
86
+ export interface ScreenwalkVideo {
87
+ url: string;
88
+ title?: string;
89
+ published_at?: string;
90
+ }
91
+ export interface ScreenwalkReview {
92
+ /** The review UUID. */
93
+ id: string;
94
+ /** The version this record last checked. */
95
+ version?: number;
96
+ }
97
+ /** A session on screen (the ERD's WitnessedSession). */
98
+ export interface ScreenwalkSession {
99
+ session_id?: string;
100
+ /** The session's name, often its tmux name. */
101
+ name?: string;
102
+ /** What the session was doing in the recording. */
103
+ note?: string;
104
+ /** The seat ledger file in this folder: what the seat did, in wall-clock time. */
105
+ ledger?: string;
106
+ }
107
+ /** A witness closing played in the recording (the ERD's WitnessClosing). */
108
+ export interface ScreenwalkClosing {
109
+ version: number;
110
+ file?: string;
111
+ /** The person's words after hearing this version. */
112
+ correction?: string;
113
+ }
114
+ export interface ScreenwalkTranscription {
115
+ file: string;
116
+ source?: string;
117
+ coverage?: string;
118
+ complete?: boolean;
119
+ }
120
+ export declare const SCREENWALK_OUTPUT_KINDS: readonly ["dialogue", "chapters", "short", "audio", "other"];
121
+ export type ScreenwalkOutputKind = (typeof SCREENWALK_OUTPUT_KINDS)[number];
122
+ /** Something made from the screenwalk: a dialogue, chapters, a short (the ERD's Short), audio. */
123
+ export interface ScreenwalkOutput {
124
+ kind: ScreenwalkOutputKind;
125
+ /** Where it lives: a file in this folder, a URL, or a `miadi-*` reference. */
126
+ ref?: string;
127
+ /** For a short: where it starts and ends in the video, `mm:ss` or `h:mm:ss`. */
128
+ starts_at?: string;
129
+ ends_at?: string;
130
+ note?: string;
131
+ }
132
+ export interface ScreenwalkRecord {
133
+ /** The id: the stamp, `yymmddHHMM`, or an early `yymmdd-NNN`. */
134
+ screenwalk: string;
135
+ /** `miadi-screenwalk:<id>`. */
136
+ reference: string;
137
+ state?: ScreenwalkState;
138
+ /** The episode directory that holds it. */
139
+ episode?: string;
140
+ /** The minute the person named, `YYYY-MM-DDTHH:MM` local, read from the id when absent. */
141
+ stamp?: string;
142
+ recording?: ScreenwalkRecording;
143
+ video?: ScreenwalkVideo;
144
+ review?: ScreenwalkReview;
145
+ /** References to what the screenwalk is about: reviews, episodes, issues. */
146
+ related?: string[];
147
+ sessions: ScreenwalkSession[];
148
+ closings: ScreenwalkClosing[];
149
+ transcriptions: ScreenwalkTranscription[];
150
+ outputs: ScreenwalkOutput[];
151
+ /** What a listener found that the review would not say, e.g. that the person's voice is missing. */
152
+ finding?: string;
153
+ /** An `@miadi/episode-capture` stem, when the phone also filed an audio take. */
154
+ audio_take?: string;
155
+ }
156
+ /** The record's keys in the order `screenwalk.json` writes them. */
157
+ export declare const SCREENWALK_RECORD_KEYS: readonly ["screenwalk", "reference", "state", "episode", "stamp", "recording", "video", "review", "related", "sessions", "closings", "transcriptions", "outputs", "finding", "audio_take"];
158
+ /**
159
+ * Keys of the hand-written screenwalk `capture.json` files that `toScreenwalkRecord` maps.
160
+ * A converter that meets any other key should stop rather than drop it.
161
+ */
162
+ export declare const LEGACY_SCREENWALK_KEYS: readonly ["stem", "video", "title", "review", "reference", "started", "session", "sessions", "seat_ledgers", "related", "recording", "stamp_estimate", "transcriptions", "finding", "note"];
163
+ /** The furthest state the record's own fields prove: a review, then a video. Undefined otherwise. */
164
+ export declare function deriveScreenwalkState(record: Pick<ScreenwalkRecord, "review" | "video">): ScreenwalkState | undefined;
165
+ /**
166
+ * Tolerant reader for a `screenwalk.json`, or for a screenwalk `capture.json` written by hand
167
+ * before this record existed (`stem`, `video` as a string, `review` as `miadi-review:<uuid>`,
168
+ * `session`/`sessions` strings, `seat_ledgers`, `stamp_estimate`). The id comes from
169
+ * `screenwalk`, then `stem`, then `options.id` (the folder name), then `reference`. Null when
170
+ * none names a screenwalk.
171
+ */
172
+ export declare function toScreenwalkRecord(raw: unknown, options?: {
173
+ id?: string;
174
+ episode?: string;
175
+ }): ScreenwalkRecord | null;
176
+ /** Strict guard for a record as `screenwalk.json` writes it. */
177
+ export declare function isScreenwalkRecord(value: unknown): value is ScreenwalkRecord;
178
+ //# sourceMappingURL=screenwalk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenwalk.d.ts","sourceRoot":"","sources":["../src/screenwalk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,411 @@
1
+ /**
2
+ * The chronicle SCREENWALK record — a recording of a person working live with agent
3
+ * sessions, with their voices, held by an episode.
4
+ *
5
+ * Episode 550 ("The Screenwalk as a Media Type") drew the type before any code held it, in
6
+ * `diagrams/screenwalk.erdf.json`: an Episode holds Screenwalks; a Screenwalk witnesses
7
+ * sessions, ends with witness closings, is read as one Review and is teased by Shorts. Its
8
+ * states are the episode's two machines, `screenwalk.smdf.json` (NotStarted to
9
+ * InConversation) and the media cycle that continues after Reviewed.
10
+ *
11
+ * File: `captures/screenwalk-<id>/screenwalk.json` in the episode vessel, beside the seat
12
+ * ledgers. `capture.json` stays the descriptor of a phone audio take (`@miadi/episode-capture`),
13
+ * whose reader skips every other shape. The screenwalk `capture.json` files written by hand
14
+ * before this record existed are read by `toScreenwalkRecord` and converted.
15
+ *
16
+ * The id is the stamp the person writes when they press record, `yymmddHHMM`
17
+ * (`miadi-screenwalk:2610061207`). The first records used `yymmdd-NNN`. The stamp is the
18
+ * minute the person named. `recording.started` is where the uploaded video's clock begins,
19
+ * which can differ from it (a retake).
20
+ *
21
+ * Shape (`screenwalk.json`):
22
+ *
23
+ * { "screenwalk": "2610061207", "reference": "miadi-screenwalk:2610061207",
24
+ * "state": "Reviewed", "episode": "2026-10-01-episode-550-…", "stamp": "2026-10-06T12:07",
25
+ * "recording": { "started": "…", "length": "about 24:30", "evidence": "…", "retake": "…" },
26
+ * "video": { "url": "https://youtu.be/…", "title": "…" },
27
+ * "review": { "id": "6a2b5b59-…", "version": 1 },
28
+ * "related": [], "sessions": [{ "session_id": "…", "name": "…", "ledger": "seat-….md" }],
29
+ * "closings": [], "transcriptions": [{ "file": "…", "source": "…", "coverage": "…" }],
30
+ * "outputs": [], "finding": "…" }
31
+ *
32
+ * Pure — no fs, no fetch. Reading and writing the file is the consumer's. Ref: jgwill/Miadi#707.
33
+ */
34
+ import { isReviewId, parseReviewRef } from "./episode-review.js";
35
+ /** The portable reference form: `miadi-screenwalk:<id>`. `miadi-screenwalk://<id>` is read too. */
36
+ export const SCREENWALK_REFERENCE_PREFIX = "miadi-screenwalk:";
37
+ /** The folder a screenwalk lives in, under the vessel's `captures/`: `screenwalk-<id>`. */
38
+ export const SCREENWALK_FOLDER_PREFIX = "screenwalk-";
39
+ /** The record's file inside its folder. */
40
+ export const SCREENWALK_FILE = "screenwalk.json";
41
+ /**
42
+ * Every state a screenwalk can be in: Episode 550's `screenwalk.smdf.json`, then the media
43
+ * cycle that continues it after Reviewed (`screenwalk-media-cycle.smdf.json`).
44
+ */
45
+ export const SCREENWALK_STATES = [
46
+ "NotStarted",
47
+ "Recording",
48
+ "Witnessing",
49
+ "ClosingDrafted",
50
+ "Played",
51
+ "Revising",
52
+ "Recorded",
53
+ "Published",
54
+ "Reviewed",
55
+ "Chronicled",
56
+ "InConversation",
57
+ "Enriched",
58
+ "Notebooked",
59
+ "MediaGenerated",
60
+ "Watched",
61
+ "HeldInCircle",
62
+ "ScriptedNext",
63
+ ];
64
+ export function isScreenwalkState(value) {
65
+ return typeof value === "string" && SCREENWALK_STATES.includes(value);
66
+ }
67
+ /** A date and time stamp of six to ten digits, then optional `-word` parts: `2610061207`, `261005-001`. */
68
+ const SCREENWALK_ID = /^[0-9]{6,10}(?:-[0-9a-z]+)*$/;
69
+ export function isScreenwalkId(value) {
70
+ return typeof value === "string" && SCREENWALK_ID.test(value);
71
+ }
72
+ export function screenwalkReference(id) {
73
+ return `${SCREENWALK_REFERENCE_PREFIX}${id}`;
74
+ }
75
+ export function screenwalkFolder(id) {
76
+ return `${SCREENWALK_FOLDER_PREFIX}${id}`;
77
+ }
78
+ /** The record's path inside an episode vessel, relative to the vessel. */
79
+ export function screenwalkPath(id) {
80
+ return `captures/${screenwalkFolder(id)}/${SCREENWALK_FILE}`;
81
+ }
82
+ /**
83
+ * Read a screenwalk reference: `miadi-screenwalk:<id>`, `miadi-screenwalk://<id>`, a folder
84
+ * name `screenwalk-<id>`, or a bare id. Null for anything else.
85
+ */
86
+ export function parseScreenwalkRef(input) {
87
+ if (typeof input !== "string")
88
+ return null;
89
+ let raw = input.trim().toLowerCase();
90
+ if (raw.startsWith(SCREENWALK_REFERENCE_PREFIX))
91
+ raw = raw.slice(SCREENWALK_REFERENCE_PREFIX.length).replace(/^\/\//, "");
92
+ else if (raw.startsWith(SCREENWALK_FOLDER_PREFIX))
93
+ raw = raw.slice(SCREENWALK_FOLDER_PREFIX.length);
94
+ if (!isScreenwalkId(raw))
95
+ return null;
96
+ return { id: raw, reference: screenwalkReference(raw), folder: screenwalkFolder(raw) };
97
+ }
98
+ /**
99
+ * The date and time an id names, read from its leading digits (`yymmdd`, `yymmddHH`,
100
+ * `yymmddHHMM`). Local time, as the person wrote it. Null when the digits are not a date.
101
+ */
102
+ export function parseScreenwalkStamp(id) {
103
+ const digits = /^([0-9]{6,10})/.exec(id)?.[1];
104
+ if (!digits || (digits.length !== 6 && digits.length !== 8 && digits.length !== 10))
105
+ return null;
106
+ const [yy, mm, dd, hh, mi] = [0, 2, 4, 6, 8].map((i) => digits.slice(i, i + 2));
107
+ const month = Number(mm);
108
+ const day = Number(dd);
109
+ if (month < 1 || month > 12 || day < 1 || day > 31)
110
+ return null;
111
+ const date = `20${yy}-${mm}-${dd}`;
112
+ if (!hh)
113
+ return { date, precision: "day" };
114
+ if (Number(hh) > 23 || (mi && Number(mi) > 59))
115
+ return null;
116
+ return { date, time: `${hh}:${mi || "00"}`, precision: mi ? "minute" : "hour" };
117
+ }
118
+ export const SCREENWALK_OUTPUT_KINDS = ["dialogue", "chapters", "short", "audio", "other"];
119
+ /** The record's keys in the order `screenwalk.json` writes them. */
120
+ export const SCREENWALK_RECORD_KEYS = [
121
+ "screenwalk",
122
+ "reference",
123
+ "state",
124
+ "episode",
125
+ "stamp",
126
+ "recording",
127
+ "video",
128
+ "review",
129
+ "related",
130
+ "sessions",
131
+ "closings",
132
+ "transcriptions",
133
+ "outputs",
134
+ "finding",
135
+ "audio_take",
136
+ ];
137
+ /**
138
+ * Keys of the hand-written screenwalk `capture.json` files that `toScreenwalkRecord` maps.
139
+ * A converter that meets any other key should stop rather than drop it.
140
+ */
141
+ export const LEGACY_SCREENWALK_KEYS = [
142
+ "stem",
143
+ "video",
144
+ "title",
145
+ "review",
146
+ "reference",
147
+ "started",
148
+ "session",
149
+ "sessions",
150
+ "seat_ledgers",
151
+ "related",
152
+ "recording",
153
+ "stamp_estimate",
154
+ "transcriptions",
155
+ "finding",
156
+ "note",
157
+ ];
158
+ function text(value) {
159
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
160
+ }
161
+ function obj(value) {
162
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
163
+ }
164
+ function list(value) {
165
+ return Array.isArray(value) ? value : [];
166
+ }
167
+ const SESSION_ID = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b\s*(?:\((.*)\))?\s*$/is;
168
+ /** A session written as an object, or as the early string `"<uuid> (note)"`. */
169
+ function toSession(raw) {
170
+ if (typeof raw === "string") {
171
+ const match = SESSION_ID.exec(raw.trim());
172
+ if (match)
173
+ return { session_id: match[1].toLowerCase(), ...(text(match[2]) ? { note: text(match[2]) } : {}) };
174
+ return text(raw) ? { note: text(raw) } : null;
175
+ }
176
+ const r = obj(raw);
177
+ if (!r)
178
+ return null;
179
+ const session = {};
180
+ const id = text(r.session_id) ?? text(r.session);
181
+ if (id)
182
+ session.session_id = id;
183
+ const name = text(r.name) ?? text(r.seat);
184
+ if (name)
185
+ session.name = name;
186
+ const note = text(r.note);
187
+ if (note)
188
+ session.note = note;
189
+ const ledger = text(r.ledger) ?? text(r.file);
190
+ if (ledger)
191
+ session.ledger = ledger;
192
+ return Object.keys(session).length ? session : null;
193
+ }
194
+ /** Attach each early `seat_ledgers` entry to its session: by session id, then by a note opening with the seat's name. */
195
+ function attachLedgers(sessions, ledgers) {
196
+ for (const raw of ledgers) {
197
+ const ledger = toSession(raw);
198
+ if (!ledger?.ledger)
199
+ continue;
200
+ const seat = ledger.name;
201
+ const match = sessions.find((s) => (ledger.session_id && s.session_id === ledger.session_id) ||
202
+ (seat && !s.name && s.note !== undefined && new RegExp(`^${seat.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:[;,)]|$)`).test(s.note)));
203
+ if (match) {
204
+ if (seat && !match.name) {
205
+ match.name = seat;
206
+ if (match.note) {
207
+ const rest = match.note.slice(seat.length).replace(/^[;,]\s*/, "").trim();
208
+ if (rest)
209
+ match.note = rest;
210
+ else
211
+ delete match.note;
212
+ }
213
+ }
214
+ match.ledger = ledger.ledger;
215
+ if (ledger.session_id && !match.session_id)
216
+ match.session_id = ledger.session_id;
217
+ }
218
+ else {
219
+ sessions.push(ledger);
220
+ }
221
+ }
222
+ return sessions;
223
+ }
224
+ function toTranscription(raw) {
225
+ const r = obj(raw);
226
+ const file = text(r?.file);
227
+ if (!r || !file)
228
+ return null;
229
+ const out = { file };
230
+ const source = text(r.source);
231
+ if (source)
232
+ out.source = source;
233
+ const coverage = text(r.coverage);
234
+ if (coverage)
235
+ out.coverage = coverage;
236
+ if (typeof r.complete === "boolean")
237
+ out.complete = r.complete;
238
+ return out;
239
+ }
240
+ function toClosing(raw) {
241
+ const r = obj(raw);
242
+ if (!r || typeof r.version !== "number" || !Number.isSafeInteger(r.version) || r.version < 1)
243
+ return null;
244
+ const out = { version: r.version };
245
+ const file = text(r.file);
246
+ if (file)
247
+ out.file = file;
248
+ const correction = text(r.correction);
249
+ if (correction)
250
+ out.correction = correction;
251
+ return out;
252
+ }
253
+ function toOutput(raw) {
254
+ const r = obj(raw);
255
+ if (!r)
256
+ return null;
257
+ const kind = SCREENWALK_OUTPUT_KINDS.includes(r.kind) ? r.kind : undefined;
258
+ if (!kind)
259
+ return null;
260
+ const out = { kind };
261
+ for (const key of ["ref", "starts_at", "ends_at", "note"]) {
262
+ const value = text(r[key]);
263
+ if (value)
264
+ out[key] = value;
265
+ }
266
+ return out;
267
+ }
268
+ function toReview(raw) {
269
+ const r = obj(raw);
270
+ const ref = parseReviewRef(r ? (text(r.id) ?? text(r.url)) : raw);
271
+ if (!ref)
272
+ return undefined;
273
+ const version = r && typeof r.version === "number" && Number.isSafeInteger(r.version) && r.version > 0 ? r.version : ref.version;
274
+ return { id: ref.id, ...(version !== undefined ? { version } : {}) };
275
+ }
276
+ function toVideo(raw, title) {
277
+ const r = obj(raw);
278
+ const url = r ? text(r.url) : text(raw);
279
+ if (!url)
280
+ return undefined;
281
+ const video = { url };
282
+ const t = (r && text(r.title)) ?? text(title);
283
+ if (t)
284
+ video.title = t;
285
+ const published = r && text(r.published_at);
286
+ if (published)
287
+ video.published_at = published;
288
+ return video;
289
+ }
290
+ function toRecording(raw, estimate) {
291
+ const r = obj(raw);
292
+ const e = obj(estimate);
293
+ const recording = {};
294
+ const fromEstimate = e ? parseScreenwalkStamp(text(e.stamp) ?? "") : null;
295
+ const started = (r && (text(r.started) ?? text(r.started_estimate))) ?? (fromEstimate?.time ? `${fromEstimate.date}T${fromEstimate.time}` : undefined);
296
+ if (started)
297
+ recording.started = started;
298
+ const length = r && text(r.length);
299
+ if (length)
300
+ recording.length = length;
301
+ const evidence = (r && text(r.evidence)) ?? (e && text(e.evidence));
302
+ if (evidence)
303
+ recording.evidence = evidence;
304
+ const retake = r && text(r.retake);
305
+ if (retake)
306
+ recording.retake = retake;
307
+ return Object.keys(recording).length ? recording : undefined;
308
+ }
309
+ /** The furthest state the record's own fields prove: a review, then a video. Undefined otherwise. */
310
+ export function deriveScreenwalkState(record) {
311
+ if (record.review)
312
+ return "Reviewed";
313
+ if (record.video)
314
+ return "Published";
315
+ return undefined;
316
+ }
317
+ /**
318
+ * Tolerant reader for a `screenwalk.json`, or for a screenwalk `capture.json` written by hand
319
+ * before this record existed (`stem`, `video` as a string, `review` as `miadi-review:<uuid>`,
320
+ * `session`/`sessions` strings, `seat_ledgers`, `stamp_estimate`). The id comes from
321
+ * `screenwalk`, then `stem`, then `options.id` (the folder name), then `reference`. Null when
322
+ * none names a screenwalk.
323
+ */
324
+ export function toScreenwalkRecord(raw, options = {}) {
325
+ const r = obj(raw);
326
+ if (!r)
327
+ return null;
328
+ const ref = parseScreenwalkRef(r.screenwalk) ?? parseScreenwalkRef(r.stem) ?? parseScreenwalkRef(options.id) ?? parseScreenwalkRef(r.reference);
329
+ if (!ref)
330
+ return null;
331
+ const record = {
332
+ screenwalk: ref.id,
333
+ reference: ref.reference,
334
+ sessions: [],
335
+ closings: [],
336
+ transcriptions: [],
337
+ outputs: [],
338
+ };
339
+ const episode = text(r.episode) ?? options.episode;
340
+ const stamp = text(r.stamp) ?? text(r.started);
341
+ const named = parseScreenwalkStamp(ref.id);
342
+ const recording = toRecording(r.recording, r.stamp_estimate);
343
+ const video = toVideo(r.video, r.title);
344
+ const review = toReview(r.review);
345
+ const related = list(r.related).map(text).filter((v) => v !== undefined);
346
+ const sessions = attachLedgers([...list(r.sessions), ...(r.session !== undefined ? [r.session] : [])].map(toSession).filter((s) => s !== null), list(r.seat_ledgers));
347
+ const finding = text(r.finding);
348
+ const audioTake = text(r.audio_take);
349
+ const state = isScreenwalkState(r.state) ? r.state : deriveScreenwalkState({ review, video });
350
+ if (state)
351
+ record.state = state;
352
+ if (episode)
353
+ record.episode = episode;
354
+ if (stamp)
355
+ record.stamp = stamp;
356
+ else if (named?.time)
357
+ record.stamp = `${named.date}T${named.time}`;
358
+ if (recording)
359
+ record.recording = recording;
360
+ if (video)
361
+ record.video = video;
362
+ if (review)
363
+ record.review = review;
364
+ if (related.length)
365
+ record.related = related;
366
+ record.sessions = sessions.map((s) => {
367
+ const ordered = {};
368
+ for (const key of ["session_id", "name", "note", "ledger"])
369
+ if (s[key] !== undefined)
370
+ ordered[key] = s[key];
371
+ return ordered;
372
+ });
373
+ record.closings = list(r.closings).map(toClosing).filter((c) => c !== null);
374
+ record.transcriptions = list(r.transcriptions).map(toTranscription).filter((t) => t !== null);
375
+ record.outputs = list(r.outputs).map(toOutput).filter((o) => o !== null);
376
+ if (finding)
377
+ record.finding = finding;
378
+ if (audioTake)
379
+ record.audio_take = audioTake;
380
+ // Rebuild in the order the file writes, so a written record diffs cleanly.
381
+ const ordered = {};
382
+ for (const key of SCREENWALK_RECORD_KEYS)
383
+ if (record[key] !== undefined)
384
+ ordered[key] = record[key];
385
+ return ordered;
386
+ }
387
+ /** Strict guard for a record as `screenwalk.json` writes it. */
388
+ export function isScreenwalkRecord(value) {
389
+ const r = obj(value);
390
+ if (!r || !isScreenwalkId(r.screenwalk) || r.reference !== screenwalkReference(r.screenwalk))
391
+ return false;
392
+ if (r.state !== undefined && !isScreenwalkState(r.state))
393
+ return false;
394
+ for (const key of ["sessions", "closings", "transcriptions", "outputs"])
395
+ if (!Array.isArray(r[key]))
396
+ return false;
397
+ const video = r.video === undefined ? null : obj(r.video);
398
+ if (r.video !== undefined && !text(video?.url))
399
+ return false;
400
+ const review = r.review === undefined ? null : obj(r.review);
401
+ if (r.review !== undefined && !isReviewId(review?.id))
402
+ return false;
403
+ if (!r.outputs.every((o) => toOutput(o) !== null))
404
+ return false;
405
+ if (!r.transcriptions.every((t) => toTranscription(t) !== null))
406
+ return false;
407
+ if (!r.closings.every((c) => toClosing(c) !== null))
408
+ return false;
409
+ return true;
410
+ }
411
+ //# sourceMappingURL=screenwalk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenwalk.js","sourceRoot":"","sources":["../src/screenwalk.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@
10
10
  * and validates what it is handed so the app and forgewright never fork the
11
11
  * read-side.
12
12
  *
13
- * OWNERSHIP (jgwill/Miadi#592, packages/CLAUDE.md): this module is the *declaration*
13
+ * OWNERSHIP (jgwill/Miadi#592, packages/AGENTS.md): this module is the *declaration*
14
14
  * of the chronicle→book edge. `@miadi/inquiry-weave` owns its *enumeration* and never
15
15
  * authors a story; `packages/passages` owns the *derivation* of a book from a vessel,
16
16
  * as a read-only projection of the chronicle; `app/chronicle` renders and serves.
@@ -10,7 +10,7 @@
10
10
  * and validates what it is handed so the app and forgewright never fork the
11
11
  * read-side.
12
12
  *
13
- * OWNERSHIP (jgwill/Miadi#592, packages/CLAUDE.md): this module is the *declaration*
13
+ * OWNERSHIP (jgwill/Miadi#592, packages/AGENTS.md): this module is the *declaration*
14
14
  * of the chronicle→book edge. `@miadi/inquiry-weave` owns its *enumeration* and never
15
15
  * authors a story; `packages/passages` owns the *derivation* of a book from a vessel,
16
16
  * as a read-only projection of the chronicle; `app/chronicle` renders and serves.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miadi/episodic-memory-schema",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "description": "TypeScript types and JSON Schema for episodic memory — the durable session-to-session memory layer in the Miadi orchestration kit. Narrative layer is NCP-aligned; provenance layer is W3C PROV-DM and OAIS-informed.",
5
5
  "keywords": [
6
6
  "miadi",
@@ -31,6 +31,7 @@
31
31
  "default": "./dist/index.js"
32
32
  },
33
33
  "./schema": "./schema/episodic-memory.schema.json",
34
+ "./schema/screenwalk": "./schema/screenwalk.schema.json",
34
35
  "./package.json": "./package.json"
35
36
  },
36
37
  "files": [
@@ -0,0 +1,105 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/jgwill/Miadi/packages/episodic-memory-schema/schema/screenwalk.schema.json",
4
+ "title": "Screenwalk record",
5
+ "description": "captures/screenwalk-<id>/screenwalk.json in a chronicle episode vessel: a recording of a person working live with agent sessions, with their voices. Types: src/screenwalk.ts.",
6
+ "type": "object",
7
+ "required": ["screenwalk", "reference", "sessions", "closings", "transcriptions", "outputs"],
8
+ "properties": {
9
+ "screenwalk": { "type": "string", "pattern": "^[0-9]{6,10}(?:-[0-9a-z]+)*$", "description": "The stamp yymmddHHMM, or an early yymmdd-NNN." },
10
+ "reference": { "type": "string", "pattern": "^miadi-screenwalk:[0-9]{6,10}(?:-[0-9a-z]+)*$" },
11
+ "state": {
12
+ "enum": ["NotStarted", "Recording", "Witnessing", "ClosingDrafted", "Played", "Revising", "Recorded", "Published", "Reviewed", "Chronicled", "InConversation", "Enriched", "Notebooked", "MediaGenerated", "Watched", "HeldInCircle", "ScriptedNext"]
13
+ },
14
+ "episode": { "type": "string", "description": "The episode directory that holds it." },
15
+ "stamp": { "type": "string", "description": "The minute the person named, YYYY-MM-DDTHH:MM local." },
16
+ "recording": {
17
+ "type": "object",
18
+ "properties": {
19
+ "started": { "type": "string" },
20
+ "length": { "type": "string" },
21
+ "evidence": { "type": "string" },
22
+ "retake": { "type": "string" }
23
+ },
24
+ "additionalProperties": false
25
+ },
26
+ "video": {
27
+ "type": "object",
28
+ "required": ["url"],
29
+ "properties": {
30
+ "url": { "type": "string", "minLength": 1 },
31
+ "title": { "type": "string" },
32
+ "published_at": { "type": "string" }
33
+ },
34
+ "additionalProperties": false
35
+ },
36
+ "review": {
37
+ "type": "object",
38
+ "required": ["id"],
39
+ "properties": {
40
+ "id": { "type": "string", "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" },
41
+ "version": { "type": "integer", "minimum": 1 }
42
+ },
43
+ "additionalProperties": false
44
+ },
45
+ "related": { "type": "array", "items": { "type": "string" } },
46
+ "sessions": {
47
+ "type": "array",
48
+ "items": {
49
+ "type": "object",
50
+ "properties": {
51
+ "session_id": { "type": "string" },
52
+ "name": { "type": "string" },
53
+ "note": { "type": "string" },
54
+ "ledger": { "type": "string" }
55
+ },
56
+ "additionalProperties": false
57
+ }
58
+ },
59
+ "closings": {
60
+ "type": "array",
61
+ "items": {
62
+ "type": "object",
63
+ "required": ["version"],
64
+ "properties": {
65
+ "version": { "type": "integer", "minimum": 1 },
66
+ "file": { "type": "string" },
67
+ "correction": { "type": "string" }
68
+ },
69
+ "additionalProperties": false
70
+ }
71
+ },
72
+ "transcriptions": {
73
+ "type": "array",
74
+ "items": {
75
+ "type": "object",
76
+ "required": ["file"],
77
+ "properties": {
78
+ "file": { "type": "string", "minLength": 1 },
79
+ "source": { "type": "string" },
80
+ "coverage": { "type": "string" },
81
+ "complete": { "type": "boolean" }
82
+ },
83
+ "additionalProperties": false
84
+ }
85
+ },
86
+ "outputs": {
87
+ "type": "array",
88
+ "items": {
89
+ "type": "object",
90
+ "required": ["kind"],
91
+ "properties": {
92
+ "kind": { "enum": ["dialogue", "chapters", "short", "audio", "other"] },
93
+ "ref": { "type": "string" },
94
+ "starts_at": { "type": "string" },
95
+ "ends_at": { "type": "string" },
96
+ "note": { "type": "string" }
97
+ },
98
+ "additionalProperties": false
99
+ }
100
+ },
101
+ "finding": { "type": "string" },
102
+ "audio_take": { "type": "string" }
103
+ },
104
+ "additionalProperties": false
105
+ }