base-themes 0.1.2 → 0.1.3
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/CHANGELOG.md +25 -0
- package/CODE_OF_CONDUCT.md +22 -0
- package/CONTRIBUTING.md +98 -0
- package/LICENSE +21 -0
- package/README.md +316 -3
- package/RELEASE.md +80 -0
- package/SECURITY.md +49 -0
- package/bin/base-themes.mjs +143 -0
- package/dist/base-themes.css +1 -1
- package/dist/base-themes.js +857 -302
- package/dist/llms-full.txt +288 -0
- package/dist/llms.txt +79 -0
- package/dist/types/blocks/AuthCard.d.ts +2 -0
- package/dist/types/blocks/CommandPaletteBlock.d.ts +2 -0
- package/dist/types/blocks/DashboardShell.d.ts +2 -0
- package/dist/types/blocks/DataTableBlock.d.ts +2 -0
- package/dist/types/blocks/PricingPanel.d.ts +2 -0
- package/dist/types/blocks/SettingsForm.d.ts +2 -0
- package/dist/types/blocks/TeamActivityFeed.d.ts +2 -0
- package/dist/types/blocks/ThemeShowcaseCard.d.ts +2 -0
- package/dist/types/blocks/index.d.ts +8 -0
- package/dist/types/components/ui/Input.d.ts +3 -0
- package/dist/types/components/ui/index.d.ts +1 -1
- package/dist/types/lib.d.ts +1 -0
- package/docs/adoption-dashboard.md +149 -0
- package/docs/analytics-setup.md +145 -0
- package/docs/community-gallery-proposal.md +64 -0
- package/docs/community-proof-telemetry.md +47 -0
- package/docs/contributor-issue-seeds.md +240 -0
- package/docs/registry-access-telemetry.md +87 -0
- package/docs/release-announcement-kit.md +229 -0
- package/docs/search-console-setup.md +111 -0
- package/docs/theme-token-contract.md +113 -0
- package/examples/dashboard/README.md +24 -0
- package/examples/dashboard/index.html +12 -0
- package/examples/dashboard/package-lock.json +1212 -0
- package/examples/dashboard/package.json +24 -0
- package/examples/dashboard/src/App.tsx +115 -0
- package/examples/dashboard/src/main.tsx +11 -0
- package/examples/dashboard/src/styles.css +129 -0
- package/examples/dashboard/src/vite-env.d.ts +4 -0
- package/examples/dashboard/tsconfig.app.json +23 -0
- package/examples/dashboard/tsconfig.json +7 -0
- package/examples/dashboard/tsconfig.node.json +15 -0
- package/examples/dashboard/vite.config.ts +6 -0
- package/examples/next/README.md +29 -0
- package/examples/next/app/base-themes-demo.tsx +70 -0
- package/examples/next/app/layout.tsx +16 -0
- package/examples/next/app/page.tsx +9 -0
- package/examples/next/app/styles.css +106 -0
- package/examples/next/next-env.d.ts +6 -0
- package/examples/next/next.config.ts +5 -0
- package/examples/next/package-lock.json +1199 -0
- package/examples/next/package.json +27 -0
- package/examples/next/tsconfig.json +36 -0
- package/examples/registry-copy/README.md +73 -0
- package/examples/registry-copy/plan-copy.mjs +130 -0
- package/examples/theme-customization/README.md +26 -0
- package/examples/theme-customization/index.html +12 -0
- package/examples/theme-customization/package-lock.json +1212 -0
- package/examples/theme-customization/package.json +24 -0
- package/examples/theme-customization/src/App.tsx +138 -0
- package/examples/theme-customization/src/main.tsx +11 -0
- package/examples/theme-customization/src/styles.css +138 -0
- package/examples/theme-customization/src/vite-env.d.ts +4 -0
- package/examples/theme-customization/tsconfig.app.json +23 -0
- package/examples/theme-customization/tsconfig.json +7 -0
- package/examples/theme-customization/tsconfig.node.json +15 -0
- package/examples/theme-customization/vite.config.ts +6 -0
- package/examples/vite/README.md +32 -0
- package/examples/vite/index.html +12 -0
- package/examples/vite/package-lock.json +1200 -0
- package/examples/vite/package.json +24 -0
- package/examples/vite/src/App.tsx +101 -0
- package/examples/vite/src/main.tsx +11 -0
- package/examples/vite/src/styles.css +125 -0
- package/examples/vite/src/vite-env.d.ts +4 -0
- package/examples/vite/tsconfig.app.json +23 -0
- package/examples/vite/tsconfig.json +7 -0
- package/examples/vite/tsconfig.node.json +15 -0
- package/examples/vite/vite.config.ts +6 -0
- package/llms-full.txt +288 -0
- package/llms.txt +79 -0
- package/package.json +157 -14
- package/registry/items/accordion.json +101 -0
- package/registry/items/alert-dialog.json +107 -0
- package/registry/items/autocomplete.json +106 -0
- package/registry/items/avatar.json +101 -0
- package/registry/items/block-auth-card.json +105 -0
- package/registry/items/block-command-palette.json +99 -0
- package/registry/items/block-dashboard-shell.json +101 -0
- package/registry/items/block-data-table.json +99 -0
- package/registry/items/block-pricing-panel.json +99 -0
- package/registry/items/block-settings-form.json +107 -0
- package/registry/items/block-team-activity-feed.json +99 -0
- package/registry/items/block-theme-showcase-card.json +99 -0
- package/registry/items/button.json +102 -0
- package/registry/items/checkbox-group.json +106 -0
- package/registry/items/checkbox.json +102 -0
- package/registry/items/collapsible.json +101 -0
- package/registry/items/combobox.json +101 -0
- package/registry/items/context-menu.json +106 -0
- package/registry/items/csp-provider.json +96 -0
- package/registry/items/dialog.json +102 -0
- package/registry/items/direction-provider.json +101 -0
- package/registry/items/drawer.json +101 -0
- package/registry/items/field.json +101 -0
- package/registry/items/fieldset.json +101 -0
- package/registry/items/form.json +101 -0
- package/registry/items/input.json +102 -0
- package/registry/items/menu.json +101 -0
- package/registry/items/menubar.json +106 -0
- package/registry/items/meter.json +101 -0
- package/registry/items/navigation-menu.json +101 -0
- package/registry/items/number-field.json +101 -0
- package/registry/items/otp-field.json +101 -0
- package/registry/items/popover.json +102 -0
- package/registry/items/preview-card.json +101 -0
- package/registry/items/progress.json +101 -0
- package/registry/items/radio-group.json +102 -0
- package/registry/items/radio.json +101 -0
- package/registry/items/scroll-area.json +101 -0
- package/registry/items/select.json +102 -0
- package/registry/items/separator.json +101 -0
- package/registry/items/slider.json +102 -0
- package/registry/items/switch.json +102 -0
- package/registry/items/tabs.json +101 -0
- package/registry/items/theme-bauhaus.json +107 -0
- package/registry/items/theme-bento.json +107 -0
- package/registry/items/theme-calm.json +107 -0
- package/registry/items/theme-cyberpunk.json +108 -0
- package/registry/items/theme-data-dense.json +107 -0
- package/registry/items/theme-editorial.json +107 -0
- package/registry/items/theme-enterprise.json +108 -0
- package/registry/items/theme-fluent.json +107 -0
- package/registry/items/theme-glass.json +107 -0
- package/registry/items/theme-linear.json +107 -0
- package/registry/items/theme-luxury.json +107 -0
- package/registry/items/theme-material.json +107 -0
- package/registry/items/theme-minimal.json +107 -0
- package/registry/items/theme-mono.json +107 -0
- package/registry/items/theme-neo-brutalism.json +107 -0
- package/registry/items/theme-playful.json +107 -0
- package/registry/items/theme-retro.json +107 -0
- package/registry/items/theme-shadcn.json +107 -0
- package/registry/items/theme-soft-ui.json +107 -0
- package/registry/items/theme-terminal.json +107 -0
- package/registry/items/toast.json +106 -0
- package/registry/items/toggle-group.json +101 -0
- package/registry/items/toggle.json +101 -0
- package/registry/items/toolbar.json +101 -0
- package/registry/items/tooltip.json +102 -0
- package/registry/registry.json +564 -49
- package/registry/shadcn-registry.json +415 -0
- package/research/telemetry-fixtures/analytics-events.jsonl +9 -0
- package/research/telemetry-fixtures/bundle-report.json +44 -0
- package/research/telemetry-fixtures/community-proof.csv +5 -0
- package/research/telemetry-fixtures/registry-access.jsonl +10 -0
- package/research/telemetry-fixtures/search-console-export.csv +4 -0
- package/scripts/registry-plan.mjs +434 -0
- package/scripts/render-launch-actions.mjs +405 -0
- package/scripts/render-launch-status.mjs +373 -0
- package/scripts/render-release-announcement.mjs +329 -0
- package/scripts/verify-launch-readiness.mjs +415 -0
- package/scripts/verify-telemetry-fixtures.mjs +85 -0
- package/scripts/verify-telemetry-report.mjs +89 -0
- package/skills/base-themes/SKILL.md +151 -47
- package/src/blocks/AuthCard.tsx +29 -0
- package/src/blocks/Blocks.css +182 -0
- package/src/blocks/CommandPaletteBlock.tsx +32 -0
- package/src/blocks/DashboardShell.tsx +36 -0
- package/src/blocks/DataTableBlock.tsx +44 -0
- package/src/blocks/PricingPanel.tsx +28 -0
- package/src/blocks/SettingsForm.tsx +37 -0
- package/src/blocks/TeamActivityFeed.tsx +38 -0
- package/src/blocks/ThemeShowcaseCard.tsx +32 -0
- package/src/blocks/index.ts +8 -0
- package/src/components/ui/Accordion.css +42 -0
- package/src/components/ui/Accordion.tsx +41 -0
- package/src/components/ui/AlertDialog.css +40 -0
- package/src/components/ui/AlertDialog.tsx +52 -0
- package/src/components/ui/Autocomplete.css +3 -0
- package/src/components/ui/Autocomplete.tsx +50 -0
- package/src/components/ui/Avatar.css +45 -0
- package/src/components/ui/Avatar.tsx +36 -0
- package/src/components/ui/Button.css +79 -0
- package/src/components/ui/Button.tsx +20 -0
- package/src/components/ui/Checkbox.css +37 -0
- package/src/components/ui/Checkbox.tsx +32 -0
- package/src/components/ui/CheckboxGroup.tsx +21 -0
- package/src/components/ui/Collapsible.css +34 -0
- package/src/components/ui/Collapsible.tsx +29 -0
- package/src/components/ui/Combobox.css +75 -0
- package/src/components/ui/Combobox.tsx +53 -0
- package/src/components/ui/ContextMenu.css +9 -0
- package/src/components/ui/ContextMenu.tsx +47 -0
- package/src/components/ui/CspProvider.tsx +10 -0
- package/src/components/ui/Dialog.css +41 -0
- package/src/components/ui/Dialog.tsx +45 -0
- package/src/components/ui/DirectionProvider.tsx +17 -0
- package/src/components/ui/Drawer.css +77 -0
- package/src/components/ui/Drawer.tsx +56 -0
- package/src/components/ui/Field.css +19 -0
- package/src/components/ui/Field.tsx +24 -0
- package/src/components/ui/Fieldset.css +16 -0
- package/src/components/ui/Fieldset.tsx +19 -0
- package/src/components/ui/Form.css +5 -0
- package/src/components/ui/Form.tsx +12 -0
- package/src/components/ui/Input.css +50 -0
- package/src/components/ui/Input.tsx +62 -0
- package/src/components/ui/Menu.css +59 -0
- package/src/components/ui/Menu.tsx +50 -0
- package/src/components/ui/Menubar.css +26 -0
- package/src/components/ui/Menubar.tsx +42 -0
- package/src/components/ui/Meter.css +45 -0
- package/src/components/ui/Meter.tsx +37 -0
- package/src/components/ui/NavigationMenu.css +103 -0
- package/src/components/ui/NavigationMenu.tsx +64 -0
- package/src/components/ui/NumberField.css +38 -0
- package/src/components/ui/NumberField.tsx +28 -0
- package/src/components/ui/OtpField.css +28 -0
- package/src/components/ui/OtpField.tsx +24 -0
- package/src/components/ui/Popover.css +25 -0
- package/src/components/ui/Popover.tsx +37 -0
- package/src/components/ui/PreviewCard.css +33 -0
- package/src/components/ui/PreviewCard.tsx +43 -0
- package/src/components/ui/Progress.css +33 -0
- package/src/components/ui/Progress.tsx +28 -0
- package/src/components/ui/Radio.tsx +22 -0
- package/src/components/ui/RadioGroup.css +42 -0
- package/src/components/ui/RadioGroup.tsx +29 -0
- package/src/components/ui/ScrollArea.css +42 -0
- package/src/components/ui/ScrollArea.tsx +22 -0
- package/src/components/ui/Select.css +86 -0
- package/src/components/ui/Select.tsx +39 -0
- package/src/components/ui/Separator.css +14 -0
- package/src/components/ui/Separator.tsx +12 -0
- package/src/components/ui/Slider.css +39 -0
- package/src/components/ui/Slider.tsx +21 -0
- package/src/components/ui/Switch.css +45 -0
- package/src/components/ui/Switch.tsx +29 -0
- package/src/components/ui/Tabs.css +72 -0
- package/src/components/ui/Tabs.tsx +44 -0
- package/src/components/ui/Toast.css +75 -0
- package/src/components/ui/Toast.tsx +48 -0
- package/src/components/ui/Toggle.tsx +12 -0
- package/src/components/ui/ToggleGroup.css +35 -0
- package/src/components/ui/ToggleGroup.tsx +30 -0
- package/src/components/ui/Toolbar.css +60 -0
- package/src/components/ui/Toolbar.tsx +36 -0
- package/src/components/ui/Tooltip.css +14 -0
- package/src/components/ui/Tooltip.tsx +31 -0
- package/src/components/ui/index.ts +83 -0
- package/src/components/ui/useDirection.ts +1 -0
- package/src/components/ui/useToastManager.ts +11 -0
- package/src/docs/blockMeta.json +66 -0
- package/src/docs/componentMeta.json +322 -0
- package/src/docs/staticPageMeta.json +143 -0
- package/src/docs/themeMeta.json +22 -0
- package/src/styles/tokenContract.json +61 -0
- package/workers/analytics-receiver.mjs +170 -0
- package/wrangler.analytics.jsonc +12 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
Base Themes is a public npm package for React applications. Security reports are handled through GitHub so fixes can be coordinated before public disclosure.
|
|
4
|
+
|
|
5
|
+
## Supported Versions
|
|
6
|
+
|
|
7
|
+
Security fixes target the latest published minor version of `base-themes`. Older versions may receive guidance, but patches are not guaranteed until the project has a stable major release policy.
|
|
8
|
+
|
|
9
|
+
## Reporting a Vulnerability
|
|
10
|
+
|
|
11
|
+
Use GitHub private vulnerability reporting if it is enabled for the repository. If it is not available, open a minimal public issue that says you need a private security contact, without including exploit details.
|
|
12
|
+
|
|
13
|
+
Do not include secrets, tokens, private keys, customer data, or production credentials in a report.
|
|
14
|
+
|
|
15
|
+
Please include:
|
|
16
|
+
|
|
17
|
+
- Affected package version.
|
|
18
|
+
- Affected component, script, workflow, or registry entry.
|
|
19
|
+
- Reproduction steps or proof of concept.
|
|
20
|
+
- Impact and likely attack scenario.
|
|
21
|
+
- Any known mitigation.
|
|
22
|
+
|
|
23
|
+
## Response Expectations
|
|
24
|
+
|
|
25
|
+
- Initial triage target: 3 business days.
|
|
26
|
+
- Fix or mitigation target: depends on severity and reproducibility.
|
|
27
|
+
- Public disclosure: after a patched release or clear mitigation is available.
|
|
28
|
+
|
|
29
|
+
## Supply Chain Posture
|
|
30
|
+
|
|
31
|
+
- Releases are published by GitHub Actions using npm provenance.
|
|
32
|
+
- CI runs registry validation, lint, and build before publish.
|
|
33
|
+
- Runtime dependencies are intentionally small.
|
|
34
|
+
- Dependency updates are managed through Dependabot once configured.
|
|
35
|
+
|
|
36
|
+
## Scope
|
|
37
|
+
|
|
38
|
+
In scope:
|
|
39
|
+
|
|
40
|
+
- Package source and bundled output.
|
|
41
|
+
- Registry metadata that could cause unsafe installs or copied files.
|
|
42
|
+
- GitHub Actions workflows and release pipeline.
|
|
43
|
+
- Documentation examples that create unsafe defaults.
|
|
44
|
+
|
|
45
|
+
Out of scope:
|
|
46
|
+
|
|
47
|
+
- Vulnerabilities in user applications after local modifications.
|
|
48
|
+
- Issues requiring access to private user environments.
|
|
49
|
+
- Social engineering or spam reports.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createDoctorReport, createRegistryAdd, createRegistryPlan, formatDoctorReport, formatRegistryAdd, formatRegistryList, formatRegistryPlan, loadRegistry } from '../scripts/registry-plan.mjs'
|
|
3
|
+
|
|
4
|
+
const [command, ...args] = process.argv.slice(2)
|
|
5
|
+
const registry = loadRegistry(new URL('../registry/registry.json', import.meta.url))
|
|
6
|
+
|
|
7
|
+
function printHelp() {
|
|
8
|
+
console.log(`Base Themes CLI
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
base-themes list [--json]
|
|
12
|
+
base-themes plan <component...> [block:<block-name>...] [theme:<style>...] [--json]
|
|
13
|
+
base-themes add <component...> [block:<block-name>...] [theme:<style>...] [--target <dir>] [--dry-run] [--force] [--json]
|
|
14
|
+
base-themes doctor [project-root] [--json]
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
base-themes list
|
|
18
|
+
base-themes list --json
|
|
19
|
+
base-themes plan button select block:dashboard-shell theme:enterprise
|
|
20
|
+
base-themes plan button select block:dashboard-shell theme:enterprise --json
|
|
21
|
+
base-themes add button select block:dashboard-shell theme:enterprise --target . --dry-run
|
|
22
|
+
base-themes doctor . --json
|
|
23
|
+
`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseRegistryArgs(args) {
|
|
27
|
+
const requested = []
|
|
28
|
+
const options = {}
|
|
29
|
+
|
|
30
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
31
|
+
const arg = args[index]
|
|
32
|
+
if (arg === '--dry-run') {
|
|
33
|
+
options.dryRun = true
|
|
34
|
+
continue
|
|
35
|
+
}
|
|
36
|
+
if (arg === '--force') {
|
|
37
|
+
options.force = true
|
|
38
|
+
continue
|
|
39
|
+
}
|
|
40
|
+
if (arg === '--json') {
|
|
41
|
+
options.json = true
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
if (arg === '--target') {
|
|
45
|
+
const target = args[index + 1]
|
|
46
|
+
if (!target) throw new Error('Missing value for --target')
|
|
47
|
+
options.target = target
|
|
48
|
+
index += 1
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
if (arg.startsWith('--target=')) {
|
|
52
|
+
options.target = arg.slice('--target='.length)
|
|
53
|
+
continue
|
|
54
|
+
}
|
|
55
|
+
if (arg.startsWith('--')) throw new Error(`Unknown add option: ${arg}`)
|
|
56
|
+
requested.push(arg)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { requested, options }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function printResult(value, json, formatter) {
|
|
63
|
+
console.log(json ? JSON.stringify(value, null, 2) : formatter(value))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
67
|
+
printHelp()
|
|
68
|
+
process.exit(0)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (command === 'list') {
|
|
72
|
+
const json = args.includes('--json')
|
|
73
|
+
const unknownArgs = args.filter((arg) => arg !== '--json')
|
|
74
|
+
if (unknownArgs.length > 0) {
|
|
75
|
+
console.error(`Unknown list option: ${unknownArgs[0]}`)
|
|
76
|
+
console.error('Usage: base-themes list [--json]')
|
|
77
|
+
process.exit(1)
|
|
78
|
+
}
|
|
79
|
+
printResult(registry, json, formatRegistryList)
|
|
80
|
+
process.exit(0)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (command === 'plan') {
|
|
84
|
+
let parsed
|
|
85
|
+
try {
|
|
86
|
+
parsed = parseRegistryArgs(args)
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(error.message)
|
|
89
|
+
console.error('Usage: base-themes plan <component...> [block:<block-name>...] [theme:<style>...] [--json]')
|
|
90
|
+
process.exit(1)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (parsed.requested.length === 0) {
|
|
94
|
+
console.error('Usage: base-themes plan <component...> [block:<block-name>...] [theme:<style>...] [--json]')
|
|
95
|
+
process.exit(1)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const plan = createRegistryPlan(registry, parsed.requested)
|
|
99
|
+
printResult(plan, parsed.options.json, formatRegistryPlan)
|
|
100
|
+
process.exit(plan.ok ? 0 : 1)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (command === 'add') {
|
|
104
|
+
let parsed
|
|
105
|
+
try {
|
|
106
|
+
parsed = parseRegistryArgs(args)
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error(error.message)
|
|
109
|
+
console.error('Usage: base-themes add <component...> [block:<block-name>...] [theme:<style>...] [--target <dir>] [--dry-run] [--force] [--json]')
|
|
110
|
+
process.exit(1)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (parsed.requested.length === 0) {
|
|
114
|
+
console.error('Usage: base-themes add <component...> [block:<block-name>...] [theme:<style>...] [--target <dir>] [--dry-run] [--force] [--json]')
|
|
115
|
+
process.exit(1)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const result = createRegistryAdd(registry, parsed.requested, parsed.options)
|
|
119
|
+
printResult(result, parsed.options.json, formatRegistryAdd)
|
|
120
|
+
process.exit(result.ok ? 0 : 1)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (command === 'doctor') {
|
|
124
|
+
const json = args.includes('--json')
|
|
125
|
+
const positional = args.filter((arg) => arg !== '--json')
|
|
126
|
+
if (positional.some((arg) => arg.startsWith('--'))) {
|
|
127
|
+
console.error(`Unknown doctor option: ${positional.find((arg) => arg.startsWith('--'))}`)
|
|
128
|
+
console.error('Usage: base-themes doctor [project-root] [--json]')
|
|
129
|
+
process.exit(1)
|
|
130
|
+
}
|
|
131
|
+
if (positional.length > 1) {
|
|
132
|
+
console.error('Usage: base-themes doctor [project-root] [--json]')
|
|
133
|
+
process.exit(1)
|
|
134
|
+
}
|
|
135
|
+
const root = positional[0] ?? process.cwd()
|
|
136
|
+
const report = createDoctorReport(root)
|
|
137
|
+
printResult(report, json, formatDoctorReport)
|
|
138
|
+
process.exit(report.ok ? 0 : 1)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.error(`Unknown command: ${command}`)
|
|
142
|
+
printHelp()
|
|
143
|
+
process.exit(1)
|