@nebutra/cinema 0.2.2 → 0.2.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @nebutra/cinema
2
2
 
3
+ ## 0.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - @nebutra/capability-kit@2.0.0
9
+ - @nebutra/graph-model@2.0.0
10
+
3
11
  ## 0.2.2
4
12
 
5
13
  ### Patch Changes
package/package.json CHANGED
@@ -1,24 +1,30 @@
1
1
  {
2
2
  "name": "@nebutra/cinema",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Agentic film-production IP: acyclic camera-continuity tree, consistency-ranked best-frame selection, novel→scene/event segmentation, film-director composition. Pure + dependency-injected; sits on reel/agents/graph-model.",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "nebutra": {
9
+ "status": "wip",
10
+ "graph": "labs",
9
11
  "featureId": "cinema",
10
12
  "category": "ai",
11
13
  "surface": "product-orchestration",
12
14
  "summary": "Multi-agent film-production orchestration over the reel media graph"
13
15
  },
14
- "main": "./src/index.ts",
15
- "types": "./src/index.ts",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
16
18
  "exports": {
17
- ".": "./src/index.ts"
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
23
+ }
18
24
  },
19
25
  "dependencies": {
20
- "@nebutra/capability-kit": "0.2.2",
21
- "@nebutra/graph-model": "0.2.2"
26
+ "@nebutra/capability-kit": "2.0.0",
27
+ "@nebutra/graph-model": "2.0.0"
22
28
  },
