variantkit 0.1.0

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.
@@ -0,0 +1,55 @@
1
+ // VariantKit vite plugin — dev-only decision transport. The panel's finalize button
2
+ // POSTs the decision here; we write it to .variantkit/decisions/<Component>.json and
3
+ // append a line to .variantkit/history/log.jsonl. The agent applies pending decisions
4
+ // per AGENT.md §4. Add to vite.config:
5
+ //
6
+ // import variantkit from './variantkit/vite-plugin.mjs' // or src/variantkit/...
7
+ // export default defineConfig({ plugins: [react(), variantkit()] })
8
+
9
+ import { mkdirSync, writeFileSync, appendFileSync } from 'node:fs'
10
+ import { join } from 'node:path'
11
+
12
+ const NAME_OK = /^[A-Za-z0-9_-]+$/
13
+
14
+ export default function variantkit() {
15
+ return {
16
+ name: 'variantkit',
17
+ apply: 'serve', // dev server only — never part of a production build
18
+ configureServer(server) {
19
+ server.middlewares.use('/__variantkit/decision', (req, res) => {
20
+ if (req.method !== 'POST') {
21
+ res.statusCode = 405
22
+ res.end('method not allowed')
23
+ return
24
+ }
25
+ let body = ''
26
+ req.on('data', (chunk) => (body += chunk))
27
+ req.on('end', () => {
28
+ try {
29
+ const decision = JSON.parse(body)
30
+ const component = String(decision.component ?? '')
31
+ if (!NAME_OK.test(component)) {
32
+ res.statusCode = 400
33
+ res.end('invalid component name')
34
+ return
35
+ }
36
+ const root = server.config.root ?? process.cwd()
37
+ const dir = join(root, '.variantkit', 'decisions')
38
+ const historyDir = join(root, '.variantkit', 'history')
39
+ mkdirSync(dir, { recursive: true })
40
+ mkdirSync(historyDir, { recursive: true })
41
+ writeFileSync(join(dir, `${component}.json`), JSON.stringify(decision, null, 2) + '\n')
42
+ appendFileSync(join(historyDir, 'log.jsonl'), JSON.stringify(decision) + '\n')
43
+ console.log(`[variantkit] decision saved: .variantkit/decisions/${component}.json`)
44
+ res.statusCode = 200
45
+ res.setHeader('content-type', 'application/json')
46
+ res.end('{"ok":true}')
47
+ } catch (e) {
48
+ res.statusCode = 400
49
+ res.end(`bad decision payload: ${e.message}`)
50
+ }
51
+ })
52
+ })
53
+ },
54
+ }
55
+ }