@archetypeai/ds-cli 0.3.7
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 +21 -0
- package/README.md +123 -0
- package/bin.js +77 -0
- package/commands/add.js +42 -0
- package/commands/create.js +238 -0
- package/commands/init.js +199 -0
- package/files/AGENTS.md +63 -0
- package/files/CLAUDE.md +63 -0
- package/files/LICENSE +21 -0
- package/files/rules/accessibility.md +219 -0
- package/files/rules/charts.md +352 -0
- package/files/rules/components.md +267 -0
- package/files/rules/design-principles.md +56 -0
- package/files/rules/linting.md +31 -0
- package/files/rules/state.md +405 -0
- package/files/rules/styling.md +245 -0
- package/files/skills/apply-ds/SKILL.md +117 -0
- package/files/skills/apply-ds/scripts/setup.sh +271 -0
- package/files/skills/build-pattern/SKILL.md +202 -0
- package/files/skills/create-dashboard/SKILL.md +189 -0
- package/files/skills/deploy-worker/SKILL.md +231 -0
- package/files/skills/deploy-worker/references/wrangler-commands.md +327 -0
- package/files/skills/fix-accessibility/SKILL.md +184 -0
- package/files/skills/fix-metadata/SKILL.md +118 -0
- package/files/skills/fix-metadata/assets/favicon.ico +0 -0
- package/files/skills/setup-chart/SKILL.md +225 -0
- package/files/skills/setup-chart/data/embedding.csv +42 -0
- package/files/skills/setup-chart/data/timeseries.csv +173 -0
- package/files/skills/setup-chart/references/scatter-chart.md +229 -0
- package/files/skills/setup-chart/references/sensor-chart.md +156 -0
- package/lib/add-ds-config-codeagent.js +154 -0
- package/lib/add-ds-ui-svelte.js +93 -0
- package/lib/scaffold-ds-svelte-project.js +272 -0
- package/lib/use-package-manager.js +65 -0
- package/lib/use-shadcn-svelte-registry.js +26 -0
- package/lib/validate-url.js +31 -0
- package/package.json +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Archetype AI
|
|
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
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
## @archetypeai/ds-cli
|
|
2
|
+
|
|
3
|
+
`@archetypeai/ds-cli` is the CLI for the **Archetype AI Design System**. It provides commands for creating, configuring, and managing projects that use the design system.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
### `create` — Scaffold a new project
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx @archetypeai/ds-cli create my-app
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Scaffolds a full SvelteKit + Tailwind v4 + shadcn-svelte project:
|
|
16
|
+
|
|
17
|
+
1. Creates a SvelteKit project via `sv create`
|
|
18
|
+
2. Installs design tokens (`@archetypeai/ds-lib-tokens`)
|
|
19
|
+
3. Optionally installs internal fonts (`@archetypeai/ds-lib-fonts-internal`)
|
|
20
|
+
4. Initializes shadcn-svelte (`components.json`, `utils.js`, dependencies)
|
|
21
|
+
5. Configures CSS (`layout.css` with design tokens and optional fonts import)
|
|
22
|
+
6. Installs all components from the design system registry
|
|
23
|
+
7. Optionally installs AI agent configuration (Cursor or Claude Code)
|
|
24
|
+
8. Creates a demo page with Button examples
|
|
25
|
+
|
|
26
|
+
#### Create flags
|
|
27
|
+
|
|
28
|
+
| Flag | Values | Default |
|
|
29
|
+
|------|--------|---------|
|
|
30
|
+
| `--framework` | `svelte` | prompt |
|
|
31
|
+
| `--pm` | `npm`, `pnpm`, `bun`, `yarn` | prompt |
|
|
32
|
+
| `--fonts` / `--no-fonts` | boolean | prompt (default: yes) |
|
|
33
|
+
| `--no-components` | skip component installation | install all |
|
|
34
|
+
| `--codeagent` | `cursor`, `claude`, `none` | prompt |
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx @archetypeai/ds-cli create my-app --framework svelte --pm pnpm --no-fonts --codeagent none
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### `init` — Add DS to an existing project
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cd my-existing-app
|
|
46
|
+
npx @archetypeai/ds-cli init
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Run from an existing SvelteKit project root. Detects your package manager from the lockfile and installs the design system without creating a new project:
|
|
50
|
+
|
|
51
|
+
1. Detects project (verifies `package.json` and `svelte.config.js`)
|
|
52
|
+
2. Auto-detects package manager from lockfile
|
|
53
|
+
3. Installs Tailwind CSS v4 if not already present
|
|
54
|
+
4. Installs design tokens
|
|
55
|
+
5. Optionally installs internal fonts
|
|
56
|
+
6. Initializes shadcn-svelte
|
|
57
|
+
7. Prepends DS imports to existing `layout.css` (preserves your styles)
|
|
58
|
+
8. Installs all components from the registry
|
|
59
|
+
9. Optionally installs AI agent configuration
|
|
60
|
+
|
|
61
|
+
#### Init flags
|
|
62
|
+
|
|
63
|
+
| Flag | Values | Default |
|
|
64
|
+
|------|--------|---------|
|
|
65
|
+
| `--pm` | `npm`, `pnpm`, `bun`, `yarn` | auto-detect from lockfile |
|
|
66
|
+
| `--fonts` / `--no-fonts` | boolean | prompt (default: yes) |
|
|
67
|
+
| `--no-components` | skip component installation | install all |
|
|
68
|
+
| `--codeagent` | `cursor`, `claude`, `none` | prompt |
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx @archetypeai/ds-cli init --pm npm --no-fonts --codeagent none
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### `add` — Add components or agent configurations
|
|
77
|
+
|
|
78
|
+
#### `add ds-ui-svelte` — Install all design system components
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx @archetypeai/ds-cli add ds-ui-svelte
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Installs all components from the design system registry into your project. Requires shadcn-svelte to be initialized (`components.json` must exist).
|
|
85
|
+
|
|
86
|
+
#### `add ds-config-codeagent` — Install agent configuration
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx @archetypeai/ds-cli add ds-config-codeagent --cursor
|
|
90
|
+
npx @archetypeai/ds-cli add ds-config-codeagent --claude
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Installs agent configuration files (AGENTS.md/CLAUDE.md, skills, and rules) for the specified IDE. If no flag is provided, an interactive prompt will ask which IDE to configure.
|
|
94
|
+
|
|
95
|
+
| Flag | Effect |
|
|
96
|
+
|------|--------|
|
|
97
|
+
| `--cursor` | Copies AGENTS.md, skills, and rules to `.cursor/` |
|
|
98
|
+
| `--claude` | Copies CLAUDE.md, skills, and rules to `.claude/` |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Environment Variables
|
|
103
|
+
|
|
104
|
+
| Variable | Default | Description |
|
|
105
|
+
|----------|---------|-------------|
|
|
106
|
+
| `REGISTRY_URL` | `https://design-system.archetypeai.workers.dev` | Override the component registry URL for testing or private registries |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Security
|
|
111
|
+
|
|
112
|
+
The CLI validates all data from external sources before use:
|
|
113
|
+
|
|
114
|
+
- **Registry URLs** are validated against an HTTPS + `/r/<name>.json` pattern before being passed to any shell command
|
|
115
|
+
- **Shell commands** use `execFileSync` (no shell interpolation) to prevent injection even if validation is bypassed
|
|
116
|
+
- **Package manager** and **framework** flag values are validated against known allowlists
|
|
117
|
+
- **Fetch requests** have a 15-second timeout to prevent hanging on unresponsive registries
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Fonts
|
|
122
|
+
|
|
123
|
+
The internal fonts package (`@archetypeai/ds-lib-fonts-internal`) is not yet published. When available, it will be on npmjs.org. If omitted, the theme falls back to system fonts.
|
package/bin.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
6
|
+
import { create } from './commands/create.js';
|
|
7
|
+
import { init } from './commands/init.js';
|
|
8
|
+
import { add } from './commands/add.js';
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
function getVersion() {
|
|
13
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf-8'));
|
|
14
|
+
return pkg.version;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function printUsage() {
|
|
18
|
+
console.log(`
|
|
19
|
+
ds - Archetype AI Design System CLI
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
npx @archetypeai/ds-cli create [project-name] [flags] Create a new project
|
|
23
|
+
npx @archetypeai/ds-cli init [flags] Init DS in existing project
|
|
24
|
+
npx @archetypeai/ds-cli add <target> [flags] Add components or configs
|
|
25
|
+
npx @archetypeai/ds-cli --help Show this help message
|
|
26
|
+
npx @archetypeai/ds-cli --version Show version
|
|
27
|
+
|
|
28
|
+
Create flags:
|
|
29
|
+
--framework <svelte> Framework to use (default: prompt)
|
|
30
|
+
--pm <npm|pnpm|bun|yarn> Package manager (default: prompt)
|
|
31
|
+
--fonts / --no-fonts Install internal fonts (default: prompt)
|
|
32
|
+
--no-components Skip component installation (default: install all)
|
|
33
|
+
--codeagent <cursor|claude|none> Agent configuration (default: prompt)
|
|
34
|
+
|
|
35
|
+
Init flags:
|
|
36
|
+
--pm <npm|pnpm|bun|yarn> Package manager (default: auto-detect)
|
|
37
|
+
--fonts / --no-fonts Install internal fonts (default: prompt)
|
|
38
|
+
--no-components Skip component installation (default: install all)
|
|
39
|
+
--codeagent <cursor|claude|none> Agent configuration (default: prompt)
|
|
40
|
+
|
|
41
|
+
Add targets:
|
|
42
|
+
ds-ui-svelte Install all design system components
|
|
43
|
+
ds-config-codeagent [flags] Install agent configuration files
|
|
44
|
+
--cursor Setup for Cursor IDE
|
|
45
|
+
--claude Setup for Claude Code
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const command = process.argv[2];
|
|
50
|
+
const args = process.argv.slice(3);
|
|
51
|
+
|
|
52
|
+
switch (command) {
|
|
53
|
+
case 'create':
|
|
54
|
+
await create(args);
|
|
55
|
+
break;
|
|
56
|
+
case 'init':
|
|
57
|
+
await init(args);
|
|
58
|
+
break;
|
|
59
|
+
case 'add':
|
|
60
|
+
await add(args);
|
|
61
|
+
break;
|
|
62
|
+
case '--help':
|
|
63
|
+
case '-h':
|
|
64
|
+
printUsage();
|
|
65
|
+
break;
|
|
66
|
+
case '--version':
|
|
67
|
+
case '-v':
|
|
68
|
+
console.log(getVersion());
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
if (command) {
|
|
72
|
+
console.error(`Unknown command: ${command}\n`);
|
|
73
|
+
}
|
|
74
|
+
printUsage();
|
|
75
|
+
if (command) process.exit(1);
|
|
76
|
+
break;
|
|
77
|
+
}
|
package/commands/add.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { addDsUiSvelte } from '../lib/add-ds-ui-svelte.js';
|
|
3
|
+
import { addDsConfigCodeagent } from '../lib/add-ds-config-codeagent.js';
|
|
4
|
+
|
|
5
|
+
const VALID_TARGETS = ['ds-ui-svelte', 'ds-config-codeagent'];
|
|
6
|
+
|
|
7
|
+
function printUsage() {
|
|
8
|
+
console.log(`
|
|
9
|
+
ds add - Add components or configurations
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
npx @archetypeai/ds-cli add ds-ui-svelte Install all design system components
|
|
13
|
+
npx @archetypeai/ds-cli add ds-config-codeagent [flags] Install agent configuration
|
|
14
|
+
--cursor Setup for Cursor IDE
|
|
15
|
+
--claude Setup for Claude Code
|
|
16
|
+
`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function add(args) {
|
|
20
|
+
const target = args[0];
|
|
21
|
+
const flags = args.slice(1);
|
|
22
|
+
|
|
23
|
+
switch (target) {
|
|
24
|
+
case 'ds-ui-svelte':
|
|
25
|
+
await addDsUiSvelte(flags);
|
|
26
|
+
break;
|
|
27
|
+
case 'ds-config-codeagent':
|
|
28
|
+
await addDsConfigCodeagent(flags);
|
|
29
|
+
break;
|
|
30
|
+
case '--help':
|
|
31
|
+
case '-h':
|
|
32
|
+
printUsage();
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
if (target) {
|
|
36
|
+
p.log.error(`Unknown add target: "${target}". Valid targets: ${VALID_TARGETS.join(', ')}`);
|
|
37
|
+
}
|
|
38
|
+
printUsage();
|
|
39
|
+
if (target) process.exit(1);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import * as p from '@clack/prompts';
|
|
4
|
+
import { getPm, pmNames, isPmInstalled } from '../lib/use-package-manager.js';
|
|
5
|
+
import { fetchComponents } from '../lib/use-shadcn-svelte-registry.js';
|
|
6
|
+
import {
|
|
7
|
+
runSvCreate,
|
|
8
|
+
installTokens,
|
|
9
|
+
installFonts,
|
|
10
|
+
initShadcn,
|
|
11
|
+
configureCss,
|
|
12
|
+
installComponents,
|
|
13
|
+
createDemoPage,
|
|
14
|
+
installAgentConfig
|
|
15
|
+
} from '../lib/scaffold-ds-svelte-project.js';
|
|
16
|
+
|
|
17
|
+
// parse flags
|
|
18
|
+
export function parseFlags(args) {
|
|
19
|
+
const flags = {
|
|
20
|
+
name: null,
|
|
21
|
+
framework: null,
|
|
22
|
+
pm: null,
|
|
23
|
+
fonts: null,
|
|
24
|
+
components: true,
|
|
25
|
+
agent: null
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
const arg = args[i];
|
|
30
|
+
if (arg === '--framework' && args[i + 1]) {
|
|
31
|
+
flags.framework = args[++i];
|
|
32
|
+
} else if (arg === '--pm' && args[i + 1]) {
|
|
33
|
+
flags.pm = args[++i];
|
|
34
|
+
} else if (arg === '--fonts') {
|
|
35
|
+
flags.fonts = true;
|
|
36
|
+
} else if (arg === '--no-fonts') {
|
|
37
|
+
flags.fonts = false;
|
|
38
|
+
} else if (arg === '--no-components') {
|
|
39
|
+
flags.components = false;
|
|
40
|
+
} else if (arg === '--codeagent' && args[i + 1]) {
|
|
41
|
+
flags.agent = args[++i];
|
|
42
|
+
} else if (!arg.startsWith('--') && !flags.name) {
|
|
43
|
+
flags.name = arg;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return flags;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// create a new project
|
|
51
|
+
export async function create(args) {
|
|
52
|
+
const flags = parseFlags(args);
|
|
53
|
+
|
|
54
|
+
p.intro('Create a new project using Archetype AI Design System.');
|
|
55
|
+
|
|
56
|
+
// specify project name
|
|
57
|
+
let name = flags.name;
|
|
58
|
+
if (!name) {
|
|
59
|
+
name = await p.text({
|
|
60
|
+
message: 'What is your project name?',
|
|
61
|
+
placeholder: 'my-app',
|
|
62
|
+
validate(value) {
|
|
63
|
+
if (!value.trim()) return 'Project name is required.';
|
|
64
|
+
if (!/^[a-z0-9-]+$/.test(value.trim()))
|
|
65
|
+
return 'Use lowercase letters, numbers, and hyphens only.';
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
if (p.isCancel(name)) {
|
|
69
|
+
p.cancel('Setup cancelled.');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
name = name.trim();
|
|
74
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
75
|
+
p.log.error('Invalid project name. Use lowercase letters, numbers, and hyphens only.');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// validate --pm flag
|
|
80
|
+
if (flags.pm && !pmNames.includes(flags.pm)) {
|
|
81
|
+
p.log.error(`Invalid --pm value "${flags.pm}". Must be one of: ${pmNames.join(', ')}`);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// validate --framework flag
|
|
86
|
+
if (flags.framework && flags.framework !== 'svelte') {
|
|
87
|
+
p.log.error(
|
|
88
|
+
`Unsupported framework "${flags.framework}". Currently only "svelte" is supported.`
|
|
89
|
+
);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// specify framework
|
|
94
|
+
let framework = flags.framework;
|
|
95
|
+
if (!framework) {
|
|
96
|
+
framework = await p.select({
|
|
97
|
+
message: 'Which framework?',
|
|
98
|
+
options: [{ value: 'svelte', label: 'SvelteKit', hint: 'Svelte 5 + Tailwind v4' }]
|
|
99
|
+
});
|
|
100
|
+
if (p.isCancel(framework)) {
|
|
101
|
+
p.cancel('Setup cancelled.');
|
|
102
|
+
process.exit(0);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// specify package manager
|
|
107
|
+
let pmName = flags.pm;
|
|
108
|
+
if (!pmName) {
|
|
109
|
+
pmName = await p.select({
|
|
110
|
+
message: 'Which package manager?',
|
|
111
|
+
options: pmNames.map((n) => ({ value: n, label: n }))
|
|
112
|
+
});
|
|
113
|
+
if (p.isCancel(pmName)) {
|
|
114
|
+
p.cancel('Setup cancelled.');
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const pm = getPm(pmName);
|
|
119
|
+
|
|
120
|
+
// verify package manager is installed
|
|
121
|
+
if (!isPmInstalled(pmName)) {
|
|
122
|
+
p.log.error(`${pmName} is not installed. Please install it first and try again.`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// check if directory exists
|
|
127
|
+
const targetDir = process.cwd();
|
|
128
|
+
const projectPath = resolve(targetDir, name);
|
|
129
|
+
|
|
130
|
+
if (existsSync(projectPath)) {
|
|
131
|
+
const overwrite = await p.confirm({
|
|
132
|
+
message: `Directory "${name}" already exists. Continue anyway?`,
|
|
133
|
+
initialValue: false
|
|
134
|
+
});
|
|
135
|
+
if (p.isCancel(overwrite) || !overwrite) {
|
|
136
|
+
p.cancel('Setup cancelled.');
|
|
137
|
+
process.exit(0);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// create SvelteKit project
|
|
142
|
+
const created = runSvCreate(pm, name, targetDir);
|
|
143
|
+
if (!created) {
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// specify fonts
|
|
148
|
+
let includeFonts = flags.fonts;
|
|
149
|
+
if (includeFonts === null) {
|
|
150
|
+
includeFonts = await p.confirm({
|
|
151
|
+
message: 'Install internal fonts package?',
|
|
152
|
+
initialValue: true
|
|
153
|
+
});
|
|
154
|
+
if (p.isCancel(includeFonts)) {
|
|
155
|
+
p.cancel('Setup cancelled.');
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// install packages
|
|
161
|
+
const tokensOk = installTokens(pm, projectPath);
|
|
162
|
+
if (!tokensOk) {
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (includeFonts) {
|
|
167
|
+
installFonts(pm, projectPath);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// init shadcn-svelte
|
|
171
|
+
initShadcn(pm, projectPath);
|
|
172
|
+
|
|
173
|
+
// configure CSS
|
|
174
|
+
configureCss(projectPath, includeFonts);
|
|
175
|
+
|
|
176
|
+
// install components
|
|
177
|
+
if (flags.components) {
|
|
178
|
+
try {
|
|
179
|
+
const s = p.spinner();
|
|
180
|
+
s.start('Fetching component list');
|
|
181
|
+
const components = await fetchComponents();
|
|
182
|
+
s.stop(`Found ${components.length} components`);
|
|
183
|
+
installComponents(pm, projectPath, components);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
p.log.warn(`Component installation skipped: ${error.message}`);
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
p.log.info('Skipped component installation (--no-components)');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// specify agent config
|
|
192
|
+
let agent = flags.agent;
|
|
193
|
+
if (!agent) {
|
|
194
|
+
agent = await p.select({
|
|
195
|
+
message: 'Install AI agent configuration?',
|
|
196
|
+
options: [
|
|
197
|
+
{ value: 'none', label: 'None' },
|
|
198
|
+
{ value: 'cursor', label: 'Cursor', hint: 'AGENTS.md + skills + rules' },
|
|
199
|
+
{ value: 'claude', label: 'Claude Code', hint: 'CLAUDE.md + skills + rules' }
|
|
200
|
+
]
|
|
201
|
+
});
|
|
202
|
+
if (p.isCancel(agent)) {
|
|
203
|
+
p.cancel('Setup cancelled.');
|
|
204
|
+
process.exit(0);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const validAgents = ['cursor', 'claude', 'none'];
|
|
209
|
+
if (!validAgents.includes(agent)) {
|
|
210
|
+
p.log.error(`Invalid --codeagent value "${agent}". Must be one of: ${validAgents.join(', ')}`);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (agent !== 'none') {
|
|
215
|
+
installAgentConfig(projectPath, agent);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// create demo page
|
|
219
|
+
createDemoPage(projectPath);
|
|
220
|
+
|
|
221
|
+
// summary
|
|
222
|
+
const summary = [
|
|
223
|
+
`Project: ${name}`,
|
|
224
|
+
`Location: ${projectPath}`,
|
|
225
|
+
`Framework: ${framework}`,
|
|
226
|
+
`Package Manager: ${pm.name}`,
|
|
227
|
+
`Fonts: ${includeFonts ? 'installed' : 'skipped'}`,
|
|
228
|
+
`Components: ${flags.components ? 'all' : 'skipped'}`,
|
|
229
|
+
`Agent Configuration: ${agent}`
|
|
230
|
+
].join('\n');
|
|
231
|
+
|
|
232
|
+
p.note(summary, 'Summary');
|
|
233
|
+
|
|
234
|
+
p.log.step(`cd ${name}`);
|
|
235
|
+
p.log.step(`${pm.name} run dev`);
|
|
236
|
+
|
|
237
|
+
p.outro('You are all set!');
|
|
238
|
+
}
|
package/commands/init.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import * as p from '@clack/prompts';
|
|
4
|
+
import { getPm, pmNames, isPmInstalled, detectPm } from '../lib/use-package-manager.js';
|
|
5
|
+
import { fetchComponents } from '../lib/use-shadcn-svelte-registry.js';
|
|
6
|
+
import {
|
|
7
|
+
installTailwind,
|
|
8
|
+
installTokens,
|
|
9
|
+
installFonts,
|
|
10
|
+
initShadcn,
|
|
11
|
+
prependCss,
|
|
12
|
+
installComponents,
|
|
13
|
+
installAgentConfig
|
|
14
|
+
} from '../lib/scaffold-ds-svelte-project.js';
|
|
15
|
+
|
|
16
|
+
// parse flags
|
|
17
|
+
export function parseFlags(args) {
|
|
18
|
+
const flags = {
|
|
19
|
+
pm: null,
|
|
20
|
+
fonts: null,
|
|
21
|
+
components: true,
|
|
22
|
+
agent: null
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < args.length; i++) {
|
|
26
|
+
const arg = args[i];
|
|
27
|
+
if (arg === '--pm' && args[i + 1]) {
|
|
28
|
+
flags.pm = args[++i];
|
|
29
|
+
} else if (arg === '--fonts') {
|
|
30
|
+
flags.fonts = true;
|
|
31
|
+
} else if (arg === '--no-fonts') {
|
|
32
|
+
flags.fonts = false;
|
|
33
|
+
} else if (arg === '--no-components') {
|
|
34
|
+
flags.components = false;
|
|
35
|
+
} else if (arg === '--codeagent' && args[i + 1]) {
|
|
36
|
+
flags.agent = args[++i];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return flags;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// check if project has Tailwind CSS
|
|
44
|
+
function hasTailwind(projectPath) {
|
|
45
|
+
try {
|
|
46
|
+
const pkg = JSON.parse(readFileSync(join(projectPath, 'package.json'), 'utf-8'));
|
|
47
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
48
|
+
return 'tailwindcss' in deps;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// initialize the design system in an existing project
|
|
55
|
+
export async function init(args) {
|
|
56
|
+
const flags = parseFlags(args);
|
|
57
|
+
const projectPath = process.cwd();
|
|
58
|
+
|
|
59
|
+
// validate --pm flag
|
|
60
|
+
if (flags.pm && !pmNames.includes(flags.pm)) {
|
|
61
|
+
p.log.error(`Invalid --pm value "${flags.pm}". Must be one of: ${pmNames.join(', ')}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
p.intro('Initialize Archetype AI Design System in existing project.');
|
|
66
|
+
|
|
67
|
+
// detect project
|
|
68
|
+
if (!existsSync(join(projectPath, 'package.json'))) {
|
|
69
|
+
p.log.error('No package.json found. Run this command from your project root.');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const hasSvelteConfig =
|
|
74
|
+
existsSync(join(projectPath, 'svelte.config.js')) ||
|
|
75
|
+
existsSync(join(projectPath, 'svelte.config.mjs')) ||
|
|
76
|
+
existsSync(join(projectPath, 'svelte.config.ts'));
|
|
77
|
+
if (!hasSvelteConfig) {
|
|
78
|
+
p.log.warn('No svelte.config found. This command is designed for SvelteKit projects.');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// detect package manager
|
|
82
|
+
let pmName = flags.pm;
|
|
83
|
+
if (!pmName) {
|
|
84
|
+
pmName = detectPm(projectPath);
|
|
85
|
+
if (pmName) {
|
|
86
|
+
p.log.info(`Detected package manager: ${pmName}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!pmName) {
|
|
90
|
+
pmName = await p.select({
|
|
91
|
+
message: 'Which package manager?',
|
|
92
|
+
options: pmNames.map((n) => ({ value: n, label: n }))
|
|
93
|
+
});
|
|
94
|
+
if (p.isCancel(pmName)) {
|
|
95
|
+
p.cancel('Setup cancelled.');
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const pm = getPm(pmName);
|
|
100
|
+
|
|
101
|
+
// verify package manager is installed
|
|
102
|
+
if (!isPmInstalled(pmName)) {
|
|
103
|
+
p.log.error(`${pmName} is not installed. Please install it first and try again.`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// detect and install Tailwind if missing
|
|
108
|
+
if (!hasTailwind(projectPath)) {
|
|
109
|
+
p.log.info('Tailwind CSS not found in dependencies.');
|
|
110
|
+
const tailwindOk = installTailwind(pm, projectPath);
|
|
111
|
+
if (!tailwindOk) {
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// specify fonts
|
|
117
|
+
let includeFonts = flags.fonts;
|
|
118
|
+
if (includeFonts === null) {
|
|
119
|
+
includeFonts = await p.confirm({
|
|
120
|
+
message: 'Install internal fonts package?',
|
|
121
|
+
initialValue: true
|
|
122
|
+
});
|
|
123
|
+
if (p.isCancel(includeFonts)) {
|
|
124
|
+
p.cancel('Setup cancelled.');
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// install packages
|
|
130
|
+
const tokensOk = installTokens(pm, projectPath);
|
|
131
|
+
if (!tokensOk) {
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (includeFonts) {
|
|
136
|
+
installFonts(pm, projectPath);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// init shadcn-svelte
|
|
140
|
+
initShadcn(pm, projectPath);
|
|
141
|
+
|
|
142
|
+
// configure CSS (prepend to existing)
|
|
143
|
+
prependCss(projectPath, includeFonts);
|
|
144
|
+
|
|
145
|
+
// install components
|
|
146
|
+
if (flags.components) {
|
|
147
|
+
try {
|
|
148
|
+
const s = p.spinner();
|
|
149
|
+
s.start('Fetching component list');
|
|
150
|
+
const components = await fetchComponents();
|
|
151
|
+
s.stop(`Found ${components.length} components`);
|
|
152
|
+
installComponents(pm, projectPath, components);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
p.log.warn(`Component installation skipped: ${error.message}`);
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
p.log.info('Skipped component installation (--no-components)');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// specify agent config
|
|
161
|
+
let agent = flags.agent;
|
|
162
|
+
if (!agent) {
|
|
163
|
+
agent = await p.select({
|
|
164
|
+
message: 'Install AI agent configuration?',
|
|
165
|
+
options: [
|
|
166
|
+
{ value: 'none', label: 'None' },
|
|
167
|
+
{ value: 'cursor', label: 'Cursor', hint: 'AGENTS.md + skills + rules' },
|
|
168
|
+
{ value: 'claude', label: 'Claude Code', hint: 'CLAUDE.md + skills + rules' }
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
if (p.isCancel(agent)) {
|
|
172
|
+
p.cancel('Setup cancelled.');
|
|
173
|
+
process.exit(0);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const validAgents = ['cursor', 'claude', 'none'];
|
|
178
|
+
if (!validAgents.includes(agent)) {
|
|
179
|
+
p.log.error(`Invalid --codeagent value "${agent}". Must be one of: ${validAgents.join(', ')}`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (agent !== 'none') {
|
|
184
|
+
installAgentConfig(projectPath, agent);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// summary
|
|
188
|
+
const summary = [
|
|
189
|
+
`Location: ${projectPath}`,
|
|
190
|
+
`Package Manager: ${pm.name}`,
|
|
191
|
+
`Fonts: ${includeFonts ? 'installed' : 'skipped'}`,
|
|
192
|
+
`Components: ${flags.components ? 'all' : 'skipped'}`,
|
|
193
|
+
`Agent Config: ${agent}`
|
|
194
|
+
].join('\n');
|
|
195
|
+
|
|
196
|
+
p.note(summary, 'Summary');
|
|
197
|
+
|
|
198
|
+
p.outro('You are all set!');
|
|
199
|
+
}
|