23
29
  "devDependencies": {
24
30
  "@types/node": "^25.9.1",
@@ -38,6 +44,12 @@
38
44
  "publishConfig": {
39
45
  "access": "public"
40
46
  },
47
+ "files": [
48
+ "dist",
49
+ "README.md",
50
+ "LICENSE",
51
+ "CHANGELOG.md"
52
+ ],
41
53
  "scripts": {
42
54
  "build": "tsup",
43
55
  "test": "vitest run",
@@ -1,17 +0,0 @@
1
-
2
- > @nebutra/cinema@0.2.2 build /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cinema
3
- > tsup
4
-
5
- CLI Building entry: src/index.ts
6
- CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.5.1
8
- CLI Using tsup config: /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cinema/tsup.config.ts
9
- CLI Target: es2022
10
- CLI Cleaning output folder
11
- ESM Build start
12
- ESM dist/index.js 4.37 KB
13
- ESM dist/index.js.map 12.98 KB
14
- ESM ⚡️ Build success in 13ms
15
- DTS Build start
16
- DTS ⚡️ Build success in 2786ms
17
- DTS dist/index.d.ts 5.90 KB
@@ -1,14 +0,0 @@
1
-
2
- > @nebutra/cinema@0.2.1 test /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cinema
3
- > vitest run
4
-
5
-
6
- RUN v4.1.4 /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cinema
7
-
8
- ✓ src/__tests__/cinema.test.ts (11 tests) 10ms
9
-
10
- Test Files 1 passed (1)
11
- Tests 11 passed (11)
12
- Start at 09:38:38
13
- Duration 641ms (transform 271ms, setup 0ms, import 301ms, tests 10ms, environment 0ms)
14
-
@@ -1,4 +0,0 @@
1
-
2
- > @nebutra/cinema@0.2.2 typecheck /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/cinema
3
- > tsc --noEmit
4
-
@@ -1,141 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { selectBestFrame } from "../best-frame";
3
- import { buildCameraTree, resolveContinuityChain } from "../camera-tree";
4
- import { runFilmPipeline } from "../director";
5
- import { CinemaError } from "../errors";
6
- import { compressNovel, extractScenes } from "../novel-segment";
7
-
8
- const cams = [
9
- { id: "c0", shotIds: ["s0", "s1"] },
10
- { id: "c1", shotIds: ["s2"] },
11
- { id: "c2", shotIds: ["s3"] },
12
- ];
13
-
14
- describe("buildCameraTree", () => {
15
- it("builds an acyclic tree with the first camera as root", async () => {
16
- const tree = await buildCameraTree(cams, async () => [
17
- { cameraId: "c0", parentCameraId: null, parentShotId: null, fullyCovers: true },
18
- { cameraId: "c1", parentCameraId: "c0", parentShotId: "s0", fullyCovers: true },
19
- { cameraId: "c2", parentCameraId: "c1", parentShotId: "s2", fullyCovers: false },
20
- ]);
21
- expect(tree.rootId).toBe("c0");
22
- expect(tree.parentOf("c1")).toBe("c0");
23
- });
24
-
25
- it("rejects a cyclic parent assignment (graph-model guard)", async () => {
26
- await expect(
27
- buildCameraTree(cams, async () => [
28
- { cameraId: "c0", parentCameraId: "c2", parentShotId: "s3", fullyCovers: true },
29
- { cameraId: "c1", parentCameraId: "c0", parentShotId: "s0", fullyCovers: true },
30
- { cameraId: "c2", parentCameraId: "c1", parentShotId: "s2", fullyCovers: true },
31
- ]),
32
- ).rejects.toBeInstanceOf(CinemaError);
33
- });
34
-
35
- it("rejects when the first camera is not a root", async () => {
36
- await expect(
37
- buildCameraTree(cams, async () => [
38
- { cameraId: "c0", parentCameraId: "c1", parentShotId: "s2", fullyCovers: true },
39
- { cameraId: "c1", parentCameraId: null, parentShotId: null, fullyCovers: true },
40
- { cameraId: "c2", parentCameraId: "c1", parentShotId: "s2", fullyCovers: true },
41
- ]),
42
- ).rejects.toThrow(/root/i);
43
- });
44
-
45
- it("resolveContinuityChain returns the root→node inheritance order", async () => {
46
- const tree = await buildCameraTree(cams, async () => [
47
- { cameraId: "c0", parentCameraId: null, parentShotId: null, fullyCovers: true },
48
- { cameraId: "c1", parentCameraId: "c0", parentShotId: "s0", fullyCovers: true },
49
- { cameraId: "c2", parentCameraId: "c1", parentShotId: "s2", fullyCovers: true },
50
- ]);
51
- expect(resolveContinuityChain(tree, "c2")).toEqual(["c0", "c1", "c2"]);
52
- expect(resolveContinuityChain(tree, "c0")).toEqual(["c0"]);
53
- });
54
- });
55
-
56
- describe("selectBestFrame", () => {
57
- const cands = [
58
- { id: "a", uri: "data:a" },
59
- { id: "b", uri: "data:b" },
60
- ];
61
- it("returns the ranked best and its reason", async () => {
62
- const r = await selectBestFrame(cands, "Alice on the left", async () => ({
63
- bestId: "b",
64
- reason: "best character consistency",
65
- }));
66
- expect(r.best.id).toBe("b");
67
- expect(r.reason).toMatch(/consistency/);
68
- });
69
- it("throws CinemaError on empty candidates", async () => {
70
- await expect(
71
- selectBestFrame([], "x", async () => ({ bestId: "", reason: "" })),
72
- ).rejects.toBeInstanceOf(CinemaError);
73
- });
74
- it("throws when the ranker picks an unknown id", async () => {
75
- await expect(
76
- selectBestFrame(cands, "x", async () => ({ bestId: "zzz", reason: "" })),
77
- ).rejects.toThrow(/not among/i);
78
- });
79
- });
80
-
81
- describe("novel segmentation", () => {
82
- it("compressNovel preserves chunk order", async () => {
83
- const out = await compressNovel(["AAA", "BBB"], async (p) => `c:${p.slice(-3)}`);
84
- expect(out).toEqual(["c:AAA", "c:BBB"]);
85
- });
86
- it("extractScenes parses a JSON array, tolerating prose wrapping", async () => {
87
- const scenes = await extractScenes("novel", async () => 'noise ["scene 1","scene 2"] tail');
88
- expect(scenes).toEqual(["scene 1", "scene 2"]);
89
- });
90
- it("extractScenes throws CinemaError on unparseable output", async () => {
91
- await expect(extractScenes("x", async () => "no array here")).rejects.toBeInstanceOf(
92
- CinemaError,
93
- );
94
- });
95
- });
96
-
97
- describe("runFilmPipeline", () => {
98
- it("threads idea→script→shots→cameras→frames in order and returns the assembly", async () => {
99
- const calls: string[] = [];
100
- const result = await runFilmPipeline(
101
- { idea: "a dog learns to fly" },
102
- {
103
- writeScript: async (idea) => {
104
- calls.push("script");
105
- return `SCRIPT(${idea})`;
106
- },
107
- splitShots: async (script) => {
108
- calls.push("shots");
109
- return [`${script}#0`, `${script}#1`];
110
- },
111
- buildCameras: async (shots) => {
112
- calls.push("cameras");
113
- return shots.map((_, i) => ({ id: `c${i}`, shotIds: [`s${i}`] }));
114
- },
115
- inferParents: async (cameras) =>
116
- cameras.map((c, i) => ({
117
- cameraId: c.id,
118
- parentCameraId: i === 0 ? null : `c${i - 1}`,
119
- parentShotId: i === 0 ? null : `s${i - 1}`,
120
- fullyCovers: true,
121
- })),
122
- renderShot: async (shot) => {
123
- calls.push(`render:${shot}`);
124
- return { uri: `mp4:${shot}` };
125
- },
126
- },
127
- );
128
- expect(calls).toEqual([
129
- "script",
130
- "shots",
131
- "cameras",
132
- "render:SCRIPT(a dog learns to fly)#0",
133
- "render:SCRIPT(a dog learns to fly)#1",
134
- ]);
135
- expect(result.clips.map((c) => c.uri)).toEqual([
136
- "mp4:SCRIPT(a dog learns to fly)#0",
137
- "mp4:SCRIPT(a dog learns to fly)#1",
138
- ]);
139
- expect(result.cameraTree.rootId).toBe("c0");
140
- });
141
- });
package/src/best-frame.ts DELETED
@@ -1,55 +0,0 @@
1
- /**
2
- * Consistency-ranked best-frame selection — ViMax-distinct IP, re-expressed.
3
- *
4
- * Generate N candidate frames, then have an MLLM rank them for character /
5
- * spatial / semantic consistency against the target description and pick the
6
- * best. The ranking is injected (a model call in production); this module
7
- * owns only the orchestration + validation invariants.
8
- */
9
-
10
- import { CinemaError } from "./errors";
11
-
12
- export interface FrameCandidate {
13
- readonly id: string;
14
- readonly uri: string;
15
- }
16
-
17
- /** Injected ranker: returns the winning candidate id + a human reason. */
18
- export type RankFrames = (
19
- candidates: readonly FrameCandidate[],
20
- targetDescription: string,
21
- ) => Promise<{ bestId: string; reason: string }>;
22
-
23
- export interface BestFrame {
24
- readonly best: FrameCandidate;
25
- readonly reason: string;
26
- }
27
-
28
- /**
29
- * Select the most consistent frame. Throws if there are no candidates or if
30
- * the ranker returns an id that is not among them (a model contract breach
31
- * must never silently pick the wrong frame).
32
- */
33
- export async function selectBestFrame(
34
- candidates: readonly FrameCandidate[],
35
- targetDescription: string,
36
- rank: RankFrames,
37
- ): Promise<BestFrame> {
38
- if (candidates.length === 0) {
39
- throw new CinemaError("No candidate frames to select from.", {
40
- code: "CINEMA_NO_CANDIDATES",
41
- suggestion: "Generate at least one candidate frame before ranking.",
42
- });
43
- }
44
- const { bestId, reason } = await rank(candidates, targetDescription);
45
- const best = candidates.find((c) => c.id === bestId);
46
- if (!best) {
47
- throw new CinemaError(`Ranker chose "${bestId}", which is not among the candidates.`, {
48
- code: "CINEMA_RANKER_CONTRACT",
49
- suggestion:
50
- "The injected ranker must return one of the provided candidate ids; " +
51
- "constrain its output schema.",
52
- });
53
- }
54
- return { best, reason };
55
- }
@@ -1,103 +0,0 @@
1
- /**
2
- * Camera-continuity tree — the ViMax-distinct IP, re-expressed.
3
- *
4
- * A film is shot by multiple cameras; a parent camera's footage encompasses
5
- * its children's, so a child shot can inherit the parent's frames for
6
- * temporal/character continuity. The parent inference itself is a model call
7
- * (injected — never bound to a provider here). The structural invariants are
8
- * enforced locally with the neutral `@nebutra/graph-model` acyclic guard
9
- * (governance: reuse, don't re-implement cycle detection).
10
- */
11
-
12
- import type { GraphEdge } from "@nebutra/graph-model";
13
- import { wouldCreateCycle } from "@nebutra/graph-model";
14
- import { CinemaError } from "./errors";
15
-
16
- export interface Camera {
17
- readonly id: string;
18
- readonly shotIds: readonly string[];
19
- }
20
-
21
- export interface CameraParent {
22
- readonly cameraId: string;
23
- /** Null = this camera is a root. */
24
- readonly parentCameraId: string | null;
25
- /** Which parent shot subsumes this camera (null at root). */
26
- readonly parentShotId: string | null;
27
- readonly fullyCovers: boolean;
28
- readonly missingInfo?: string;
29
- }
30
-
31
- /** Injected: infer each camera's parent (a model call in production). */
32
- export type InferParents = (cameras: readonly Camera[]) => Promise<readonly CameraParent[]>;
33
-
34
- export interface CameraTree {
35
- readonly rootId: string;
36
- readonly cameras: readonly Camera[];
37
- /** Parent camera id, or null for the root. */
38
- parentOf(cameraId: string): string | null;
39
- }
40
-
41
- /**
42
- * Build the camera tree: infer parents, enforce that the first camera is the
43
- * root, and that the parent relation is acyclic (a parent's footage cannot
44
- * transitively depend on its descendant).
45
- */
46
- export async function buildCameraTree(
47
- cameras: readonly Camera[],
48
- infer: InferParents,
49
- ): Promise<CameraTree> {
50
- if (cameras.length === 0) {
51
- throw new CinemaError("Cannot build a camera tree from zero cameras.", {
52
- code: "CINEMA_NO_CAMERAS",
53
- suggestion: "Pass at least one camera (the root).",
54
- });
55
- }
56
-
57
- const parents = await infer(cameras);
58
- const parentById = new Map<string, string | null>();
59
- for (const p of parents) parentById.set(p.cameraId, p.parentCameraId);
60
-
61
- const firstId = cameras[0]?.id;
62
- if (parentById.get(firstId as string)) {
63
- throw new CinemaError(`The first camera "${firstId}" must be the tree root.`, {
64
- code: "CINEMA_BAD_ROOT",
65
- suggestion: "Ensure the inference returns parentCameraId=null for the first camera.",
66
- });
67
- }
68
-
69
- // Acyclic guard via graph-model: add parent→child edges incrementally.
70
- const edges: GraphEdge[] = [];
71
- for (const p of parents) {
72
- if (p.parentCameraId == null) continue;
73
- if (wouldCreateCycle(edges, p.parentCameraId, p.cameraId)) {
74
- throw new CinemaError(`Camera parent assignment is cyclic at "${p.cameraId}".`, {
75
- code: "CINEMA_CYCLIC_TREE",
76
- suggestion:
77
- "A parent camera must not transitively depend on its descendant; " +
78
- "re-infer parents or break the cycle.",
79
- });
80
- }
81
- edges.push({ from: p.parentCameraId, to: p.cameraId });
82
- }
83
-
84
- return {
85
- rootId: firstId as string,
86
- cameras,
87
- parentOf: (id) => parentById.get(id) ?? null,
88
- };
89
- }
90
-
91
- /** Root→node camera order — the frame-inheritance chain for continuity. */
92
- export function resolveContinuityChain(tree: CameraTree, cameraId: string): string[] {
93
- const chain: string[] = [];
94
- let cur: string | null = cameraId;
95
- const seen = new Set<string>();
96
- while (cur) {
97
- if (seen.has(cur)) break; // defensive; tree is acyclic by construction
98
- seen.add(cur);
99
- chain.push(cur);
100
- cur = tree.parentOf(cur);
101
- }
102
- return chain.reverse();
103
- }
package/src/director.ts DELETED
@@ -1,50 +0,0 @@
1
- /**
2
- * Film-director composition — the ViMax pipeline form, re-expressed as a
3
- * thin, fully-injected orchestrator. Every stage (write script, split shots,
4
- * build cameras, infer parents, render a shot) is supplied by the caller and
5
- * wired to Sailor primitives (`@nebutra/agents`, `@nebutra/reel`,
6
- * `@nebutra/cinema` camera tree). This module owns only the sequencing and
7
- * the cross-shot continuity guarantee — no model, no I/O.
8
- */
9
-
10
- import { buildCameraTree, type Camera, type CameraParent, type CameraTree } from "./camera-tree";
11
-
12
- export interface FilmInput {
13
- readonly idea: string;
14
- }
15
-
16
- export interface FilmSteps {
17
- readonly writeScript: (idea: string) => Promise<string>;
18
- readonly splitShots: (script: string) => Promise<readonly string[]>;
19
- readonly buildCameras: (shots: readonly string[]) => Promise<readonly Camera[]>;
20
- readonly inferParents: (cameras: readonly Camera[]) => Promise<readonly CameraParent[]>;
21
- readonly renderShot: (shot: string, index: number) => Promise<{ uri: string }>;
22
- }
23
-
24
- export interface FilmResult {
25
- readonly script: string;
26
- readonly shots: readonly string[];
27
- readonly cameraTree: CameraTree;
28
- readonly clips: ReadonlyArray<{ shot: string; uri: string }>;
29
- }
30
-
31
- /**
32
- * Run idea → script → shots → cameras (acyclic continuity tree) → per-shot
33
- * render → assembled clip list. Shots render in narrative order so a later
34
- * shot can reuse an earlier one's frames for continuity.
35
- */
36
- export async function runFilmPipeline(input: FilmInput, steps: FilmSteps): Promise<FilmResult> {
37
- const script = await steps.writeScript(input.idea);
38
- const shots = await steps.splitShots(script);
39
- const cameras = await steps.buildCameras(shots);
40
- const cameraTree = await buildCameraTree(cameras, steps.inferParents);
41
-
42
- const clips: Array<{ shot: string; uri: string }> = [];
43
- for (let i = 0; i < shots.length; i++) {
44
- const shot = shots[i] as string;
45
- const { uri } = await steps.renderShot(shot, i);
46
- clips.push({ shot, uri });
47
- }
48
-
49
- return { script, shots, cameraTree, clips };
50
- }
package/src/errors.ts DELETED
@@ -1,13 +0,0 @@
1
- import { CapabilityError } from "@nebutra/capability-kit";
2
-
3
- /** Every cinema failure is a CinemaError (code + actionable suggestion). */
4
- export class CinemaError extends CapabilityError {
5
- constructor(message: string, init: { code: string; suggestion: string; cause?: unknown }) {
6
- super(message, init, {
7
- name: "CinemaError",
8
- emptySuggestionFallback:
9
- "No suggestion was provided. This is a bug in @nebutra/cinema — " +
10
- "report it with the failing stage.",
11
- });
12
- }
13
- }
package/src/index.ts DELETED
@@ -1,38 +0,0 @@
1
- /**
2
- * @nebutra/cinema — agentic film-production IP absorbed from a research
3
- * video pipeline, re-expressed clean-room as pure, dependency-injected
4
- * orchestration on top of Sailor primitives.
5
- *
6
- * SKIP (reused, not re-implemented): typed media DAG + script→shots split
7
- * (`@nebutra/reel`), agent loop (`@nebutra/agent-runtime`), LLM + image/video
8
- * generation registry (`@nebutra/agents`), acyclic guard
9
- * (`@nebutra/graph-model`), errors/cli (`@nebutra/capability-kit`).
10
- *
11
- * PORT (this package — the differentiated IP): camera-continuity tree,
12
- * consistency-ranked best-frame selection, novel→scene segmentation, and the
13
- * film-director composition. Every model/IO touchpoint is injected, so this
14
- * is multi-tenant-agnostic and fully unit-testable.
15
- */
16
-
17
- export {
18
- type BestFrame,
19
- type FrameCandidate,
20
- type RankFrames,
21
- selectBestFrame,
22
- } from "./best-frame";
23
- export {
24
- buildCameraTree,
25
- type Camera,
26
- type CameraParent,
27
- type CameraTree,
28
- type InferParents,
29
- resolveContinuityChain,
30
- } from "./camera-tree";
31
- export {
32
- type FilmInput,
33
- type FilmResult,
34
- type FilmSteps,
35
- runFilmPipeline,
36
- } from "./director";
37
- export { CinemaError } from "./errors";
38
- export { type CompleteFn, compressNovel, extractScenes } from "./novel-segment";
@@ -1,59 +0,0 @@
1
- /**
2
- * Novel → compressed chunks → scene units — ViMax-distinct IP, re-expressed.
3
- *
4
- * Long-form adaptation: compress chapters (preserving plot/character) then
5
- * segment into filmable scenes. Both steps are model calls — injected via a
6
- * `CompleteFn` (the same injection shape `@nebutra/reel/storyboard` uses, so
7
- * callers wire it to `@nebutra/agents` once). RAG retrieval, when used, is
8
- * supplied by `@nebutra/knowledge-rag` through the same injection — not a
9
- * hard dependency here.
10
- */
11
-
12
- import { CinemaError } from "./errors";
13
-
14
- /** Injected model call: prompt in, completion text out. */
15
- export type CompleteFn = (prompt: string) => Promise<string>;
16
-
17
- /** Compress each chunk independently; order is preserved. */
18
- export async function compressNovel(
19
- chunks: readonly string[],
20
- complete: CompleteFn,
21
- ): Promise<string[]> {
22
- return Promise.all(
23
- chunks.map((chunk) =>
24
- complete(
25
- `Compress this passage, preserving plot, character and emotional ` +
26
- `beats; output prose only:\n\n${chunk}`,
27
- ),
28
- ),
29
- );
30
- }
31
-
32
- /**
33
- * Extract ordered scene units from compressed text. The model is asked for a
34
- * JSON array of scene strings; parsing tolerates surrounding prose but a
35
- * non-array response is a hard error (a silent empty list would drop story).
36
- */
37
- export async function extractScenes(compressed: string, complete: CompleteFn): Promise<string[]> {
38
- const raw = await complete(
39
- `Split the following into a JSON array of self-contained, filmable ` +
40
- `scene descriptions in narrative order. Output ONLY the array:\n\n${compressed}`,
41
- );
42
- const match = raw.match(/\[[\s\S]*\]/);
43
- if (match) {
44
- try {
45
- const parsed: unknown = JSON.parse(match[0]);
46
- if (Array.isArray(parsed) && parsed.every((s) => typeof s === "string")) {
47
- return parsed as string[];
48
- }
49
- } catch {
50
- // fall through to the structured error below
51
- }
52
- }
53
- throw new CinemaError("Scene extraction did not return a JSON string array.", {
54
- code: "CINEMA_SCENE_PARSE",
55
- suggestion:
56
- "Constrain the model to emit a JSON array of strings (use a schema / " +
57
- "response-format), or retry — output was not parseable.",
58
- });
59
- }
package/tsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src",
6
- "incremental": false
7
- },
8
- "include": ["src/**/*.ts"],
9
- "exclude": ["node_modules", "dist"]
10
- }
package/tsup.config.ts DELETED
@@ -1,10 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- entry: ["src/index.ts"],
5
- format: ["esm"],
6
- dts: true,
7
- clean: true,
8
- sourcemap: true,
9
- target: "es2022",
10
- });