cyberui-2045 1.3.3 → 2.0.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.
Files changed (37) hide show
  1. package/AGENT.md +85 -79
  2. package/LICENSE +21 -21
  3. package/README.md +160 -72
  4. package/bin/init.js +178 -0
  5. package/bin/usage-content.js +120 -0
  6. package/dist/components/Badge.d.ts +17 -0
  7. package/dist/components/Button.d.ts +14 -0
  8. package/dist/components/Card.d.ts +16 -0
  9. package/dist/components/Checkbox.d.ts +48 -0
  10. package/dist/components/CircularProgress.d.ts +11 -0
  11. package/dist/components/Divider.d.ts +43 -0
  12. package/dist/components/GradientText.d.ts +47 -0
  13. package/dist/components/Input.d.ts +22 -0
  14. package/dist/components/LinearProgress.d.ts +13 -0
  15. package/dist/components/Modal.d.ts +13 -0
  16. package/dist/components/Notification.d.ts +13 -0
  17. package/dist/components/SectionTitle.d.ts +41 -0
  18. package/dist/components/SegmentedProgress.d.ts +10 -0
  19. package/dist/components/Select.d.ts +22 -0
  20. package/dist/components/Skeleton.d.ts +12 -0
  21. package/dist/components/Steps.d.ts +75 -0
  22. package/dist/components/TabNavigation.d.ts +21 -0
  23. package/dist/components/Timeline.d.ts +70 -0
  24. package/dist/components/Toggle.d.ts +14 -0
  25. package/dist/components/index.d.ts +13 -4
  26. package/dist/contexts/NotificationContext.d.ts +9 -0
  27. package/dist/cyberui-2045.css +1 -1
  28. package/dist/hooks/useCyberScrollbar.d.ts +12 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.es.js +5021 -5191
  31. package/dist/index.js +35 -35
  32. package/dist/utils/cn.d.ts +10 -0
  33. package/package.json +118 -104
  34. package/dist/components/tabs/ElementsTab.d.ts +0 -3
  35. package/dist/components/tabs/FeedbackTab.d.ts +0 -3
  36. package/dist/components/tabs/HomeTab.d.ts +0 -3
  37. package/dist/components/tabs/InteractiveTab.d.ts +0 -3
