@nebutra/3d-pipeline 0.1.2 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nebutra/3d-pipeline",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "BrandContext-first mesh generation, export manifests, and previews",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -23,16 +23,20 @@
23
23
  "category": "ai",
24
24
  "summary": "BrandContext-first mesh, preview, and export surface"
25
25
  },
26
- "main": "./src/index.ts",
27
- "types": "./src/index.ts",
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
28
  "exports": {
29
- ".": "./src/index.ts"
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js",
32
+ "default": "./dist/index.js"
33
+ }
30
34
  },
31
35
  "dependencies": {
32
- "@nebutra/capability-kit": "0.2.2",
33
- "@nebutra/errors": "0.1.2",
34
- "@nebutra/generation-context": "0.1.2",
35
- "@nebutra/image-pipeline": "0.1.2"
36
+ "@nebutra/generation-context": "0.1.3",
37
+ "@nebutra/capability-kit": "0.2.4",
38
+ "@nebutra/image-pipeline": "0.1.3",
39
+ "@nebutra/errors": "0.1.2"
36
40
  },
37
41
  "devDependencies": {
38
42
  "@types/node": "^25.9.1",
@@ -53,6 +57,12 @@
53
57
  "publishConfig": {
54
58
  "access": "public"
55
59
  },
60
+ "files": [
61
+ "dist",
62
+ "README.md",
63
+ "LICENSE",
64
+ "CHANGELOG.md"
65
+ ],
56
66
  "scripts": {
57
67
  "build": "tsup",
58
68
  "test": "vitest run",
@@ -1,22 +0,0 @@
1
-
2
- > @nebutra/3d-pipeline@0.1.2 build /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/3d-pipeline
3
- > tsup
4
-
5
- CLI Building entry: src/cli.ts, 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/3d-pipeline/tsup.config.ts
9
- CLI Target: es2022
10
- CLI Cleaning output folder
11
- ESM Build start
12
- ESM dist/index.js 148.00 B
13
- ESM dist/cli.js 1.19 KB
14
- ESM dist/chunk-PGYUP7CZ.js 4.24 KB
15
- ESM dist/index.js.map 71.00 B
16
- ESM dist/cli.js.map 2.08 KB
17
- ESM dist/chunk-PGYUP7CZ.js.map 8.78 KB
18
- ESM ⚡️ Build success in 31ms
19
- DTS Build start
20
- DTS ⚡️ Build success in 2748ms
21
- DTS dist/cli.d.ts 13.00 B
22
- DTS dist/index.d.ts 1.56 KB
@@ -1,14 +0,0 @@
1
-
2
- > @nebutra/3d-pipeline@0.1.1 test /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/3d-pipeline
3
- > vitest run
4
-
5
-
6
- RUN v4.1.4 /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/3d-pipeline
7
-
8
- ✓ src/index.test.ts (2 tests) 106ms
9
-
10
- Test Files 1 passed (1)
11
- Tests 2 passed (2)
12
- Start at 09:38:45
13
- Duration 1.02s (transform 98ms, setup 0ms, import 151ms, tests 106ms, environment 0ms)
14
-
@@ -1,4 +0,0 @@
1
-
2
- > @nebutra/3d-pipeline@0.1.2 typecheck /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/3d-pipeline
3
- > tsc --noEmit
4
-
@@ -1,7 +0,0 @@
1
- import { createDemoBrandContext } from "@nebutra/generation-context";
2
- import { MeshPipeline } from "../src/index";
3
-
4
- const pipeline = new MeshPipeline();
5
- const asset = await pipeline.fromText("a 3D debugging loop logo", createDemoBrandContext());
6
-
7
- process.stdout.write(`${JSON.stringify(await pipeline.export(asset, "gltf"), null, 2)}\n`);
@@ -1,6 +0,0 @@
1
- import { createDemoBrandContext } from "@nebutra/generation-context";
2
- import { MeshPipeline } from "../src/index";
3
-
4
- const asset = await new MeshPipeline().fromText("a sleek robot mascot", createDemoBrandContext());
5
-
6
- process.stdout.write(`${asset.gltfPath}\n`);
@@ -1,7 +0,0 @@
1
- import { createDemoBrandContext } from "@nebutra/generation-context";
2
- import { MeshPipeline } from "../src/index";
3
-
4
- const pipeline = new MeshPipeline();
5
- const asset = await pipeline.fromText("product mockup", createDemoBrandContext());
6
-
7
- process.stdout.write(`${JSON.stringify(await pipeline.preview(asset), null, 2)}\n`);
package/src/cli.ts DELETED
@@ -1,28 +0,0 @@
1
- import { createDemoBrandContext } from "@nebutra/generation-context";
2
- import { MeshPipeline, readMeshDebug } from "./index";
3
-
4
- const command = process.argv[2] ?? "doctor";
5
- const pipeline = new MeshPipeline();
6
-
7
- if (command === "doctor") {
8
- process.stdout.write(
9
- `${JSON.stringify({ capability: "3d-pipeline", results: await pipeline.doctor() }, null, 2)}\n`,
10
- );
11
- } else if (command === "debug") {
12
- process.stdout.write(
13
- `${JSON.stringify({ capability: "3d-pipeline", entries: await readMeshDebug() }, null, 2)}\n`,
14
- );
15
- } else if (command === "preview") {
16
- const asset = await pipeline.fromText("sleek debugging mascot", createDemoBrandContext());
17
- process.stdout.write(
18
- `${JSON.stringify({ capability: "3d-pipeline", preview: await pipeline.preview(asset) }, null, 2)}\n`,
19
- );
20
- } else if (command === "export") {
21
- const asset = await pipeline.fromText("sleek debugging mascot", createDemoBrandContext());
22
- process.stdout.write(
23
- `${JSON.stringify({ capability: "3d-pipeline", export: await pipeline.export(asset, "gltf") }, null, 2)}\n`,
24
- );
25
- } else {
26
- process.stderr.write(`Unknown 3d-pipeline command: ${command}\n`);
27
- process.exitCode = 1;
28
- }
package/src/index.test.ts DELETED
@@ -1,32 +0,0 @@
1
- import { mkdtemp, readFile, rm } from "node:fs/promises";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { createDemoBrandContext } from "@nebutra/generation-context";
5
- import { afterEach, describe, expect, it } from "vitest";
6
- import { MeshPipeline, readMeshDebug } from "./index";
7
-
8
- let root: string | undefined;
9
-
10
- afterEach(async () => {
11
- if (root) await rm(root, { recursive: true, force: true });
12
- root = undefined;
13
- });
14
-
15
- describe("MeshPipeline", () => {
16
- it("requires BrandContext", async () => {
17
- await expect(new MeshPipeline().fromText("robot", undefined)).rejects.toMatchObject({
18
- capability: "3d-pipeline",
19
- });
20
- });
21
-
22
- it("writes a glTF asset and preview", async () => {
23
- root = await mkdtemp(join(tmpdir(), "mesh-pipeline-"));
24
- const asset = await new MeshPipeline({ root }).fromText(
25
- "robot mascot",
26
- createDemoBrandContext(),
27
- );
28
- expect(JSON.parse(await readFile(asset.gltfPath, "utf8")).asset.version).toBe("2.0");
29
- expect(await readFile(asset.previewImagePath, "utf8")).toContain("<svg");
30
- expect(await readMeshDebug(root)).toHaveLength(1);
31
- });
32
- });
package/src/index.ts DELETED
@@ -1,176 +0,0 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { appendCapabilityDebug, readCapabilityDebug } from "@nebutra/capability-kit/debug";
4
- import {
5
- assetId,
6
- type BrandContext,
7
- type GeneratedAsset,
8
- requireBrandContext,
9
- summarizeBrandContext,
10
- } from "@nebutra/generation-context";
11
- import type { ImageAsset } from "@nebutra/image-pipeline";
12
-
13
- export type MeshIntent =
14
- | { type: "product-mockup"; description: string }
15
- | { type: "logo-extrusion"; depth: number }
16
- | { type: "icon-pack"; count: number };
17
-
18
- export interface MeshAsset extends GeneratedAsset {
19
- readonly kind: "mesh";
20
- readonly gltfPath: string;
21
- readonly usdzPath?: string;
22
- readonly objPath?: string;
23
- readonly fbxPath?: string;
24
- readonly previewImagePath: string;
25
- readonly triangleCount: number;
26
- readonly format: "gltf";
27
- }
28
-
29
- export interface MeshHealth {
30
- readonly provider: string;
31
- readonly ok: boolean;
32
- readonly suggestion?: string;
33
- }
34
-
35
- export interface MeshPipelineOptions {
36
- readonly root?: string;
37
- }
38
-
39
- export async function readMeshDebug(root = process.cwd(), limit = 10): Promise<unknown[]> {
40
- return readCapabilityDebug("3d-pipeline", { root, limit });
41
- }
42
-
43
- function gltfDocument(brand: BrandContext, intent: MeshIntent): Record<string, unknown> {
44
- return {
45
- asset: { version: "2.0", generator: "@nebutra/3d-pipeline deterministic mesh" },
46
- scene: 0,
47
- scenes: [{ nodes: [0] }],
48
- nodes: [{ mesh: 0, name: `${brand.name} ${intent.type}` }],
49
- meshes: [
50
- {
51
- primitives: [
52
- {
53
- attributes: { POSITION: 0 },
54
- indices: 1,
55
- material: 0,
56
- },
57
- ],
58
- },
59
- ],
60
- materials: [{ name: brand.palette[0]?.name ?? "brand", pbrMetallicRoughness: {} }],
61
- extras: { brand: summarizeBrandContext(brand), intent },
62
- };
63
- }
64
-
65
- function previewSvg(brand: BrandContext, intent: MeshIntent): string {
66
- const primary = brand.palette[0]?.hex ?? "#111111";
67
- return `<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480">
68
- <rect width="640" height="480" fill="${primary}"/>
69
- <polygon points="320,72 520,360 120,360" fill="#ffffff" opacity="0.88"/>
70
- <text x="64" y="430" fill="#ffffff" font-family="${brand.typography.body}" font-size="28">${brand.name} ${intent.type}</text>
71
- </svg>`;
72
- }
73
-
74
- export class MeshPipeline {
75
- readonly #root: string;
76
-
77
- constructor(options: MeshPipelineOptions = {}) {
78
- this.#root = options.root ?? process.cwd();
79
- }
80
-
81
- async fromText(description: string, brandInput: BrandContext | undefined): Promise<MeshAsset> {
82
- return this.#write({ type: "product-mockup", description }, brandInput);
83
- }
84
-
85
- async fromImage(
86
- image: Pick<ImageAsset, "path">,
87
- brandInput: BrandContext | undefined,
88
- ): Promise<MeshAsset> {
89
- return this.#write(
90
- { type: "product-mockup", description: `image-to-mesh source ${image.path}` },
91
- brandInput,
92
- );
93
- }
94
-
95
- async batchFromIntent(
96
- intent: MeshIntent,
97
- brandInput: BrandContext | undefined,
98
- ): Promise<MeshAsset[]> {
99
- const count = intent.type === "icon-pack" ? Math.max(1, Math.min(intent.count, 10)) : 1;
100
- const assets: MeshAsset[] = [];
101
- for (let index = 0; index < count; index += 1) {
102
- assets.push(await this.#write(intent, brandInput));
103
- }
104
- return assets;
105
- }
106
-
107
- async preview(asset: MeshAsset): Promise<{ path: string }> {
108
- return { path: asset.previewImagePath };
109
- }
110
-
111
- async export(
112
- asset: MeshAsset,
113
- format: "gltf" | "obj" | "usdz" | "fbx" = "gltf",
114
- ): Promise<{ path: string }> {
115
- if (format === "gltf") return { path: asset.gltfPath };
116
- const path = join(
117
- this.#root,
118
- ".nebutra",
119
- "generated",
120
- "3d-pipeline",
121
- `${asset.id}.${format}.json`,
122
- );
123
- await writeFile(
124
- path,
125
- `${JSON.stringify({ source: asset.gltfPath, format }, null, 2)}\n`,
126
- "utf8",
127
- );
128
- return { path };
129
- }
130
-
131
- async doctor(): Promise<MeshHealth[]> {
132
- return [
133
- { provider: "gltf-local", ok: true },
134
- {
135
- provider: "local-mesh-model",
136
- ok: Boolean(process.env.MESH_LOCAL_MODEL_PATH),
137
- suggestion: "Set MESH_LOCAL_MODEL_PATH to enable local mesh generation.",
138
- },
139
- {
140
- provider: "remote-mesh",
141
- ok: Boolean(process.env.MESH_REMOTE_API_KEY),
142
- suggestion: "Set MESH_REMOTE_API_KEY to enable remote mesh fallback.",
143
- },
144
- ];
145
- }
146
-
147
- async #write(intent: MeshIntent, brandInput: BrandContext | undefined): Promise<MeshAsset> {
148
- const brand = requireBrandContext(brandInput, "3d-pipeline");
149
- const id = assetId("mesh", `${intent.type}_${brand.brandId}`);
150
- const dir = join(this.#root, ".nebutra", "generated", "3d-pipeline");
151
- const gltfPath = join(dir, `${id}.gltf`);
152
- const previewImagePath = join(dir, `${id}.svg`);
153
- await mkdir(dir, { recursive: true });
154
- await writeFile(gltfPath, `${JSON.stringify(gltfDocument(brand, intent), null, 2)}\n`, "utf8");
155
- await writeFile(previewImagePath, previewSvg(brand, intent), "utf8");
156
-
157
- const asset: MeshAsset = {
158
- id,
159
- tenantId: brand.tenantId,
160
- kind: "mesh",
161
- path: gltfPath,
162
- gltfPath,
163
- previewImagePath,
164
- brandId: brand.brandId,
165
- provider: "gltf-local",
166
- model: "brand-context-gltf-v1",
167
- createdAt: new Date().toISOString(),
168
- license: { status: "commercial-ok", source: "deterministic local mesh" },
169
- triangleCount: 1,
170
- format: "gltf",
171
- metadata: { intent, brandSource: brand.sourcePath },
172
- };
173
- await appendCapabilityDebug("3d-pipeline", { type: "mesh", asset }, { root: this.#root });
174
- return asset;
175
- }
176
- }
package/tsconfig.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "target": "esnext",
7
- "types": ["node"],
8
- "incremental": false
9
- },
10
- "include": ["src", "examples"],
11
- "exclude": ["node_modules", "dist"]
12
- }
package/tsup.config.ts DELETED
@@ -1,16 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- entry: ["src/index.ts", "src/cli.ts"],
5
- format: ["esm"],
6
- dts: true,
7
- sourcemap: true,
8
- clean: true,
9
- target: "es2022",
10
- external: [
11
- "@nebutra/capability-kit/debug",
12
- "@nebutra/errors",
13
- "@nebutra/generation-context",
14
- "@nebutra/image-pipeline",
15
- ],
16
- });