@medicine-wheel/narrative-cluster 0.4.9
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 +75 -0
- package/dist/clusters.d.ts +30 -0
- package/dist/clusters.d.ts.map +1 -0
- package/dist/clusters.js +72 -0
- package/dist/clusters.js.map +1 -0
- package/dist/edit-brief.d.ts +36 -0
- package/dist/edit-brief.d.ts.map +1 -0
- package/dist/edit-brief.js +47 -0
- package/dist/edit-brief.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @medicine-wheel/narrative-cluster
|
|
2
|
+
|
|
3
|
+
Turn witnessed production events into cinematic clusters, narrative beats, and a Film Edit Brief.
|
|
4
|
+
|
|
5
|
+
This package receives the output of `@medicine-wheel/perception-layer` and gives it an edit-facing structure: grouped rushes, Medicine Wheel-aligned beats, EDL-style markers, and narrative annotations. It is intentionally deterministic so a real transcript can become a testable vertical slice.
|
|
6
|
+
|
|
7
|
+
## Why it exists
|
|
8
|
+
|
|
9
|
+
Episode 066 named a film-production path where agents help transform raw material into story without erasing relationship. Episode 067 sharpened the distinction between the Jerry thread of runtime observability and the Nicolas Renaud thread of Research is Ceremony. This package sits between perception and editing: it clusters witnessed events while preserving relational moments as first-class material.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @medicine-wheel/narrative-cluster
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## API
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import {
|
|
21
|
+
clusterEvents,
|
|
22
|
+
clustersToBeats,
|
|
23
|
+
generateEditBrief,
|
|
24
|
+
} from '@medicine-wheel/narrative-cluster';
|
|
25
|
+
|
|
26
|
+
const clusters = clusterEvents(
|
|
27
|
+
events.map((event) => ({
|
|
28
|
+
type: event.type,
|
|
29
|
+
text: event.text,
|
|
30
|
+
index: event.index,
|
|
31
|
+
source: event.source,
|
|
32
|
+
})),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const beats = clustersToBeats(clusters);
|
|
36
|
+
const brief = generateEditBrief(clusters, {
|
|
37
|
+
title: 'Episode 066 rushes',
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Main concepts
|
|
42
|
+
|
|
43
|
+
- `NarrativeCluster`: a group of related events with a kind, theme, direction, and source events.
|
|
44
|
+
- `NarrativeBeat`: a Medicine Wheel-aligned beat for downstream narrative engines.
|
|
45
|
+
- `EditBrief`: ordered markers plus a CMX3600-style EDL text block.
|
|
46
|
+
- `EditMarker`: deterministic timecode and annotation for an editable unit.
|
|
47
|
+
|
|
48
|
+
## Cluster kinds
|
|
49
|
+
|
|
50
|
+
- `shot-sequence` → usually East / vision
|
|
51
|
+
- `sound-environment` → usually South / growth
|
|
52
|
+
- `relational-moment` → usually West / reflection
|
|
53
|
+
|
|
54
|
+
## Verification
|
|
55
|
+
|
|
56
|
+
The real vertical slice is covered by:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd /workspace/repos/jgwill/medicine-wheel
|
|
60
|
+
npm run build:packages
|
|
61
|
+
npm test -- --run tests/film-production-vertical-slice.test.ts
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
That test uses the real Episode 066 transcript and proves:
|
|
65
|
+
|
|
66
|
+
1. perceptual events → narrative clusters,
|
|
67
|
+
2. clusters → Medicine Wheel-aligned beats,
|
|
68
|
+
3. clusters → Film Edit Brief / EDL markers,
|
|
69
|
+
4. storyteller and ceremony gates can complete the production loop.
|
|
70
|
+
|
|
71
|
+
## Related issues
|
|
72
|
+
|
|
73
|
+
- #85 — Episode 068 vertical slice
|
|
74
|
+
- #87 — narrative cluster, storyteller gate, and production ceremony gates
|
|
75
|
+
- #84 — Episode 068 plan-review audio steering context
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @medicine-wheel/narrative-cluster — Clusters
|
|
3
|
+
*
|
|
4
|
+
* The Narrative Cluster Processor as a reusable method: group witnessed events
|
|
5
|
+
* into cinematic clusters and turn them into direction-aligned NarrativeBeats.
|
|
6
|
+
* Input is the minimal `ClusterableEvent` shape, so any source (transcript,
|
|
7
|
+
* rushes, notes) flows through without a hard dependency on perception-layer.
|
|
8
|
+
*/
|
|
9
|
+
import type { NarrativeBeat, DirectionName } from '@medicine-wheel/ontology-core';
|
|
10
|
+
export type ClusterKind = 'shot-sequence' | 'sound-environment' | 'relational-moment';
|
|
11
|
+
/** The minimal input shape — decoupled from any specific producer. */
|
|
12
|
+
export interface ClusterableEvent {
|
|
13
|
+
/** Event type label (e.g. a PerceptualEventType string). */
|
|
14
|
+
type: string;
|
|
15
|
+
text: string;
|
|
16
|
+
index: number;
|
|
17
|
+
source?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface NarrativeCluster {
|
|
20
|
+
id: string;
|
|
21
|
+
kind: ClusterKind;
|
|
22
|
+
theme: string;
|
|
23
|
+
direction: DirectionName;
|
|
24
|
+
events: ClusterableEvent[];
|
|
25
|
+
}
|
|
26
|
+
/** Group events into cinematic clusters, preserving stream order within each. */
|
|
27
|
+
export declare function clusterEvents(events: ClusterableEvent[]): NarrativeCluster[];
|
|
28
|
+
/** One direction-aligned NarrativeBeat per cluster. */
|
|
29
|
+
export declare function clustersToBeats(clusters: NarrativeCluster[]): NarrativeBeat[];
|
|
30
|
+
//# sourceMappingURL=clusters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clusters.d.ts","sourceRoot":"","sources":["../src/clusters.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAElF,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEtF,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AA+BD,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAsB5E;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,aAAa,EAAE,CAiB7E"}
|
package/dist/clusters.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clusterEvents = clusterEvents;
|
|
4
|
+
exports.clustersToBeats = clustersToBeats;
|
|
5
|
+
const KIND_FOR_EVENT = {
|
|
6
|
+
'shot-composition': 'shot-sequence',
|
|
7
|
+
'ambient-sound': 'sound-environment',
|
|
8
|
+
'relational-moment': 'relational-moment',
|
|
9
|
+
'director-intent': 'relational-moment',
|
|
10
|
+
'transcript-segment': 'relational-moment',
|
|
11
|
+
};
|
|
12
|
+
const DIRECTION_FOR_KIND = {
|
|
13
|
+
'shot-sequence': 'east', // vision — what is seen
|
|
14
|
+
'sound-environment': 'south', // embodied — what is heard
|
|
15
|
+
'relational-moment': 'west', // reflection — relationship
|
|
16
|
+
};
|
|
17
|
+
const THEME_FOR_KIND = {
|
|
18
|
+
'shot-sequence': 'Visual composition — what the eye witnesses',
|
|
19
|
+
'sound-environment': 'Sound environment — what the ear witnesses',
|
|
20
|
+
'relational-moment': 'Relational moments — knowledge from relationship',
|
|
21
|
+
};
|
|
22
|
+
const CLUSTER_ORDER = ['shot-sequence', 'sound-environment', 'relational-moment'];
|
|
23
|
+
const ACT_FOR_DIRECTION = {
|
|
24
|
+
east: 1,
|
|
25
|
+
south: 2,
|
|
26
|
+
west: 3,
|
|
27
|
+
north: 4,
|
|
28
|
+
};
|
|
29
|
+
/** Group events into cinematic clusters, preserving stream order within each. */
|
|
30
|
+
function clusterEvents(events) {
|
|
31
|
+
const buckets = new Map();
|
|
32
|
+
for (const ev of events) {
|
|
33
|
+
const kind = KIND_FOR_EVENT[ev.type] ?? 'relational-moment';
|
|
34
|
+
const arr = buckets.get(kind) ?? [];
|
|
35
|
+
arr.push(ev);
|
|
36
|
+
buckets.set(kind, arr);
|
|
37
|
+
}
|
|
38
|
+
const clusters = [];
|
|
39
|
+
for (const kind of CLUSTER_ORDER) {
|
|
40
|
+
const evs = buckets.get(kind);
|
|
41
|
+
if (!evs || evs.length === 0)
|
|
42
|
+
continue;
|
|
43
|
+
clusters.push({
|
|
44
|
+
id: `cluster:${kind}:${evs[0].index}`,
|
|
45
|
+
kind,
|
|
46
|
+
theme: THEME_FOR_KIND[kind],
|
|
47
|
+
direction: DIRECTION_FOR_KIND[kind],
|
|
48
|
+
events: evs,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return clusters;
|
|
52
|
+
}
|
|
53
|
+
/** One direction-aligned NarrativeBeat per cluster. */
|
|
54
|
+
function clustersToBeats(clusters) {
|
|
55
|
+
const now = new Date().toISOString();
|
|
56
|
+
return clusters.map((c) => ({
|
|
57
|
+
id: `beat:${c.id}`,
|
|
58
|
+
direction: c.direction,
|
|
59
|
+
title: c.theme,
|
|
60
|
+
description: `${c.events.length} ${c.kind} event(s) witnessed`,
|
|
61
|
+
prose: c.events
|
|
62
|
+
.slice(0, 3)
|
|
63
|
+
.map((e) => e.text)
|
|
64
|
+
.join(' '),
|
|
65
|
+
ceremonies: [],
|
|
66
|
+
learnings: [],
|
|
67
|
+
timestamp: now,
|
|
68
|
+
act: ACT_FOR_DIRECTION[c.direction],
|
|
69
|
+
relations_honored: [],
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=clusters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clusters.js","sourceRoot":"","sources":["../src/clusters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @medicine-wheel/narrative-cluster — Edit Brief
|
|
3
|
+
*
|
|
4
|
+
* Generate a Film Edit Brief from narrative clusters: ordered EDL-style markers
|
|
5
|
+
* with synthesized timecodes and narrative annotations. Deterministic — the same
|
|
6
|
+
* clusters always yield the same brief, so the slice is testable.
|
|
7
|
+
*/
|
|
8
|
+
import type { ClusterKind, NarrativeCluster } from './clusters.js';
|
|
9
|
+
export interface EditMarker {
|
|
10
|
+
index: number;
|
|
11
|
+
clusterId: string;
|
|
12
|
+
kind: ClusterKind;
|
|
13
|
+
/** HH:MM:SS:FF timecode synthesized from marker order. */
|
|
14
|
+
timecode: string;
|
|
15
|
+
/** Narrative annotation for the editor. */
|
|
16
|
+
label: string;
|
|
17
|
+
source: string;
|
|
18
|
+
}
|
|
19
|
+
export interface EditBrief {
|
|
20
|
+
productionId: string;
|
|
21
|
+
title: string;
|
|
22
|
+
markers: EditMarker[];
|
|
23
|
+
/** CMX3600-style EDL text block. */
|
|
24
|
+
edl: string;
|
|
25
|
+
generatedAt: string;
|
|
26
|
+
}
|
|
27
|
+
export interface EditBriefOptions {
|
|
28
|
+
productionId?: string;
|
|
29
|
+
title?: string;
|
|
30
|
+
fps?: number;
|
|
31
|
+
/** Seconds allotted per marker for synthetic timecodes (default: 4). */
|
|
32
|
+
secondsPerMarker?: number;
|
|
33
|
+
}
|
|
34
|
+
/** Produce ordered markers + an EDL text block from clusters. */
|
|
35
|
+
export declare function generateEditBrief(clusters: NarrativeCluster[], opts?: EditBriefOptions): EditBrief;
|
|
36
|
+
//# sourceMappingURL=edit-brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-brief.d.ts","sourceRoot":"","sources":["../src/edit-brief.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAWD,iEAAiE;AACjE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,IAAI,GAAE,gBAAqB,GAC1B,SAAS,CAoCX"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateEditBrief = generateEditBrief;
|
|
4
|
+
function tc(totalSeconds, fps) {
|
|
5
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
6
|
+
const h = Math.floor(totalSeconds / 3600);
|
|
7
|
+
const m = Math.floor(totalSeconds / 60) % 60;
|
|
8
|
+
const s = Math.floor(totalSeconds) % 60;
|
|
9
|
+
const f = Math.floor((totalSeconds - Math.floor(totalSeconds)) * fps);
|
|
10
|
+
return `${pad(h)}:${pad(m)}:${pad(s)}:${pad(f)}`;
|
|
11
|
+
}
|
|
12
|
+
/** Produce ordered markers + an EDL text block from clusters. */
|
|
13
|
+
function generateEditBrief(clusters, opts = {}) {
|
|
14
|
+
const fps = opts.fps ?? 24;
|
|
15
|
+
const secondsPerMarker = opts.secondsPerMarker ?? 4;
|
|
16
|
+
const productionId = opts.productionId ?? `production:${Date.now()}`;
|
|
17
|
+
const title = opts.title ?? 'Agent-supported edit brief';
|
|
18
|
+
const generatedAt = new Date().toISOString();
|
|
19
|
+
const markers = [];
|
|
20
|
+
let order = 0;
|
|
21
|
+
for (const cluster of clusters) {
|
|
22
|
+
for (const ev of cluster.events) {
|
|
23
|
+
const startSec = order * secondsPerMarker;
|
|
24
|
+
order += 1;
|
|
25
|
+
markers.push({
|
|
26
|
+
index: order,
|
|
27
|
+
clusterId: cluster.id,
|
|
28
|
+
kind: cluster.kind,
|
|
29
|
+
timecode: tc(startSec, fps),
|
|
30
|
+
label: `[${cluster.kind}] ${ev.text.slice(0, 72)}`,
|
|
31
|
+
source: ev.source ?? 'belt-device',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const edlLines = [`TITLE: ${title}`, 'FCM: NON-DROP FRAME'];
|
|
36
|
+
markers.forEach((marker, i) => {
|
|
37
|
+
const startSec = i * secondsPerMarker;
|
|
38
|
+
const inTc = tc(startSec, fps);
|
|
39
|
+
const outTc = tc(startSec + secondsPerMarker, fps);
|
|
40
|
+
const num = String(marker.index).padStart(3, '0');
|
|
41
|
+
edlLines.push(`${num} AX AA/V C ${inTc} ${outTc} ${inTc} ${outTc}`);
|
|
42
|
+
edlLines.push(`* FROM CLIP NAME: ${marker.source}`);
|
|
43
|
+
edlLines.push(`* COMMENT: ${marker.label}`);
|
|
44
|
+
});
|
|
45
|
+
return { productionId, title, markers, edl: edlLines.join('\n'), generatedAt };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=edit-brief.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-brief.js","sourceRoot":"","sources":["../src/edit-brief.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @medicine-wheel/narrative-cluster
|
|
3
|
+
*
|
|
4
|
+
* The Narrative Cluster Processor: witnessed events → cinematic clusters →
|
|
5
|
+
* narrative beats → a Film Edit Brief (EDL markers with narrative annotations).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { clusterEvents, clustersToBeats, generateEditBrief } from '@medicine-wheel/narrative-cluster';
|
|
10
|
+
*
|
|
11
|
+
* const clusters = clusterEvents(events.map((e) => ({ type: e.type, text: e.text, index: e.index, source: e.source })));
|
|
12
|
+
* const beats = clustersToBeats(clusters);
|
|
13
|
+
* const brief = generateEditBrief(clusters, { title: 'Episode 066 rushes' });
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
export type { ClusterKind, ClusterableEvent, NarrativeCluster } from './clusters.js';
|
|
19
|
+
export { clusterEvents, clustersToBeats } from './clusters.js';
|
|
20
|
+
export type { EditMarker, EditBrief, EditBriefOptions } from './edit-brief.js';
|
|
21
|
+
export { generateEditBrief } from './edit-brief.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAE/D,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateEditBrief = exports.clustersToBeats = exports.clusterEvents = void 0;
|
|
4
|
+
var clusters_js_1 = require("./clusters.js");
|
|
5
|
+
Object.defineProperty(exports, "clusterEvents", { enumerable: true, get: function () { return clusters_js_1.clusterEvents; } });
|
|
6
|
+
Object.defineProperty(exports, "clustersToBeats", { enumerable: true, get: function () { return clusters_js_1.clustersToBeats; } });
|
|
7
|
+
var edit_brief_js_1 = require("./edit-brief.js");
|
|
8
|
+
Object.defineProperty(exports, "generateEditBrief", { enumerable: true, get: function () { return edit_brief_js_1.generateEditBrief; } });
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAkBA,6CAA+D;AAAtD,4GAAA,aAAa,OAAA;AAAE,8GAAA,eAAe,OAAA;AAGvC,iDAAoD;AAA3C,kHAAA,iBAAiB,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@medicine-wheel/narrative-cluster",
|
|
3
|
+
"version": "0.4.9",
|
|
4
|
+
"description": "Narrative Cluster Processor — turn witnessed perceptual events / rushes into thematic clusters, narrative beats, and a Film Edit Brief (EDL markers)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"medicine-wheel",
|
|
27
|
+
"film-production",
|
|
28
|
+
"narrative",
|
|
29
|
+
"cluster",
|
|
30
|
+
"edit-brief",
|
|
31
|
+
"edl",
|
|
32
|
+
"indigenous"
|
|
33
|
+
],
|
|
34
|
+
"author": "jgwill",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@medicine-wheel/ontology-core": "^0.4.9"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.7.0"
|
|
41
|
+
}
|
|
42
|
+
}
|