brand-intent 0.1.6 → 0.1.8
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/cli/index.mjs +49 -1
- package/package.json +1 -1
- package/skills/brand-intent.md +12 -26
package/cli/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
|
|
4
4
|
import { join, dirname, resolve } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { createInterface } from 'readline';
|
|
@@ -44,6 +44,45 @@ function ask(q) {
|
|
|
44
44
|
return new Promise((res) => rl().question(q, res));
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// ── File operations ──
|
|
48
|
+
|
|
49
|
+
function copyDirRecursive(src, dest) {
|
|
50
|
+
mkdirSync(dest, { recursive: true });
|
|
51
|
+
for (const entry of readdirSync(src)) {
|
|
52
|
+
const srcPath = join(src, entry);
|
|
53
|
+
const destPath = join(dest, entry);
|
|
54
|
+
if (statSync(srcPath).isDirectory()) {
|
|
55
|
+
copyDirRecursive(srcPath, destPath);
|
|
56
|
+
} else {
|
|
57
|
+
copyFileSync(srcPath, destPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function scaffoldExample(targetDir) {
|
|
63
|
+
const brandSrc = join(PKG_ROOT, 'brands', 'krume');
|
|
64
|
+
const exampleDest = join(targetDir, 'examples', 'krume');
|
|
65
|
+
|
|
66
|
+
copyDirRecursive(brandSrc, exampleDest);
|
|
67
|
+
|
|
68
|
+
const layers = [
|
|
69
|
+
{ layer: 'formats', file: 'instagram-4-5-feed-portrait.format' },
|
|
70
|
+
{ layer: 'purposes', file: 'daily-bread.purpose' },
|
|
71
|
+
{ layer: 'compositions', file: 'editorial.composition' },
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
for (const { layer, file } of layers) {
|
|
75
|
+
const src = join(PKG_ROOT, layer, file);
|
|
76
|
+
if (existsSync(src)) {
|
|
77
|
+
const dest = join(exampleDest, layer, file);
|
|
78
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
79
|
+
copyFileSync(src, dest);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.log(' \u2713 examples/krume/ \u2014 reference implementation (identity, brand, format, purpose, composition)');
|
|
84
|
+
}
|
|
85
|
+
|
|
47
86
|
// ── Install skill ──
|
|
48
87
|
|
|
49
88
|
async function installSkills(cwd) {
|
|
@@ -114,8 +153,17 @@ const targetDir = resolve(cwd, folder.trim() || '.');
|
|
|
114
153
|
if (targetDir !== cwd) {
|
|
115
154
|
mkdirSync(targetDir, { recursive: true });
|
|
116
155
|
}
|
|
156
|
+
console.log('\n This will:');
|
|
157
|
+
console.log(' \u2014 Copy the Krume bakery reference into examples/krume/');
|
|
158
|
+
console.log(' \u2014 Install the Brand Intent skill for your AI agent\n');
|
|
159
|
+
const proceed = await ask(' Proceed? (Y/n) ');
|
|
160
|
+
if (proceed.trim().toLowerCase() === 'n') {
|
|
161
|
+
closeRl();
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
117
164
|
console.log('');
|
|
118
165
|
|
|
166
|
+
scaffoldExample(targetDir);
|
|
119
167
|
await installSkills(targetDir);
|
|
120
168
|
closeRl();
|
|
121
169
|
|
package/package.json
CHANGED
package/skills/brand-intent.md
CHANGED
|
@@ -216,30 +216,16 @@ Once confirmed, generate these files at the project root:
|
|
|
216
216
|
- **Typography sizes use `cqmin` units.** Use these sensible defaults unless the user specified otherwise: headline 6, body 2.8, caption 2.2, label 2.
|
|
217
217
|
- **Spacing defaults:** unit cqmin, xs 1.5, s 2, m 3, l 5, xl 6.5.
|
|
218
218
|
|
|
219
|
-
## Example:
|
|
220
|
-
|
|
221
|
-
When `$ARGUMENTS` is "example",
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const dest = 'examples/krume';
|
|
231
|
-
mkdirSync(dest, { recursive: true });
|
|
232
|
-
for (const d of ['brands/krume', 'formats', 'purposes', 'compositions']) {
|
|
233
|
-
const src = require('path').join(root, d);
|
|
234
|
-
try { cpSync(src, require('path').join(dest, d.replace('brands/krume', '')), { recursive: true }); } catch {}
|
|
235
|
-
}
|
|
236
|
-
console.log('Krume example scaffolded into examples/krume/');
|
|
237
|
-
"
|
|
238
|
-
```
|
|
219
|
+
## Example: Explore the Krume Reference
|
|
220
|
+
|
|
221
|
+
When `$ARGUMENTS` is "example", the Krume bakery reference is already in `examples/krume/` (copied there by `npx brand-intent init`).
|
|
222
|
+
|
|
223
|
+
Read the files and walk the user through them:
|
|
224
|
+
|
|
225
|
+
- **`krume.identity`** — the strategic layer: essence, voice, values, audiences. Start here.
|
|
226
|
+
- **`krume.brand`** — derived expression: colors, themes, typography, spacing. Every decision traces back to identity.
|
|
227
|
+
- **`formats/`** — canvas dimensions, safe zones, grid. Where content appears.
|
|
228
|
+
- **`purposes/`** — content type with semantic slots, samples, constraints. What content does.
|
|
229
|
+
- **`compositions/`** — spatial arrangement of slots. How elements are placed.
|
|
239
230
|
|
|
240
|
-
|
|
241
|
-
- **`.identity`** — the strategic layer: essence, voice, values, audiences. Read this first.
|
|
242
|
-
- **`.brand`** — derived expression: colors, themes, typography, spacing. Every decision traces back to identity.
|
|
243
|
-
- **`.format`** — canvas dimensions, safe zones, grid. Where content appears.
|
|
244
|
-
- **`.purpose`** — content type with semantic slots, samples, constraints. What content does.
|
|
245
|
-
- **`.composition`** — spatial arrangement of slots. How elements are placed.
|
|
231
|
+
If `examples/krume/` doesn't exist, tell the user to run `npx brand-intent init` first.
|