package/AGENT.md CHANGED
@@ -1,79 +1,85 @@
1
- # CyberUI 2045 - Agent Guide
2
-
3
- You are an expert frontend developer building a futuristic, cyberpunk-themed application using the `cyberui-2045` library.
4
-
5
- ## 1. Setup & Installation
6
-
7
- **Install the package:**
8
- ```bash
9
- npm install cyberui-2045
10
- ```
11
-
12
- **Import the styles (CRITICAL):**
13
- Add this to your root entry file (e.g., `main.tsx`, `App.tsx`):
14
- ```tsx
15
- import "cyberui-2045/styles.css";
16
- ```
17
-
18
- ## 2. Vibe Coding Principles (Consumer Edition)
19
-
20
- * **Dark Mode Only**: CyberUI is designed for dark backgrounds. Always set your page background to a dark color (e.g., `bg-slate-900`, `#050505`).
21
- * **Use the Library**: Do not build custom UI components if a CyberUI component exists.
22
- * **Neon Pop**: Use the library's built-in glow effects. Don't override them with flat colors unless necessary.
23
- * **Responsive**: Use the `ResponsiveValue` prop pattern for mobile-first designs.
24
-
25
- ## 3. Component Reference
26
-
27
- | Component | Description |
28
- | :--- | :--- |
29
- | `Button` | Neon-styled button. Variants: `primary`, `secondary`, `danger`, `ghost`. |
30
- | `Card` | Glassmorphism container with borders. |
31
- | `Input` | Cyberpunk text input with focus glows. |
32
- | `Modal` | CRT-style modal dialog. |
33
- | `Notification` | Toast notifications. Use `useCyberNotifications` hook. |
34
- | `CircularProgress` | Dual-ring progress indicator. |
35
- | `TabNavigation` | Animated tab bar. |
36
- | `Badge` | Status indicator. Variants: `default`, `success`, `warning`, `danger`. |
37
- | `Toggle` | Cyberpunk switch. |
38
- | `Select` | Styled dropdown. |
39
- | `Skeleton` | Loading placeholder. |
40
- | `Image` | Image with cyberpunk frame/effects. |
41
- | `Carousel` | Image carousel. |
42
-
43
- ## 4. Usage Patterns (Few-Shot)
44
-
45
- ### Basic Card with Action
46
- ```tsx
47
- import { Card, Button, Badge } from "cyberui-2045";
48
-
49
- export const UserProfile = () => (
50
- <Card variant="default" className="max-w-md">
51
- <div className="flex justify-between items-center mb-4">
52
- <h2 className="text-xl text-cyan-400 font-bold">Operative Status</h2>
53
- <Badge variant="success">ONLINE</Badge>
54
- </div>
55
- <p className="text-gray-300 mb-6">System synchronization at 98%.</p>
56
- <Button variant="primary" onClick={() => console.log("Syncing...")}>
57
- INITIATE SYNC
58
- </Button>
59
- </Card>
60
- );
61
- ```
62
-
63
- ### Responsive Layout
64
- ```tsx
65
- import { Button } from "cyberui-2045";
66
-
67
- // Resize button based on screen width
68
- <Button
69
- size={{ base: 'sm', md: 'md', lg: 'lg' }}
70
- variant="secondary"
71
- >
72
- Responsive Action
73
- </Button>
74
- ```
75
-
76
- ## 5. Troubleshooting
77
-
78
- * **Missing Styles?** Ensure `import "cyberui-2045/styles.css"` is present.
79
- * **Text Invisible?** Check if you are on a white background. Switch to dark mode.
1
+ # CyberUI 2045 - Agent Guide
2
+
3
+ You are an expert frontend developer building a futuristic, cyberpunk-themed application using the `cyberui-2045` library.
4
+
5
+ ## 1. Setup & Installation
6
+
7
+ **Install the package:**
8
+ ```bash
9
+ npm install cyberui-2045
10
+ ```
11
+
12
+ **Import the styles (CRITICAL):**
13
+ Add this to your root entry file (e.g., `main.tsx`, `App.tsx`):
14
+ ```tsx
15
+ import "cyberui-2045/styles.css";
16
+ ```
17
+
18
+ ## 2. Vibe Coding Principles (Consumer Edition)
19
+
20
+ * **Dark Mode Only**: CyberUI is designed for dark backgrounds. Always set your page background to a dark color (e.g., `bg-slate-900`, `#050505`).
21
+ * **Use the Library**: Do not build custom UI components if a CyberUI component exists.
22
+ * **Neon Pop**: Use the library's built-in glow effects. Don't override them with flat colors unless necessary.
23
+ * **Responsive**: Use the `ResponsiveValue` prop pattern for mobile-first designs.
24
+
25
+ ## 3. Component Reference
26
+
27
+ | Component | Description |
28
+ | :--- | :--- |
29
+ | `Button` | Neon-styled button. Variants: `primary`, `secondary`, `danger`, `ghost`. |
30
+ | `Card` | Glassmorphism container with borders. |
31
+ | `Input` | Cyberpunk text input with focus glows. |
32
+ | `Modal` | CRT-style modal dialog. |
33
+ | `Notification` | Toast notifications. Use `useCyberNotifications` hook. |
34
+ | `CircularProgress` | Dual-ring progress indicator. |
35
+ | `TabNavigation` | Animated tab bar. |
36
+ | `Badge` | Status indicator. Variants: `default`, `success`, `warning`, `danger`. |
37
+ | `Toggle` | Cyberpunk switch. |
38
+ | `Select` | Styled dropdown. |
39
+ | `Skeleton` | Loading placeholder. |
40
+ | `Image` | Image with cyberpunk frame/effects. |
41
+ | `Carousel` | Image carousel. |
42
+ | `Checkbox` | Neon-styled checkbox with SVG icons. |
43
+ | `Divider` | Gradient/solid/dashed content separator. |
44
+ | `GradientText` | Text with cyberpunk gradient effects. |
45
+ | `SectionTitle` | Title with decorative gradient line. |
46
+ | `Steps` | Multi-step progress indicator. |
47
+ | `Timeline` | Vertical event history display. |
48
+
49
+ ## 4. Usage Patterns (Few-Shot)
50
+
51
+ ### Basic Card with Action
52
+ ```tsx
53
+ import { Card, Button, Badge } from "cyberui-2045";
54
+
55
+ export const UserProfile = () => (
56
+ <Card variant="default" className="max-w-md">
57
+ <div className="flex justify-between items-center mb-4">
58
+ <h2 className="text-xl text-cyan-400 font-bold">Operative Status</h2>
59
+ <Badge variant="success">ONLINE</Badge>
60
+ </div>
61
+ <p className="text-gray-300 mb-6">System synchronization at 98%.</p>
62
+ <Button variant="primary" onClick={() => console.log("Syncing...")}>
63
+ INITIATE SYNC
64
+ </Button>
65
+ </Card>
66
+ );
67
+ ```
68
+
69
+ ### Responsive Layout
70
+ ```tsx
71
+ import { Button } from "cyberui-2045";
72
+
73
+ // Resize button based on screen width
74
+ <Button
75
+ size={{ base: 'sm', md: 'md', lg: 'lg' }}
76
+ variant="secondary"
77
+ >
78
+ Responsive Action
79
+ </Button>
80
+ ```
81
+
82
+ ## 5. Troubleshooting
83
+
84
+ * **Missing Styles?** Ensure `import "cyberui-2045/styles.css"` is present.
85
+ * **Text Invisible?** Check if you are on a white background. Switch to dark mode.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Patrick Yang
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Patrick Yang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,72 +1,160 @@
1
- # CyberUI
2
-
3
- A cyberpunk-themed React UI library with neon-styled components and futuristic aesthetics.
4
-
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
-
7
- ## 🌐 Demo & Documentation
8
-
9
- <details>
10
- <summary>Check out the Demo Video 🎬</summary>
11
- <video src="https://github.com/user-attachments/assets/00d3de8d-d243-4ae0-80c4-e6b97b71c0f0">
12
- </video>
13
- </details>
14
-
15
- - 🔗 **[Live Demo](https://patrickkuei.github.io/CyberUI)** - Experience the cyberpunk theme in action
16
- - 📚 **[Storybook Documentation](https://patrickkuei.github.io/CyberUI/storybook)** - Interactive component documentation
17
-
18
- ## 🚀 Quick Start
19
-
20
- ```bash
21
- npm install cyberui-2045
22
- ```
23
-
24
- Import the core stylesheet and components
25
-
26
- ```tsx
27
- import React from "react";
28
- import "cyberui-2045/styles.css";
29
- import { CircularProgress, Notification } from "cyberui-2045";
30
-
31
- function App() {
32
- return (
33
- <div>
34
- <CircularProgress progress={75} radius={20}>
35
- <span>75%</span>
36
- </CircularProgress>
37
-
38
- <Notification
39
- type="success"
40
- title="System Online"
41
- message="All systems are operational"
42
- />
43
- </div>
44
- );
45
- }
46
- ```
47
-
48
- ## Changelog
49
-
50
- See the full history in [CHANGELOG.md](./CHANGELOG.md).
51
-
52
- ## 🛠️ Development
53
-
54
- ```bash
55
- git clone https://github.com/patrickkuei/CyberUI.git
56
- cd CyberUI
57
- npm install
58
- npm run dev # Start development server
59
- npm run storybook # Start Storybook
60
- ```
61
-
62
- ## 🤝 Contributing
63
-
64
- Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md).
65
-
66
- ## 📄 License
67
-
68
- MIT License - see [LICENSE](LICENSE) file for details.
69
-
70
- ---
71
-
72
- Made with ⚡ by [Patrick Yang](https://github.com/patrickkuei)
1
+ # CyberUI
2
+
3
+ A cyberpunk-themed React UI library with neon-styled components and futuristic aesthetics.
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ ## Demo & Documentation
8
+
9
+ <details>
10
+ <summary>Check out the Demo Video 🎬</summary>
11
+ <video src="https://github.com/user-attachments/assets/00d3de8d-d243-4ae0-80c4-e6b97b71c0f0">
12
+ </video>
13
+ </details>
14
+
15
+ - **[Live Demo & Storybook](https://patrickkuei.github.io/CyberUI)** interactive component docs and examples
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ npm install cyberui-2045
21
+ ```
22
+
23
+ Import the stylesheet once in your app entry, then use any component:
24
+
25
+ ```tsx
26
+ import 'cyberui-2045/styles.css';
27
+ import { Button, Card, CircularProgress } from 'cyberui-2045';
28
+
29
+ function App() {
30
+ return (
31
+ <Card>
32
+ <CircularProgress progress={75} radius={20}>
33
+ <span>75%</span>
34
+ </CircularProgress>
35
+ <Button variant="primary">Jack In</Button>
36
+ </Card>
37
+ );
38
+ }
39
+ ```
40
+
41
+ ## Components
42
+
43
+ | Component | Category | Docs |
44
+ |-----------|----------|------|
45
+ | Button | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/button--docs) |
46
+ | Input | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/input--docs) |
47
+ | Select | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/select--docs) |
48
+ | Toggle | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/toggle--docs) |
49
+ | Card | Layout | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/card--docs) |
50
+ | Modal | Layout | [](https://patrickkuei.github.io/CyberUI/?path=/docs/modal--docs) |
51
+ | Badge | Feedback | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/badge--docs) |
52
+ | Notification | Feedback | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/notification--docs) |
53
+ | Skeleton | Feedback | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/skeleton--docs) |
54
+ | CircularProgress | Progress | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/circularprogress--docs) |
55
+ | LinearProgress | Progress | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/linearprogress--docs) |
56
+ | SegmentedProgress | Progress | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/segmentedprogress--docs) |
57
+ | TabNavigation | Navigation | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/tabnavigation--docs) |
58
+ | Carousel | Navigation | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/carousel--docs) |
59
+ | Steps | Navigation | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/steps--docs) |
60
+ | Image | Media | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/image--docs) |
61
+ | Checkbox | Forms | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/checkbox--docs) |
62
+ | Divider | Layout | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/divider--docs) |
63
+ | GradientText | Typography | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/gradienttext--docs) |
64
+ | SectionTitle | Typography | [](https://patrickkuei.github.io/CyberUI/?path=/docs/sectiontitle--docs) |
65
+ | Timeline | Display | [→](https://patrickkuei.github.io/CyberUI/?path=/docs/timeline--docs) |
66
+
67
+ Also includes hooks (`useCyberNotifications`, `useAnimatedProgress`, `useCyberScrollbar`) and `CyberNotificationProvider` context.
68
+
69
+ ## AI Coding Setup
70
+
71
+ If you use an AI coding assistant (Claude Code, Cursor, GitHub Copilot), run this once after installing:
72
+
73
+ ```bash
74
+ npx cyberui-2045 init
75
+ ```
76
+
77
+ It writes a concise CyberUI usage guide — components, hooks, tokens, and patterns — directly into your AI config file (`CLAUDE.md`, `.cursorrules`, or `.github/copilot-instructions.md`). Idempotent: safe to re-run after upgrades.
78
+
79
+ ```bash
80
+ npx cyberui-2045 init --claude # Claude Code only
81
+ npx cyberui-2045 init --cursor # Cursor only
82
+ npx cyberui-2045 init --copilot # GitHub Copilot only
83
+ npx cyberui-2045 init --all # all three
84
+ npx cyberui-2045 init --dry-run # preview without writing
85
+ ```
86
+
87
+ ## Customization
88
+
89
+ CyberUI is an opinionated design system. Layout, spacing, and motion are intentional and fixed. You own the **color palette**.
90
+
91
+ ### CSS token overrides
92
+
93
+ Override in your global CSS after importing `cyberui-2045/styles.css`:
94
+
95
+ ```css
96
+ :root {
97
+ --color-primary: #ff005d; /* neon pink */
98
+ --color-secondary: #00fff9; /* cyan */
99
+ --color-accent: #fffb00; /* yellow */
100
+ --color-success: #00ff9e; /* green */
101
+ --color-error: #ff4f4f; /* red */
102
+ --color-warning: #ffaa00; /* orange */
103
+ --color-base: #1a1a2e; /* page background */
104
+ --color-surface: #2d2d44; /* card / component surface */
105
+ --color-border-default: #3c3c5e; /* borders */
106
+ --color-default: #e0e0e0; /* primary text */
107
+ --color-muted: #8888aa; /* secondary text */
108
+ --color-inverse: #1a1a2e; /* inverted text */
109
+ }
110
+ ```
111
+
112
+ These tokens are **guaranteed stable** across minor versions. All other CSS variables (shadows, gradients, animation values, `--tw-*`) are internal and may change.
113
+
114
+ ### className prop
115
+
116
+ All components accept a `className` prop, merged via [`tailwind-merge`](https://github.com/dcastil/tailwind-merge) — your classes win on conflict:
117
+
118
+ ```tsx
119
+ <Button className="mt-8 w-full">Full width with margin</Button>
120
+ ```
121
+
122
+ Use `className` for layout and spacing. Overriding color or variant classes is supported but visual coherence becomes your responsibility.
123
+
124
+ ### cn() utility
125
+
126
+ CyberUI re-exports its `cn()` helper (clsx + tailwind-merge) for use in your own components:
127
+
128
+ ```tsx
129
+ import { cn } from 'cyberui-2045';
130
+
131
+ <div className={cn('base-classes', isActive && 'active', userClassName)} />
132
+ ```
133
+
134
+ ## Changelog
135
+
136
+ See [CHANGELOG.md](./CHANGELOG.md) for the full history.
137
+
138
+ ## Development
139
+
140
+ ```bash
141
+ git clone https://github.com/patrickkuei/CyberUI.git
142
+ cd CyberUI
143
+ npm install
144
+ npm run dev # demo app
145
+ npm run storybook # Storybook on :6006
146
+ npm run test # unit + Storybook tests
147
+ npm run build # typecheck + bundle → dist/
148
+ ```
149
+
150
+ ## Contributing
151
+
152
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md).
153
+
154
+ ## License
155
+
156
+ MIT — see [LICENSE](LICENSE) for details.
157
+
158
+ ---
159
+
160
+ Made with ⚡ by [Patrick Yang](https://github.com/patrickkuei)
package/bin/init.js ADDED
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createInterface } from 'node:readline';
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
5
+ import { join, dirname } from 'node:path';
6
+ import { getUsageContent } from './usage-content.js';
7
+
8
+ // ─── Constants ────────────────────────────────────────────────────────────────
9
+
10
+ const MARKER_START = '<!-- cyberui-2045:start -->';
11
+ const MARKER_END = '<!-- cyberui-2045:end -->';
12
+
13
+ const TARGETS = {
14
+ claude: {
15
+ label: 'Claude Code → CLAUDE.md',
16
+ file: 'CLAUDE.md',
17
+ },
18
+ cursor: {
19
+ label: 'Cursor → .cursorrules',
20
+ file: '.cursorrules',
21
+ },
22
+ copilot: {
23
+ label: 'GitHub Copilot → .github/copilot-instructions.md',
24
+ file: '.github/copilot-instructions.md',
25
+ },
26
+ };
27
+
28
+ // ─── Arg parsing ──────────────────────────────────────────────────────────────
29
+
30
+ const args = process.argv.slice(2);
31
+ const isDryRun = args.includes('--dry-run');
32
+
33
+ let selectedKeys = [];
34
+ if (args.includes('--all')) {
35
+ selectedKeys = Object.keys(TARGETS);
36
+ } else {
37
+ if (args.includes('--claude')) selectedKeys.push('claude');
38
+ if (args.includes('--cursor')) selectedKeys.push('cursor');
39
+ if (args.includes('--copilot')) selectedKeys.push('copilot');
40
+ }
41
+
42
+ // ─── Main ─────────────────────────────────────────────────────────────────────
43
+
44
+ async function main() {
45
+ console.log('\n cyberui-2045 — AI assistant setup\n');
46
+
47
+ if (selectedKeys.length === 0) {
48
+ if (!process.stdin.isTTY) {
49
+ // Non-interactive (CI / piped input)
50
+ console.log(' Non-interactive environment detected. Run one of:\n');
51
+ console.log(' npx cyberui-2045 init --claude');
52
+ console.log(' npx cyberui-2045 init --cursor');
53
+ console.log(' npx cyberui-2045 init --copilot');
54
+ console.log(' npx cyberui-2045 init --all\n');
55
+ process.exit(0);
56
+ }
57
+ selectedKeys = await promptTargets();
58
+ }
59
+
60
+ if (selectedKeys.length === 0) {
61
+ console.log('\n Nothing written. Exiting.\n');
62
+ process.exit(0);
63
+ }
64
+
65
+ console.log(isDryRun ? '\n [dry-run] Would write:\n' : '');
66
+
67
+ for (const key of selectedKeys) {
68
+ writeTarget(key);
69
+ }
70
+
71
+ console.log('\n Done! Your AI assistant now has CyberUI context.\n');
72
+ }
73
+
74
+ // ─── Interactive prompt ───────────────────────────────────────────────────────
75
+
76
+ function promptTargets() {
77
+ return new Promise((resolve) => {
78
+ const keys = Object.keys(TARGETS);
79
+ const cwd = process.cwd();
80
+
81
+ console.log(' Which AI config file should the CyberUI usage guide be added to?\n');
82
+
83
+ keys.forEach((key, i) => {
84
+ const target = TARGETS[key];
85
+ const filePath = join(cwd, target.file);
86
+ const exists = existsSync(filePath);
87
+ const hasSection = exists && readFileSync(filePath, 'utf8').includes(MARKER_START);
88
+ const status = hasSection ? ' (update)' : exists ? ' (append)' : ' (create)';
89
+ console.log(` ${i + 1}. ${target.label}${status}`);
90
+ });
91
+
92
+ console.log(` ${keys.length + 1}. All of the above`);
93
+ console.log('\n Enter number(s) separated by commas (e.g. 1,3), or press Enter to cancel:');
94
+
95
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
96
+
97
+ rl.question(' > ', (answer) => {
98
+ rl.close();
99
+
100
+ const raw = answer.trim();
101
+ if (!raw) return resolve([]);
102
+
103
+ const chosen = [];
104
+ for (const part of raw.split(',')) {
105
+ const n = parseInt(part.trim(), 10);
106
+ if (n === keys.length + 1) return resolve([...keys]); // "All"
107
+ if (n >= 1 && n <= keys.length) {
108
+ const key = keys[n - 1];
109
+ if (!chosen.includes(key)) chosen.push(key);
110
+ }
111
+ }
112
+
113
+ resolve(chosen);
114
+ });
115
+ });
116
+ }
117
+
118
+ // ─── Write / update target file ───────────────────────────────────────────────
119
+
120
+ function writeTarget(key) {
121
+ const target = TARGETS[key];
122
+ const cwd = process.cwd();
123
+ const filePath = join(cwd, target.file);
124
+
125
+ // Read current package version
126
+ let version = '1.3.2';
127
+ try {
128
+ const pkgPath = new URL('../package.json', import.meta.url).pathname;
129
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
130
+ version = pkg.version ?? version;
131
+ } catch {
132
+ // fallback to hardcoded version
133
+ }
134
+
135
+ const block = `${MARKER_START}\n${getUsageContent(version)}\n${MARKER_END}`;
136
+
137
+ if (isDryRun) {
138
+ console.log(` ── ${target.file} ──\n${block}\n`);
139
+ return;
140
+ }
141
+
142
+ // Ensure parent directory exists (e.g. .github/)
143
+ const dir = dirname(filePath);
144
+ if (!existsSync(dir)) {
145
+ mkdirSync(dir, { recursive: true });
146
+ }
147
+
148
+ let finalContent;
149
+
150
+ if (existsSync(filePath)) {
151
+ const existing = readFileSync(filePath, 'utf8');
152
+
153
+ if (existing.includes(MARKER_START) && existing.includes(MARKER_END)) {
154
+ // Replace existing section
155
+ const before = existing.slice(0, existing.indexOf(MARKER_START));
156
+ const after = existing.slice(existing.indexOf(MARKER_END) + MARKER_END.length);
157
+ finalContent = `${before}${block}${after}`;
158
+ console.log(` ✓ Updated ${target.file}`);
159
+ } else {
160
+ // Append new section
161
+ finalContent = `${existing.trimEnd()}\n\n${block}\n`;
162
+ console.log(` ✓ Appended ${target.file}`);
163
+ }
164
+ } else {
165
+ // Create new file
166
+ finalContent = `${block}\n`;
167
+ console.log(` ✓ Created ${target.file}`);
168
+ }
169
+
170
+ writeFileSync(filePath, finalContent, 'utf8');
171
+ }
172
+
173
+ // ─── Run ──────────────────────────────────────────────────────────────────────
174
+
175
+ main().catch((err) => {
176
+ console.error('\n Error:', err.message, '\n');
177
+ process.exit(1);
178
+ });