@harpiaresearch/vref 1.0.0 → 1.0.2
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/LICENSE +1 -1
- package/README.md +261 -193
- package/dist/VREFReader.d.ts +4 -0
- package/dist/VREFReader.js +19 -0
- package/dist/VREFWriter.d.ts +1 -1
- package/dist/VREFWriter.js +67 -13
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +153 -30
- package/dist/types.d.ts +6 -2
- package/package.json +4 -4
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,220 +1,274 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# VREF — Visual Reference Format
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
**A standardized format for curated visual references in AI image generation**
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/@harpiaresearch/vref)
|
|
6
8
|
[](LICENSE)
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
Harpia AI Research
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<div align="center">
|
|
17
|
+
|
|
18
|
+
## The Problem
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
You know exactly what you want your AI to generate, but describing it in words is **nearly impossible**.
|
|
23
|
+
|
|
24
|
+
- 🤔 "How do I describe this art style?"
|
|
25
|
+
- 📸 "I have 20 reference images, but uploading them one by one is tedious"
|
|
26
|
+
- 🔄 "I can't easily share or reuse my reference collections"
|
|
27
|
+
- 😤 "Text prompts alone just don't capture the vision"
|
|
28
|
+
|
|
29
|
+
**Visual concepts are hard to describe, but easy to show.**
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
<div align="center">
|
|
34
|
+
|
|
35
|
+
## The Solution
|
|
36
|
+
|
|
37
|
+
**VREF** (Visual Reference Format) is a simple, open standard that packages your visual references into a single `.vref` file.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Your 50 reference images → one references.vref file
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
### How It Works
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
1. Package images → references.vref
|
|
49
|
+
2. Upload to AI platform
|
|
50
|
+
3. Platform samples N random images
|
|
51
|
+
4. You write text prompt
|
|
52
|
+
5. AI generates with visual context
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Instead of fighting with text descriptions, you **show the AI what you want**.
|
|
9
56
|
|
|
10
57
|
---
|
|
11
58
|
|
|
12
|
-
|
|
59
|
+
<div align="center">
|
|
60
|
+
|
|
61
|
+
## Why You Should Use VREF
|
|
13
62
|
|
|
14
|
-
|
|
63
|
+
</div>
|
|
15
64
|
|
|
16
|
-
|
|
65
|
+
### ✅ For Creators
|
|
17
66
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
67
|
+
**Stop struggling with prompts.**
|
|
68
|
+
- Package your mood boards, style references, and inspirations
|
|
69
|
+
- Upload once, reuse forever
|
|
70
|
+
- Share with your team or community
|
|
22
71
|
|
|
23
|
-
|
|
72
|
+
**Example:** Download `roblox-banners.vref` → Upload → Describe what you want → Get perfect results
|
|
24
73
|
|
|
25
|
-
|
|
26
|
-
- ❌ Know what they want visually but can't describe it in words
|
|
27
|
-
- ❌ Need to upload 10-50 reference images individually
|
|
28
|
-
- ❌ Can't easily share or reuse reference collections
|
|
29
|
-
- ❌ Struggle to communicate style, mood, and composition
|
|
74
|
+
### ✅ For Platforms
|
|
30
75
|
|
|
31
|
-
|
|
76
|
+
**Better user experience.**
|
|
77
|
+
- Users get better results faster
|
|
78
|
+
- Reduces prompt engineering frustration
|
|
79
|
+
- Differentiates your platform
|
|
80
|
+
- Simple to implement (< 1 day)
|
|
32
81
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
82
|
+
### ✅ For Everyone
|
|
83
|
+
|
|
84
|
+
**It's an open standard.**
|
|
85
|
+
- No vendor lock-in
|
|
86
|
+
- Portable across platforms
|
|
87
|
+
- Community-driven
|
|
88
|
+
- Free forever
|
|
40
89
|
|
|
41
90
|
---
|
|
42
91
|
|
|
92
|
+
<div align="center">
|
|
93
|
+
|
|
94
|
+
## Real-World Use Cases
|
|
95
|
+
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
### 🎮 Game Development
|
|
99
|
+
```
|
|
100
|
+
rpg-sprites.vref → Character references
|
|
101
|
+
platformer-tiles.vref → Level design inspiration
|
|
102
|
+
ui-elements.vref → Interface styles
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 🎨 Creative Work
|
|
106
|
+
```
|
|
107
|
+
architecture.vref → Building styles
|
|
108
|
+
color-palettes.vref → Mood and tone
|
|
109
|
+
typography.vref → Font and layout ideas
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 🤖 AI Training
|
|
113
|
+
```
|
|
114
|
+
training-data.vref → Curated datasets
|
|
115
|
+
style-transfer.vref → Style references
|
|
116
|
+
fine-tuning.vref → Model-specific data
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
<div align="center">
|
|
122
|
+
|
|
43
123
|
## Installation
|
|
44
124
|
|
|
125
|
+
</div>
|
|
126
|
+
|
|
45
127
|
```bash
|
|
46
128
|
npm install @harpiaresearch/vref
|
|
47
129
|
```
|
|
48
130
|
|
|
49
|
-
Or use directly
|
|
131
|
+
Or use directly:
|
|
50
132
|
|
|
51
133
|
```bash
|
|
52
|
-
npx
|
|
134
|
+
npx @harpiaresearch/vref
|
|
53
135
|
```
|
|
54
136
|
|
|
55
137
|
---
|
|
56
138
|
|
|
139
|
+
<div align="center">
|
|
140
|
+
|
|
57
141
|
## Quick Start
|
|
58
142
|
|
|
59
|
-
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
### Creating a .vref File
|
|
60
146
|
|
|
147
|
+
**CLI:**
|
|
61
148
|
```bash
|
|
62
|
-
# From a directory
|
|
63
|
-
npx
|
|
149
|
+
# From a directory (via npx or global/local vref)
|
|
150
|
+
npx @harpiaresearch/vref ./my-images -o references.vref
|
|
64
151
|
|
|
65
|
-
# With metadata
|
|
66
|
-
npx
|
|
152
|
+
# With metadata (including title name)
|
|
153
|
+
npx @harpiaresearch/vref ./images -o pack.vref \
|
|
67
154
|
-n "My Reference Pack" \
|
|
68
|
-
-d "Collection of
|
|
69
|
-
-t "style,
|
|
155
|
+
-d "Collection of art references" \
|
|
156
|
+
-t "art,style,inspiration" \
|
|
70
157
|
-a "Your Name" \
|
|
71
158
|
-l "CC-BY-4.0"
|
|
72
|
-
|
|
73
|
-
# From a single image
|
|
74
|
-
npx create-vref image.png -o single.vref
|
|
75
159
|
```
|
|
76
160
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
**Creating a .vref file:**
|
|
80
|
-
|
|
161
|
+
**Code:**
|
|
81
162
|
```typescript
|
|
82
163
|
import { VREFWriter } from '@harpiaresearch/vref';
|
|
83
164
|
|
|
84
165
|
const writer = new VREFWriter({
|
|
85
|
-
|
|
86
|
-
description: 'Collection of
|
|
87
|
-
tags: ['
|
|
166
|
+
name: 'Art Style References',
|
|
167
|
+
description: 'Collection of curated art style references',
|
|
168
|
+
tags: ['art', 'style'],
|
|
88
169
|
author: 'Your Name',
|
|
89
170
|
license: 'CC-BY-4.0',
|
|
90
171
|
});
|
|
91
172
|
|
|
92
|
-
|
|
93
|
-
writer.
|
|
173
|
+
writer.addImagesFromDirectory('./images');
|
|
174
|
+
writer.write('references.vref');
|
|
175
|
+
```
|
|
94
176
|
|
|
95
|
-
|
|
96
|
-
writer.addImageFromFile('./image1.png');
|
|
97
|
-
writer.addImage('image2.jpg', imageBuffer);
|
|
177
|
+
### Inspecting, Validating & Extracting via CLI
|
|
98
178
|
|
|
99
|
-
|
|
100
|
-
|
|
179
|
+
```bash
|
|
180
|
+
# Inspect metadata and images in a pack
|
|
181
|
+
vref info references.vref
|
|
101
182
|
|
|
102
|
-
|
|
183
|
+
# Validate format and manifest integrity
|
|
184
|
+
vref validate references.vref
|
|
185
|
+
|
|
186
|
+
# Extract images to a directory
|
|
187
|
+
vref extract references.vref ./extracted-images
|
|
103
188
|
```
|
|
104
189
|
|
|
105
|
-
|
|
190
|
+
### Reading a .vref File
|
|
106
191
|
|
|
107
192
|
```typescript
|
|
108
193
|
import { VREFReader } from '@harpiaresearch/vref';
|
|
109
194
|
|
|
110
|
-
// Read
|
|
111
|
-
const vref = VREFReader.read('references.vref', {
|
|
195
|
+
// Read file (optional validation & preloading)
|
|
196
|
+
const vref = VREFReader.read('references.vref', {
|
|
197
|
+
validate: true,
|
|
198
|
+
loadImages: true,
|
|
199
|
+
});
|
|
112
200
|
|
|
113
201
|
console.log(`Loaded ${vref.manifest.imageCount} images`);
|
|
114
|
-
console.log(`Description: ${vref.manifest.metadata?.description}`);
|
|
115
202
|
|
|
116
|
-
//
|
|
117
|
-
const
|
|
118
|
-
randomImages.forEach((buffer, idx) => {
|
|
119
|
-
console.log(`Image ${idx + 1}: ${buffer.length} bytes`);
|
|
120
|
-
});
|
|
203
|
+
// Sample 3 random images
|
|
204
|
+
const randomSamples = vref.sample(3);
|
|
121
205
|
|
|
122
206
|
// Get specific image
|
|
123
207
|
const image = vref.getImage('photo1.png');
|
|
124
|
-
if (image) {
|
|
125
|
-
// Do something with the image buffer
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Read only the manifest:**
|
|
130
208
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const manifest = VREFReader.readManifest('references.vref');
|
|
135
|
-
console.log(manifest);
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
**Validate a .vref file:**
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
import { VREFReader } from '@harpiaresearch/vref';
|
|
142
|
-
|
|
143
|
-
const result = VREFReader.validate('references.vref');
|
|
144
|
-
if (result.valid) {
|
|
145
|
-
console.log('✅ Valid .vref file');
|
|
146
|
-
} else {
|
|
147
|
-
console.error('❌ Invalid .vref file:');
|
|
148
|
-
result.errors.forEach(err => console.error(` - ${err}`));
|
|
149
|
-
}
|
|
209
|
+
// Extract all images to disk
|
|
210
|
+
VREFReader.extract('references.vref', './extracted');
|
|
150
211
|
```
|
|
151
212
|
|
|
152
213
|
---
|
|
153
214
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
### 1. **AI Image Generation Platforms**
|
|
215
|
+
<div align="center">
|
|
157
216
|
|
|
158
|
-
|
|
159
|
-
- Midjourney
|
|
160
|
-
- Stable Diffusion
|
|
161
|
-
- DALL-E
|
|
162
|
-
- Replicate
|
|
163
|
-
- Custom AI platforms
|
|
217
|
+
## For AI Platform Developers
|
|
164
218
|
|
|
165
|
-
|
|
219
|
+
Integrating VREF takes **< 1 day**:
|
|
166
220
|
|
|
167
|
-
|
|
221
|
+
</div>
|
|
168
222
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- `platformer-tiles.vref` — Tile sets for platformers
|
|
172
|
-
- `ui-elements.vref` — UI design references
|
|
223
|
+
```typescript
|
|
224
|
+
import { VREFReader } from '@harpiaresearch/vref';
|
|
173
225
|
|
|
174
|
-
|
|
226
|
+
// 1. User uploads .vref
|
|
227
|
+
const vref = VREFReader.read(uploadedFile, { loadImages: true });
|
|
175
228
|
|
|
176
|
-
|
|
229
|
+
// 2. Show slider: "How many references? (1-{imageCount})"
|
|
230
|
+
const count = getUserSliderValue();
|
|
177
231
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
import { PixelGenModel } from '@harpiaresearch/pixelgen';
|
|
232
|
+
// 3. Sample random images
|
|
233
|
+
const references = vref.sample(count);
|
|
181
234
|
|
|
182
|
-
|
|
183
|
-
const
|
|
235
|
+
// 4. Get user prompt
|
|
236
|
+
const prompt = getUserPrompt();
|
|
184
237
|
|
|
185
|
-
//
|
|
186
|
-
|
|
238
|
+
// 5. Send to your AI
|
|
239
|
+
await generateImage({
|
|
240
|
+
prompt: prompt,
|
|
241
|
+
referenceImages: references,
|
|
242
|
+
});
|
|
187
243
|
```
|
|
188
244
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
Share mood boards and references:
|
|
192
|
-
- `architecture-modern.vref`
|
|
193
|
-
- `color-palettes-warm.vref`
|
|
194
|
-
- `typography-references.vref`
|
|
245
|
+
**That's it.** ✅
|
|
195
246
|
|
|
196
247
|
---
|
|
197
248
|
|
|
198
|
-
## File Format
|
|
249
|
+
## File Format
|
|
199
250
|
|
|
200
251
|
A `.vref` file is a ZIP container with:
|
|
201
252
|
|
|
202
253
|
```
|
|
203
|
-
|
|
204
|
-
├── manifest.json
|
|
254
|
+
references.vref
|
|
255
|
+
├── manifest.json (metadata)
|
|
205
256
|
├── image1.png
|
|
206
257
|
├── image2.jpg
|
|
207
|
-
|
|
208
|
-
└── ...
|
|
258
|
+
└── image3.webp
|
|
209
259
|
```
|
|
210
260
|
|
|
211
|
-
|
|
261
|
+
**Supported formats:** PNG, JPEG, WebP, GIF, AVIF
|
|
262
|
+
|
|
263
|
+
**Only images allowed.** Any other file type is rejected.
|
|
264
|
+
|
|
265
|
+
### manifest.json
|
|
212
266
|
|
|
213
267
|
```json
|
|
214
268
|
{
|
|
215
|
-
"version": "1.0.
|
|
269
|
+
"version": "1.0.2",
|
|
216
270
|
"format": "VREF",
|
|
217
|
-
"fileName": "
|
|
271
|
+
"fileName": "references.vref",
|
|
218
272
|
"imageCount": 24,
|
|
219
273
|
"images": [
|
|
220
274
|
{
|
|
@@ -225,31 +279,47 @@ my-pack.vref (ZIP)
|
|
|
225
279
|
"height": 1080
|
|
226
280
|
}
|
|
227
281
|
],
|
|
228
|
-
"createdAt": "
|
|
282
|
+
"createdAt": "2026-10-13T10:30:00.000Z",
|
|
229
283
|
"metadata": {
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
284
|
+
"name": "RPG Sprites",
|
|
285
|
+
"description": "Collection of references",
|
|
286
|
+
"tags": ["style", "mood"],
|
|
287
|
+
"author": "Your Name",
|
|
233
288
|
"license": "CC-BY-4.0"
|
|
234
289
|
}
|
|
235
290
|
}
|
|
236
291
|
```
|
|
237
292
|
|
|
238
|
-
|
|
293
|
+
---
|
|
239
294
|
|
|
240
|
-
|
|
241
|
-
- ✅ JPEG (`.jpg`, `.jpeg`)
|
|
242
|
-
- ✅ WebP (`.webp`)
|
|
243
|
-
- ✅ GIF (`.gif`)
|
|
244
|
-
- ✅ AVIF (`.avif`)
|
|
295
|
+
<div align="center">
|
|
245
296
|
|
|
246
|
-
|
|
297
|
+
## Why VREF Will Win
|
|
247
298
|
|
|
248
|
-
|
|
299
|
+
</div>
|
|
300
|
+
|
|
301
|
+
### 🎯 Solves a Real Problem
|
|
302
|
+
Everyone who uses AI image generation has struggled with describing visual concepts. VREF makes it trivial.
|
|
303
|
+
|
|
304
|
+
### 🚀 Simple to Implement
|
|
305
|
+
ZIP + JSON. No complex dependencies. Works everywhere.
|
|
306
|
+
|
|
307
|
+
### 🌍 Open Standard
|
|
308
|
+
No company owns it. Community-driven. Free forever.
|
|
249
309
|
|
|
250
|
-
|
|
310
|
+
### 📦 Already Shipping
|
|
311
|
+
- ✅ npm package published
|
|
312
|
+
- ✅ Full TypeScript support
|
|
313
|
+
- ✅ CLI tool ready (`create`, `info`, `validate`, `extract`)
|
|
314
|
+
- ✅ Automated test suite (`node:test`)
|
|
315
|
+
- ✅ Complete documentation
|
|
251
316
|
|
|
252
|
-
###
|
|
317
|
+
### 🇧🇷 Made in Brazil
|
|
318
|
+
Harpia AI Research is putting Brazil on the map of AI innovation.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### VREFWriter
|
|
253
323
|
|
|
254
324
|
```typescript
|
|
255
325
|
class VREFWriter {
|
|
@@ -265,102 +335,100 @@ class VREFWriter {
|
|
|
265
335
|
}
|
|
266
336
|
```
|
|
267
337
|
|
|
268
|
-
###
|
|
338
|
+
### VREFReader
|
|
269
339
|
|
|
270
340
|
```typescript
|
|
271
341
|
class VREFReader {
|
|
272
342
|
static read(filePath: string, options?: VREFReadOptions): VREFReadResult;
|
|
273
343
|
static readManifest(filePath: string): VREFManifest;
|
|
274
344
|
static validate(filePath: string): { valid: boolean; errors: string[] };
|
|
345
|
+
static extract(filePath: string, targetDir: string): void;
|
|
275
346
|
}
|
|
276
347
|
```
|
|
277
348
|
|
|
278
|
-
###
|
|
279
|
-
|
|
280
|
-
See [src/types.ts](src/types.ts) for complete type definitions.
|
|
281
|
-
|
|
282
|
-
---
|
|
283
|
-
|
|
284
|
-
## Platform Integration
|
|
285
|
-
|
|
286
|
-
### For AI Platform Developers
|
|
287
|
-
|
|
288
|
-
Integrating VREF support:
|
|
349
|
+
### VREFReadResult
|
|
289
350
|
|
|
290
351
|
```typescript
|
|
291
|
-
|
|
352
|
+
interface VREFReadResult {
|
|
353
|
+
manifest: VREFManifest;
|
|
354
|
+
images?: Map<string, Buffer>;
|
|
355
|
+
sample: (count: number) => Buffer[];
|
|
356
|
+
getImage: (path: string) => Buffer | undefined;
|
|
357
|
+
}
|
|
358
|
+
```
|
|
292
359
|
|
|
293
|
-
|
|
294
|
-
const vref = VREFReader.read(uploadedFile, { loadImages: true });
|
|
360
|
+
Full API documentation: [TypeScript definitions](src/types.ts)
|
|
295
361
|
|
|
296
|
-
|
|
297
|
-
const userSelectedCount = getUserSliderValue(); // e.g., 3
|
|
362
|
+
---
|
|
298
363
|
|
|
299
|
-
|
|
300
|
-
const selectedImages = vref.sample(userSelectedCount);
|
|
364
|
+
## Roadmap
|
|
301
365
|
|
|
302
|
-
|
|
303
|
-
|
|
366
|
+
### Phase 1 ✅ (Done)
|
|
367
|
+
- Core library implementation
|
|
368
|
+
- CLI tool (`create`, `info`, `validate`, `extract`)
|
|
369
|
+
- Automated test coverage
|
|
370
|
+
- npm package published
|
|
371
|
+
- Full documentation
|
|
304
372
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
});
|
|
310
|
-
```
|
|
373
|
+
### Phase 2 (In Progress)
|
|
374
|
+
- Community-created .vref files
|
|
375
|
+
- Platform integrations
|
|
376
|
+
- Example collections
|
|
311
377
|
|
|
312
|
-
|
|
378
|
+
### Phase 3 (Future)
|
|
379
|
+
- Web-based .vref creator
|
|
380
|
+
- .vref marketplace
|
|
381
|
+
- Browser extensions
|
|
382
|
+
- Mobile support
|
|
313
383
|
|
|
314
384
|
---
|
|
315
385
|
|
|
316
|
-
##
|
|
386
|
+
## Join the Movement
|
|
317
387
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
-
|
|
321
|
-
-
|
|
322
|
-
-
|
|
388
|
+
VREF is just getting started. We need:
|
|
389
|
+
|
|
390
|
+
- **Platform developers**: Integrate VREF support
|
|
391
|
+
- **Creators**: Build and share .vref collections
|
|
392
|
+
- **Contributors**: Improve the library
|
|
393
|
+
- **Evangelists**: Spread the word
|
|
323
394
|
|
|
324
395
|
---
|
|
325
396
|
|
|
326
|
-
##
|
|
397
|
+
## Links
|
|
327
398
|
|
|
328
|
-
|
|
399
|
+
- **npm**: https://www.npmjs.com/package/@harpiaresearch/vref
|
|
400
|
+
- **GitHub**: https://github.com/Harpia-AI-Research/vref
|
|
401
|
+
- **Harpia AI Research**: https://harpiaresearch.cc
|
|
402
|
+
- **Issues**: https://github.com/Harpia-AI-Research/vref/issues
|
|
329
403
|
|
|
330
404
|
---
|
|
331
405
|
|
|
332
406
|
## License
|
|
333
407
|
|
|
334
|
-
BSD 3-Clause License
|
|
335
|
-
|
|
336
|
-
Copyright (c) 2024, Harpia AI Research
|
|
408
|
+
This project is licensed under the **BSD 3-Clause License** - see the [LICENSE](LICENSE) file for details.
|
|
337
409
|
|
|
338
|
-
|
|
410
|
+
Copyright (c) 2026, Harpia AI Research
|
|
339
411
|
|
|
340
412
|
---
|
|
341
413
|
|
|
342
|
-
##
|
|
414
|
+
## Acknowledgments
|
|
343
415
|
|
|
344
|
-
|
|
416
|
+
VREF is an open standard for visual references in AI systems. Built to solve the gap between what creators envision and what they can describe in text.
|
|
345
417
|
|
|
346
|
-
|
|
347
|
-
@software{vref2024,
|
|
348
|
-
title = {VREF: Visual Reference Format for AI Image Generation},
|
|
349
|
-
author = {Harpia AI Research},
|
|
350
|
-
year = {2024},
|
|
351
|
-
url = {https://github.com/Harpia-AI-Research/vref}
|
|
352
|
-
}
|
|
353
|
-
```
|
|
418
|
+
**Technologies**: TypeScript, Node.js, adm-zip
|
|
354
419
|
|
|
355
420
|
---
|
|
356
421
|
|
|
357
|
-
|
|
422
|
+
<div align="center">
|
|
358
423
|
|
|
359
|
-
|
|
360
|
-
- 📦 npm: [@harpiaresearch/vref](https://www.npmjs.com/package/@harpiaresearch/vref)
|
|
361
|
-
- 📄 Specification: [docs/SPECIFICATION.md](docs/SPECIFICATION.md)
|
|
362
|
-
- 💬 Issues: [GitHub Issues](https://github.com/Harpia-AI-Research/vref/issues)
|
|
424
|
+
**VREF** — Bridging vision and AI generation
|
|
363
425
|
|
|
364
|
-
|
|
426
|
+
<br><br>
|
|
427
|
+
|
|
428
|
+
[GitHub](https://github.com/Harpia-AI-Research/vref) •
|
|
429
|
+
[npm](https://www.npmjs.com/package/@harpiaresearch/vref) •
|
|
430
|
+
[Documentation](https://github.com/Harpia-AI-Research/vref#readme) •
|
|
431
|
+
[Issues](https://github.com/Harpia-AI-Research/vref/issues)
|
|
432
|
+
|
|
433
|
+
</div>
|
|
365
434
|
|
|
366
|
-
**Made with 💚💛 by Harpia AI Research — São Paulo, Brazil** 🇧🇷
|
package/dist/VREFReader.d.ts
CHANGED
package/dist/VREFReader.js
CHANGED
|
@@ -51,6 +51,12 @@ class VREFReader {
|
|
|
51
51
|
if (!fs.existsSync(filePath)) {
|
|
52
52
|
throw new Error(`File not found: ${filePath}`);
|
|
53
53
|
}
|
|
54
|
+
if (options.validate) {
|
|
55
|
+
const validation = VREFReader.validate(filePath);
|
|
56
|
+
if (!validation.valid) {
|
|
57
|
+
throw new Error(`Invalid .vref file: ${validation.errors.join(', ')}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
54
60
|
const zip = new adm_zip_1.default(filePath);
|
|
55
61
|
const zipEntries = zip.getEntries();
|
|
56
62
|
// Find and parse manifest
|
|
@@ -181,5 +187,18 @@ class VREFReader {
|
|
|
181
187
|
return { valid: false, errors };
|
|
182
188
|
}
|
|
183
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Extract all files from a .vref file to a target directory
|
|
192
|
+
*/
|
|
193
|
+
static extract(filePath, targetDir) {
|
|
194
|
+
if (!fs.existsSync(filePath)) {
|
|
195
|
+
throw new Error(`File not found: ${filePath}`);
|
|
196
|
+
}
|
|
197
|
+
if (!fs.existsSync(targetDir)) {
|
|
198
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
199
|
+
}
|
|
200
|
+
const zip = new adm_zip_1.default(filePath);
|
|
201
|
+
zip.extractAllTo(targetDir, true);
|
|
202
|
+
}
|
|
184
203
|
}
|
|
185
204
|
exports.VREFReader = VREFReader;
|
package/dist/VREFWriter.d.ts
CHANGED
package/dist/VREFWriter.js
CHANGED
|
@@ -125,13 +125,14 @@ class VREFWriter {
|
|
|
125
125
|
}
|
|
126
126
|
// Create manifest
|
|
127
127
|
const manifest = {
|
|
128
|
-
version: '1.0.
|
|
128
|
+
version: '1.0.2',
|
|
129
129
|
format: 'VREF',
|
|
130
|
-
fileName: path.basename(outputPath),
|
|
130
|
+
fileName: this.options.fileName || path.basename(outputPath),
|
|
131
131
|
imageCount: this.images.size,
|
|
132
132
|
images: imageMetadataList,
|
|
133
133
|
createdAt: new Date().toISOString(),
|
|
134
134
|
metadata: {
|
|
135
|
+
name: this.options.name,
|
|
135
136
|
description: this.options.description,
|
|
136
137
|
tags: this.options.tags,
|
|
137
138
|
author: this.options.author,
|
|
@@ -154,28 +155,56 @@ class VREFWriter {
|
|
|
154
155
|
* Validate image buffer by checking magic bytes
|
|
155
156
|
*/
|
|
156
157
|
isValidImageBuffer(buffer, format) {
|
|
157
|
-
if (buffer.length < 8)
|
|
158
|
+
if (!buffer || buffer.length < 8)
|
|
158
159
|
return false;
|
|
159
160
|
switch (format.toLowerCase()) {
|
|
160
161
|
case 'png':
|
|
161
|
-
return buffer
|
|
162
|
+
return (buffer.length >= 8 &&
|
|
163
|
+
buffer[0] === 0x89 &&
|
|
164
|
+
buffer[1] === 0x50 &&
|
|
165
|
+
buffer[2] === 0x4e &&
|
|
166
|
+
buffer[3] === 0x47);
|
|
162
167
|
case 'jpg':
|
|
163
168
|
case 'jpeg':
|
|
164
|
-
return buffer
|
|
169
|
+
return (buffer.length >= 3 &&
|
|
170
|
+
buffer[0] === 0xff &&
|
|
171
|
+
buffer[1] === 0xd8 &&
|
|
172
|
+
buffer[2] === 0xff);
|
|
165
173
|
case 'gif':
|
|
166
|
-
return buffer
|
|
174
|
+
return (buffer.length >= 6 &&
|
|
175
|
+
buffer[0] === 0x47 &&
|
|
176
|
+
buffer[1] === 0x49 &&
|
|
177
|
+
buffer[2] === 0x46 &&
|
|
178
|
+
buffer[3] === 0x38 &&
|
|
179
|
+
(buffer[4] === 0x37 || buffer[4] === 0x39) &&
|
|
180
|
+
buffer[5] === 0x61);
|
|
167
181
|
case 'webp':
|
|
168
|
-
return buffer
|
|
182
|
+
return (buffer.length >= 12 &&
|
|
183
|
+
buffer[0] === 0x52 &&
|
|
184
|
+
buffer[1] === 0x49 &&
|
|
185
|
+
buffer[2] === 0x46 &&
|
|
186
|
+
buffer[3] === 0x46 &&
|
|
187
|
+
buffer[8] === 0x57 &&
|
|
188
|
+
buffer[9] === 0x45 &&
|
|
189
|
+
buffer[10] === 0x42 &&
|
|
190
|
+
buffer[11] === 0x50);
|
|
169
191
|
case 'avif':
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
192
|
+
if (buffer.length < 16)
|
|
193
|
+
return false;
|
|
194
|
+
const ftypBox = buffer.toString('ascii', 4, 8);
|
|
195
|
+
if (ftypBox !== 'ftyp')
|
|
196
|
+
return false;
|
|
197
|
+
const majorBrand = buffer.toString('ascii', 8, 12);
|
|
198
|
+
if (majorBrand === 'avif' || majorBrand === 'avis')
|
|
199
|
+
return true;
|
|
200
|
+
const headerSlice = buffer.subarray(12, Math.min(buffer.length, 64)).toString('ascii');
|
|
201
|
+
return headerSlice.includes('avif') || headerSlice.includes('avis');
|
|
173
202
|
default:
|
|
174
203
|
return false;
|
|
175
204
|
}
|
|
176
205
|
}
|
|
177
206
|
/**
|
|
178
|
-
* Get image dimensions (
|
|
207
|
+
* Get image dimensions (supports PNG, JPEG, GIF, WebP)
|
|
179
208
|
*/
|
|
180
209
|
getImageDimensions(buffer, format) {
|
|
181
210
|
try {
|
|
@@ -185,8 +214,6 @@ class VREFWriter {
|
|
|
185
214
|
return { width, height };
|
|
186
215
|
}
|
|
187
216
|
if ((format === 'jpg' || format === 'jpeg') && buffer.length >= 4) {
|
|
188
|
-
// Basic JPEG dimension extraction (simplified)
|
|
189
|
-
// This is a simplified version; production code might use a library
|
|
190
217
|
let offset = 2;
|
|
191
218
|
while (offset < buffer.length) {
|
|
192
219
|
if (buffer[offset] !== 0xff)
|
|
@@ -202,6 +229,33 @@ class VREFWriter {
|
|
|
202
229
|
offset += segmentLength;
|
|
203
230
|
}
|
|
204
231
|
}
|
|
232
|
+
if (format === 'gif' && buffer.length >= 10) {
|
|
233
|
+
const width = buffer.readUInt16LE(6);
|
|
234
|
+
const height = buffer.readUInt16LE(8);
|
|
235
|
+
return { width, height };
|
|
236
|
+
}
|
|
237
|
+
if (format === 'webp' && buffer.length >= 30) {
|
|
238
|
+
const chunkType = buffer.toString('ascii', 12, 16);
|
|
239
|
+
if (chunkType === 'VP8 ' && buffer.length >= 30) {
|
|
240
|
+
const width = buffer.readUInt16LE(26) & 0x3fff;
|
|
241
|
+
const height = buffer.readUInt16LE(28) & 0x3fff;
|
|
242
|
+
return { width, height };
|
|
243
|
+
}
|
|
244
|
+
else if (chunkType === 'VP8L' && buffer.length >= 25) {
|
|
245
|
+
const b1 = buffer[21];
|
|
246
|
+
const b2 = buffer[22];
|
|
247
|
+
const b3 = buffer[23];
|
|
248
|
+
const b4 = buffer[24];
|
|
249
|
+
const width = 1 + (((b2 & 0x3f) << 8) | b1);
|
|
250
|
+
const height = 1 + (((b4 & 0x0f) << 10) | (b3 << 2) | ((b2 & 0xc0) >> 6));
|
|
251
|
+
return { width, height };
|
|
252
|
+
}
|
|
253
|
+
else if (chunkType === 'VP8X' && buffer.length >= 30) {
|
|
254
|
+
const width = 1 + buffer.readUIntLE(24, 3);
|
|
255
|
+
const height = 1 + buffer.readUIntLE(27, 3);
|
|
256
|
+
return { width, height };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
205
259
|
}
|
|
206
260
|
catch (error) {
|
|
207
261
|
// If dimension extraction fails, just return undefined
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
/**
|
|
4
|
-
* VREF CLI - Command line interface for
|
|
4
|
+
* VREF CLI - Command line interface for .vref files
|
|
5
5
|
* Harpia AI Research
|
|
6
6
|
*/
|
|
7
7
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -41,47 +41,144 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
43
|
const VREFWriter_1 = require("./VREFWriter");
|
|
44
|
+
const VREFReader_1 = require("./VREFReader");
|
|
45
|
+
const CLI_VERSION = '1.0.2';
|
|
44
46
|
function showHelp() {
|
|
45
47
|
console.log(`
|
|
46
48
|
┌─────────────────────────────────────────────────┐
|
|
47
|
-
│ VREF CLI
|
|
49
|
+
│ VREF CLI v${CLI_VERSION} │
|
|
48
50
|
│ by Harpia AI Research │
|
|
49
51
|
│ https://harpiaresearch.cc │
|
|
50
52
|
└─────────────────────────────────────────────────┘
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
Standardized container for curated visual references in AI image generation
|
|
53
55
|
|
|
54
56
|
USAGE:
|
|
55
|
-
npx
|
|
56
|
-
|
|
57
|
-
ARGUMENTS:
|
|
58
|
-
<input> Path to image file or directory
|
|
57
|
+
npx @harpiaresearch/vref <input> [options]
|
|
58
|
+
vref <command> [arguments]
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
60
|
+
COMMANDS:
|
|
61
|
+
<input> [options] Create a .vref file from an image or directory
|
|
62
|
+
info, inspect <file.vref> Inspect metadata and images in a .vref file
|
|
63
|
+
validate <file.vref> Validate integrity and manifest of a .vref file
|
|
64
|
+
extract <file.vref> [dir] Extract all images from a .vref file
|
|
65
|
+
|
|
66
|
+
CREATION OPTIONS:
|
|
67
|
+
-o, --output <path> Output .vref file path (default: output.vref)
|
|
68
|
+
-n, --name <name> Name/title for the reference pack
|
|
69
|
+
-d, --desc <text> Description of the reference pack
|
|
70
|
+
-t, --tags <tags> Comma-separated tags
|
|
71
|
+
-a, --author <name> Author name
|
|
72
|
+
-l, --license <lic> License (e.g., CC-BY-4.0, MIT)
|
|
73
|
+
-r, --recursive Include subdirectories
|
|
74
|
+
-v, --version Show CLI version
|
|
75
|
+
-h, --help Show this help
|
|
69
76
|
|
|
70
77
|
EXAMPLES:
|
|
71
|
-
# Create from single image
|
|
72
|
-
npx create-vref image.png -o references.vref
|
|
73
|
-
|
|
74
78
|
# Create from directory
|
|
75
|
-
npx
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
npx
|
|
79
|
+
npx @harpiaresearch/vref ./images -o pack.vref -n "My Pack"
|
|
80
|
+
|
|
81
|
+
# Create with complete metadata
|
|
82
|
+
npx @harpiaresearch/vref ./sprites -o rpg-sprites.vref \\
|
|
79
83
|
-n "RPG Sprites" \\
|
|
80
84
|
-d "Character sprites for RPG games" \\
|
|
81
85
|
-t "rpg,sprites,pixelart" \\
|
|
82
86
|
-a "Your Name" \\
|
|
83
87
|
-l "CC-BY-4.0"
|
|
84
|
-
|
|
88
|
+
|
|
89
|
+
# Inspect an existing .vref file
|
|
90
|
+
vref info references.vref
|
|
91
|
+
|
|
92
|
+
# Validate file integrity
|
|
93
|
+
vref validate references.vref
|
|
94
|
+
|
|
95
|
+
# Extract images
|
|
96
|
+
vref extract references.vref ./extracted-images
|
|
97
|
+
`);
|
|
98
|
+
}
|
|
99
|
+
function handleValidate(filePath) {
|
|
100
|
+
if (!filePath) {
|
|
101
|
+
console.error('❌ Error: Please specify a .vref file to validate');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
console.log(`🔍 Validating ${filePath}...`);
|
|
105
|
+
const result = VREFReader_1.VREFReader.validate(filePath);
|
|
106
|
+
if (result.valid) {
|
|
107
|
+
const manifest = VREFReader_1.VREFReader.readManifest(filePath);
|
|
108
|
+
console.log(`✅ Valid .vref file!`);
|
|
109
|
+
console.log(` Format: ${manifest.format} (v${manifest.version})`);
|
|
110
|
+
console.log(` Images: ${manifest.imageCount}`);
|
|
111
|
+
if (manifest.metadata?.name)
|
|
112
|
+
console.log(` Name: ${manifest.metadata.name}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.error(`❌ Validation failed with ${result.errors.length} error(s):`);
|
|
116
|
+
result.errors.forEach(err => console.error(` - ${err}`));
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function handleInfo(filePath) {
|
|
121
|
+
if (!filePath) {
|
|
122
|
+
console.error('❌ Error: Please specify a .vref file to inspect');
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const manifest = VREFReader_1.VREFReader.readManifest(filePath);
|
|
127
|
+
const stats = fs.statSync(filePath);
|
|
128
|
+
const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
|
|
129
|
+
console.log(`\n📦 File: ${path.basename(filePath)} (${sizeMB} MB)`);
|
|
130
|
+
console.log(` Format: ${manifest.format} v${manifest.version}`);
|
|
131
|
+
console.log(` Created at: ${manifest.createdAt}`);
|
|
132
|
+
console.log(` Total images: ${manifest.imageCount}`);
|
|
133
|
+
if (manifest.metadata) {
|
|
134
|
+
console.log('\n📋 Metadata:');
|
|
135
|
+
if (manifest.metadata.name)
|
|
136
|
+
console.log(` Name: ${manifest.metadata.name}`);
|
|
137
|
+
if (manifest.metadata.description)
|
|
138
|
+
console.log(` Description: ${manifest.metadata.description}`);
|
|
139
|
+
if (manifest.metadata.tags && manifest.metadata.tags.length > 0) {
|
|
140
|
+
console.log(` Tags: ${manifest.metadata.tags.join(', ')}`);
|
|
141
|
+
}
|
|
142
|
+
if (manifest.metadata.author)
|
|
143
|
+
console.log(` Author: ${manifest.metadata.author}`);
|
|
144
|
+
if (manifest.metadata.license)
|
|
145
|
+
console.log(` License: ${manifest.metadata.license}`);
|
|
146
|
+
}
|
|
147
|
+
if (manifest.images.length > 0) {
|
|
148
|
+
console.log('\n🖼️ Sample of contained images:');
|
|
149
|
+
const previewCount = Math.min(manifest.images.length, 5);
|
|
150
|
+
for (let i = 0; i < previewCount; i++) {
|
|
151
|
+
const img = manifest.images[i];
|
|
152
|
+
const dim = img.width && img.height ? ` (${img.width}x${img.height})` : '';
|
|
153
|
+
const sizeKB = (img.size / 1024).toFixed(1);
|
|
154
|
+
console.log(` - ${img.path} [${img.format.toUpperCase()}]${dim} - ${sizeKB} KB`);
|
|
155
|
+
}
|
|
156
|
+
if (manifest.images.length > previewCount) {
|
|
157
|
+
console.log(` ... and ${manifest.images.length - previewCount} more`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
console.log();
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error(`❌ Error inspecting file: ${error.message}`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function handleExtract(filePath, outputDir) {
|
|
168
|
+
if (!filePath) {
|
|
169
|
+
console.error('❌ Error: Please specify a .vref file to extract');
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
const targetDir = outputDir || path.join(process.cwd(), path.basename(filePath, '.vref') + '_extracted');
|
|
173
|
+
try {
|
|
174
|
+
console.log(`📦 Extracting ${filePath} to ${targetDir}...`);
|
|
175
|
+
VREFReader_1.VREFReader.extract(filePath, targetDir);
|
|
176
|
+
console.log(`✅ Extracted successfully to ${targetDir}`);
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
console.error(`❌ Extraction error: ${error.message}`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
85
182
|
}
|
|
86
183
|
function parseArgs(args) {
|
|
87
184
|
const options = {
|
|
@@ -102,6 +199,11 @@ function parseArgs(args) {
|
|
|
102
199
|
showHelp();
|
|
103
200
|
process.exit(0);
|
|
104
201
|
break;
|
|
202
|
+
case '-v':
|
|
203
|
+
case '--version':
|
|
204
|
+
console.log(`v${CLI_VERSION}`);
|
|
205
|
+
process.exit(0);
|
|
206
|
+
break;
|
|
105
207
|
case '-o':
|
|
106
208
|
case '--output':
|
|
107
209
|
options.output = args[++i];
|
|
@@ -117,7 +219,7 @@ function parseArgs(args) {
|
|
|
117
219
|
break;
|
|
118
220
|
case '-t':
|
|
119
221
|
case '--tags':
|
|
120
|
-
options.tags = args[++i]
|
|
222
|
+
options.tags = args[++i]?.split(',').map((t) => t.trim());
|
|
121
223
|
break;
|
|
122
224
|
case '-a':
|
|
123
225
|
case '--author':
|
|
@@ -132,7 +234,7 @@ function parseArgs(args) {
|
|
|
132
234
|
options.recursive = true;
|
|
133
235
|
break;
|
|
134
236
|
default:
|
|
135
|
-
if (!arg.startsWith('-')) {
|
|
237
|
+
if (!arg.startsWith('-') && !options.input) {
|
|
136
238
|
options.input = arg;
|
|
137
239
|
}
|
|
138
240
|
break;
|
|
@@ -146,10 +248,31 @@ function main() {
|
|
|
146
248
|
showHelp();
|
|
147
249
|
process.exit(0);
|
|
148
250
|
}
|
|
251
|
+
const firstArg = args[0];
|
|
252
|
+
if (firstArg === 'validate') {
|
|
253
|
+
handleValidate(args[1]);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (firstArg === 'info' || firstArg === 'inspect') {
|
|
257
|
+
handleInfo(args[1]);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (firstArg === 'extract') {
|
|
261
|
+
handleExtract(args[1], args[2]);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (firstArg === '-h' || firstArg === '--help') {
|
|
265
|
+
showHelp();
|
|
266
|
+
process.exit(0);
|
|
267
|
+
}
|
|
268
|
+
if (firstArg === '-v' || firstArg === '--version') {
|
|
269
|
+
console.log(`v${CLI_VERSION}`);
|
|
270
|
+
process.exit(0);
|
|
271
|
+
}
|
|
149
272
|
const options = parseArgs(args);
|
|
150
273
|
if (!options.input) {
|
|
151
274
|
console.error('❌ Error: No input specified');
|
|
152
|
-
console.log('Run "npx
|
|
275
|
+
console.log('Run "npx @harpiaresearch/vref --help" for usage information');
|
|
153
276
|
process.exit(1);
|
|
154
277
|
}
|
|
155
278
|
if (!fs.existsSync(options.input)) {
|
|
@@ -157,13 +280,13 @@ function main() {
|
|
|
157
280
|
process.exit(1);
|
|
158
281
|
}
|
|
159
282
|
console.log('┌─────────────────────────────────────────────────┐');
|
|
160
|
-
console.log(
|
|
283
|
+
console.log(`│ VREF CLI v${CLI_VERSION} │`);
|
|
161
284
|
console.log('│ by Harpia AI Research │');
|
|
162
285
|
console.log('└─────────────────────────────────────────────────┘\n');
|
|
163
286
|
try {
|
|
164
|
-
const fileName = options.name || path.basename(options.output, '.vref');
|
|
165
287
|
const writer = new VREFWriter_1.VREFWriter({
|
|
166
|
-
fileName: options.output,
|
|
288
|
+
fileName: path.basename(options.output),
|
|
289
|
+
name: options.name,
|
|
167
290
|
description: options.description,
|
|
168
291
|
tags: options.tags,
|
|
169
292
|
author: options.author,
|
package/dist/types.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface VREFManifest {
|
|
|
23
23
|
createdAt: string;
|
|
24
24
|
/** Optional metadata */
|
|
25
25
|
metadata?: {
|
|
26
|
+
/** Human-readable title/name of the reference pack */
|
|
27
|
+
name?: string;
|
|
26
28
|
/** Description of the reference pack */
|
|
27
29
|
description?: string;
|
|
28
30
|
/** Tags for categorization */
|
|
@@ -54,8 +56,10 @@ export interface ImageMetadata {
|
|
|
54
56
|
* Options for creating a VREF file
|
|
55
57
|
*/
|
|
56
58
|
export interface VREFCreateOptions {
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
+
/** Optional name/title for the reference pack */
|
|
60
|
+
name?: string;
|
|
61
|
+
/** Name for the output .vref file (optional, defaults to output path file name) */
|
|
62
|
+
fileName?: string;
|
|
59
63
|
/** Optional description */
|
|
60
64
|
description?: string;
|
|
61
65
|
/** Optional tags */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harpiaresearch/vref",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Visual Reference Format - Standardized container for curated visual references in AI image generation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"LICENSE"
|
|
11
11
|
],
|
|
12
12
|
"bin": {
|
|
13
|
-
"create-vref": "
|
|
14
|
-
"vref": "
|
|
13
|
+
"create-vref": "dist/cli.js",
|
|
14
|
+
"vref": "dist/cli.js"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "tsc",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/Harpia-AI-Research/vref"
|
|
35
|
+
"url": "git+https://github.com/Harpia-AI-Research/vref.git"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"adm-zip": "^0.5.10"
|