vibes-plug 1.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.
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/BLUEPRINT.md +125 -0
- package/CHANGELOG.md +195 -0
- package/CONTRIBUTING.md +199 -0
- package/LICENSE +21 -0
- package/README.md +263 -0
- package/SECURITY.md +21 -0
- package/banner.png +0 -0
- package/package.json +25 -0
- package/plugin.json +8 -0
- package/scripts/update_skills.js +75 -0
- package/skills/ai-llm-integration-expert/SKILL.md +162 -0
- package/skills/api-design-expert/SKILL.md +310 -0
- package/skills/app-analyzer-optimizer/SKILL.md +189 -0
- package/skills/asisten_ramah/SKILL.md +41 -0
- package/skills/authentication-identity-expert/SKILL.md +45 -0
- package/skills/auto-doc-updater/SKILL.md +204 -0
- package/skills/bootstrap-to-modern/SKILL.md +87 -0
- package/skills/brainstorming/SKILL.md +353 -0
- package/skills/bun-runtime-expert/SKILL.md +211 -0
- package/skills/ci-cd-devops-architect/SKILL.md +45 -0
- package/skills/cloud-hosting-expert/SKILL.md +244 -0
- package/skills/coderabbit/SKILL.md +192 -0
- package/skills/data-telemetry-expert/SKILL.md +213 -0
- package/skills/database-orm-expert/SKILL.md +294 -0
- package/skills/design-system-architect/SKILL.md +243 -0
- package/skills/e2e-testing-expert/SKILL.md +315 -0
- package/skills/event-driven-architect/SKILL.md +81 -0
- package/skills/firebase-security-expert/SKILL.md +195 -0
- package/skills/fullstack-expert/SKILL.md +202 -0
- package/skills/fullstack-expert/references/api_design_guide.md +466 -0
- package/skills/fullstack-expert/references/devops_infrastructure.md +477 -0
- package/skills/fullstack-expert/references/multi_language_backend.md +528 -0
- package/skills/fullstack-expert/references/system_design_patterns.md +358 -0
- package/skills/fullstack-expert/scripts/api_contract_validator.py +253 -0
- package/skills/fullstack-expert/scripts/architecture_analyzer.py +326 -0
- package/skills/gemini-agent-booster/SKILL.md +135 -0
- package/skills/global-a11y-i18n-expert/SKILL.md +81 -0
- package/skills/go-programming-expert/SKILL.md +295 -0
- package/skills/hig/SKILL.md +188 -0
- package/skills/js-backend-expert/SKILL.md +192 -0
- package/skills/mcp-server-architect/SKILL.md +194 -0
- package/skills/mobile-expo-expert/SKILL.md +186 -0
- package/skills/monday-design-aesthetic/SKILL.md +67 -0
- package/skills/monorepo-architect/SKILL.md +227 -0
- package/skills/mpa-orchestrator/SKILL.md +101 -0
- package/skills/multi-agent-orchestration/SKILL.md +234 -0
- package/skills/multiple-entry-points/SKILL.md +55 -0
- package/skills/mvc-expert/SKILL.md +231 -0
- package/skills/payment-gateway-expert/SKILL.md +45 -0
- package/skills/performance-web-vitals/SKILL.md +332 -0
- package/skills/prd-architect/SKILL.md +191 -0
- package/skills/production-ready-hardener/SKILL.md +469 -0
- package/skills/production-ready-hardener/references/performance_optimization.md +441 -0
- package/skills/production-ready-hardener/references/production_checklist.md +161 -0
- package/skills/production-ready-hardener/references/security_hardening_guide.md +379 -0
- package/skills/production-ready-hardener/scripts/production_readiness_scanner.py +875 -0
- package/skills/python-programming-expert/SKILL.md +271 -0
- package/skills/realtime-collaboration-expert/SKILL.md +45 -0
- package/skills/rust-programming-expert/SKILL.md +235 -0
- package/skills/saas-billing/SKILL.md +377 -0
- package/skills/saas-multi-tenant/SKILL.md +237 -0
- package/skills/saas-mvp-launcher/SKILL.md +231 -0
- package/skills/saas-transformer/SKILL.md +446 -0
- package/skills/saas-transformer/references/billing_integration_guide.md +401 -0
- package/skills/saas-transformer/references/feature_gating_patterns.md +137 -0
- package/skills/saas-transformer/references/saas_transformation_checklist.md +121 -0
- package/skills/saas-transformer/scripts/saas_transformation_scanner.py +254 -0
- package/skills/scalability-clean-code/SKILL.md +229 -0
- package/skills/secure-fuzz-testing/SKILL.md +201 -0
- package/skills/senior-frontend/SKILL.md +161 -0
- package/skills/senior-frontend/references/frontend_best_practices.md +806 -0
- package/skills/senior-frontend/references/nextjs_optimization_guide.md +724 -0
- package/skills/senior-frontend/references/react_patterns.md +746 -0
- package/skills/senior-frontend/scripts/bundle_analyzer.py +407 -0
- package/skills/senior-frontend/scripts/component_generator.py +329 -0
- package/skills/senior-frontend/scripts/frontend_scaffolder.py +1005 -0
- package/skills/senior-fullstack/SKILL.md +167 -0
- package/skills/senior-fullstack/references/architecture_patterns.md +160 -0
- package/skills/senior-fullstack/references/development_workflows.md +222 -0
- package/skills/senior-fullstack/references/tech_stack_guide.md +190 -0
- package/skills/senior-fullstack/scripts/code_quality_analyzer.py +114 -0
- package/skills/senior-fullstack/scripts/fullstack_scaffolder.py +114 -0
- package/skills/senior-fullstack/scripts/project_scaffolder.py +114 -0
- package/skills/seo/SKILL.md +225 -0
- package/skills/seo/references/cwv-thresholds.md +108 -0
- package/skills/seo/references/eeat-framework.md +214 -0
- package/skills/seo/references/quality-gates.md +155 -0
- package/skills/seo/references/schema-types.md +118 -0
- package/skills/seo-aeo-landing-page-writer/SKILL.md +97 -0
- package/skills/seo-geo/SKILL.md +188 -0
- package/skills/session-handoff-resume/SKILL.md +158 -0
- package/skills/skill_baru/SKILL.md +147 -0
- package/skills/spa-orchestrator/SKILL.md +288 -0
- package/skills/state-management-expert/SKILL.md +272 -0
- package/skills/supabase-migration/SKILL.md +45 -0
- package/skills/supabase-security-expert/SKILL.md +243 -0
- package/skills/tailwind-expert/SKILL.md +188 -0
- package/skills/tanstack-query-expert/SKILL.md +199 -0
- package/skills/tauri-expert/SKILL.md +97 -0
- package/skills/token-saver/SKILL.md +111 -0
- package/skills/typescript-expert/SKILL.md +279 -0
- package/skills/ui-components-expert/SKILL.md +63 -0
- package/skills/ui-ux-pro-max/SKILL.md +201 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-310.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-310.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-312.pyc +0 -0
- package/skills/ui-ux-pro-max/scripts/core.py +257 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +493 -0
- package/skills/ui-ux-pro-max/scripts/search.py +81 -0
- package/skills/ui_ux_expert/SKILL.md +114 -0
- package/skills/vibe-code-gardener/SKILL.md +173 -0
- package/skills/web-scraper/SKILL.md +205 -0
- package/skills/web-scraper/references/data-transforms.md +397 -0
- package/skills/web-scraper/references/extraction-patterns.md +475 -0
- package/skills/web-scraper/references/output-templates.md +481 -0
- package/skills/zero-to-prod-orchestrator/SKILL.md +180 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
React Component Generator
|
|
4
|
+
|
|
5
|
+
Generates React/Next.js component files with TypeScript, Tailwind CSS,
|
|
6
|
+
and optional test files following best practices.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python component_generator.py Button --dir src/components/ui
|
|
10
|
+
python component_generator.py ProductCard --type client --with-test
|
|
11
|
+
python component_generator.py UserProfile --type server --with-story
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import argparse
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Component templates
|
|
22
|
+
TEMPLATES = {
|
|
23
|
+
"client": '''\'use client\';
|
|
24
|
+
|
|
25
|
+
import {{ useState }} from 'react';
|
|
26
|
+
import {{ cn }} from '@/lib/utils';
|
|
27
|
+
|
|
28
|
+
interface {name}Props {{
|
|
29
|
+
className?: string;
|
|
30
|
+
children?: React.ReactNode;
|
|
31
|
+
}}
|
|
32
|
+
|
|
33
|
+
export function {name}({{ className, children }}: {name}Props) {{
|
|
34
|
+
return (
|
|
35
|
+
<div className={{cn('', className)}}>
|
|
36
|
+
{{children}}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}}
|
|
40
|
+
''',
|
|
41
|
+
|
|
42
|
+
"server": '''import {{ cn }} from '@/lib/utils';
|
|
43
|
+
|
|
44
|
+
interface {name}Props {{
|
|
45
|
+
className?: string;
|
|
46
|
+
children?: React.ReactNode;
|
|
47
|
+
}}
|
|
48
|
+
|
|
49
|
+
export async function {name}({{ className, children }}: {name}Props) {{
|
|
50
|
+
return (
|
|
51
|
+
<div className={{cn('', className)}}>
|
|
52
|
+
{{children}}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}}
|
|
56
|
+
''',
|
|
57
|
+
|
|
58
|
+
"hook": '''import {{ useState, useEffect, useCallback }} from 'react';
|
|
59
|
+
|
|
60
|
+
interface Use{name}Options {{
|
|
61
|
+
// Add options here
|
|
62
|
+
}}
|
|
63
|
+
|
|
64
|
+
interface Use{name}Return {{
|
|
65
|
+
// Add return type here
|
|
66
|
+
isLoading: boolean;
|
|
67
|
+
error: Error | null;
|
|
68
|
+
}}
|
|
69
|
+
|
|
70
|
+
export function use{name}(options: Use{name}Options = {{}}): Use{name}Return {{
|
|
71
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
72
|
+
const [error, setError] = useState<Error | null>(null);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {{
|
|
75
|
+
// Effect logic here
|
|
76
|
+
}}, []);
|
|
77
|
+
|
|
78
|
+
return {{
|
|
79
|
+
isLoading,
|
|
80
|
+
error,
|
|
81
|
+
}};
|
|
82
|
+
}}
|
|
83
|
+
''',
|
|
84
|
+
|
|
85
|
+
"test": '''import {{ render, screen }} from '@testing-library/react';
|
|
86
|
+
import userEvent from '@testing-library/user-event';
|
|
87
|
+
import {{ {name} }} from './{name}';
|
|
88
|
+
|
|
89
|
+
describe('{name}', () => {{
|
|
90
|
+
it('renders correctly', () => {{
|
|
91
|
+
render(<{name}>Test content</{name}>);
|
|
92
|
+
expect(screen.getByText('Test content')).toBeInTheDocument();
|
|
93
|
+
}});
|
|
94
|
+
|
|
95
|
+
it('applies custom className', () => {{
|
|
96
|
+
render(<{name} className="custom-class">Content</{name}>);
|
|
97
|
+
expect(screen.getByText('Content').parentElement).toHaveClass('custom-class');
|
|
98
|
+
}});
|
|
99
|
+
|
|
100
|
+
// Add more tests here
|
|
101
|
+
}});
|
|
102
|
+
''',
|
|
103
|
+
|
|
104
|
+
"story": '''import type {{ Meta, StoryObj }} from '@storybook/react';
|
|
105
|
+
import {{ {name} }} from './{name}';
|
|
106
|
+
|
|
107
|
+
const meta: Meta<typeof {name}> = {{
|
|
108
|
+
title: 'Components/{name}',
|
|
109
|
+
component: {name},
|
|
110
|
+
tags: ['autodocs'],
|
|
111
|
+
argTypes: {{
|
|
112
|
+
className: {{
|
|
113
|
+
control: 'text',
|
|
114
|
+
description: 'Additional CSS classes',
|
|
115
|
+
}},
|
|
116
|
+
}},
|
|
117
|
+
}};
|
|
118
|
+
|
|
119
|
+
export default meta;
|
|
120
|
+
type Story = StoryObj<typeof {name}>;
|
|
121
|
+
|
|
122
|
+
export const Default: Story = {{
|
|
123
|
+
args: {{
|
|
124
|
+
children: 'Default content',
|
|
125
|
+
}},
|
|
126
|
+
}};
|
|
127
|
+
|
|
128
|
+
export const WithCustomClass: Story = {{
|
|
129
|
+
args: {{
|
|
130
|
+
className: 'bg-blue-100 p-4',
|
|
131
|
+
children: 'Styled content',
|
|
132
|
+
}},
|
|
133
|
+
}};
|
|
134
|
+
''',
|
|
135
|
+
|
|
136
|
+
"index": '''export {{ {name} }} from './{name}';
|
|
137
|
+
export type {{ {name}Props }} from './{name}';
|
|
138
|
+
''',
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def to_pascal_case(name: str) -> str:
|
|
143
|
+
"""Convert string to PascalCase."""
|
|
144
|
+
# Handle kebab-case and snake_case
|
|
145
|
+
words = name.replace('-', '_').split('_')
|
|
146
|
+
return ''.join(word.capitalize() for word in words)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def to_kebab_case(name: str) -> str:
|
|
150
|
+
"""Convert PascalCase to kebab-case."""
|
|
151
|
+
result = []
|
|
152
|
+
for i, char in enumerate(name):
|
|
153
|
+
if char.isupper() and i > 0:
|
|
154
|
+
result.append('-')
|
|
155
|
+
result.append(char.lower())
|
|
156
|
+
return ''.join(result)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def generate_component(
|
|
160
|
+
name: str,
|
|
161
|
+
output_dir: Path,
|
|
162
|
+
component_type: str = "client",
|
|
163
|
+
with_test: bool = False,
|
|
164
|
+
with_story: bool = False,
|
|
165
|
+
with_index: bool = True,
|
|
166
|
+
flat: bool = False,
|
|
167
|
+
) -> dict:
|
|
168
|
+
"""Generate component files."""
|
|
169
|
+
pascal_name = to_pascal_case(name)
|
|
170
|
+
kebab_name = to_kebab_case(pascal_name)
|
|
171
|
+
|
|
172
|
+
# Determine output path
|
|
173
|
+
if flat:
|
|
174
|
+
component_dir = output_dir
|
|
175
|
+
else:
|
|
176
|
+
component_dir = output_dir / pascal_name
|
|
177
|
+
|
|
178
|
+
files_created = []
|
|
179
|
+
|
|
180
|
+
# Create directory
|
|
181
|
+
component_dir.mkdir(parents=True, exist_ok=True)
|
|
182
|
+
|
|
183
|
+
# Generate main component file
|
|
184
|
+
if component_type == "hook":
|
|
185
|
+
main_file = component_dir / f"use{pascal_name}.ts"
|
|
186
|
+
template = TEMPLATES["hook"]
|
|
187
|
+
else:
|
|
188
|
+
main_file = component_dir / f"{pascal_name}.tsx"
|
|
189
|
+
template = TEMPLATES[component_type]
|
|
190
|
+
|
|
191
|
+
content = template.format(name=pascal_name)
|
|
192
|
+
main_file.write_text(content)
|
|
193
|
+
files_created.append(str(main_file))
|
|
194
|
+
|
|
195
|
+
# Generate test file
|
|
196
|
+
if with_test and component_type != "hook":
|
|
197
|
+
test_file = component_dir / f"{pascal_name}.test.tsx"
|
|
198
|
+
test_content = TEMPLATES["test"].format(name=pascal_name)
|
|
199
|
+
test_file.write_text(test_content)
|
|
200
|
+
files_created.append(str(test_file))
|
|
201
|
+
|
|
202
|
+
# Generate story file
|
|
203
|
+
if with_story and component_type != "hook":
|
|
204
|
+
story_file = component_dir / f"{pascal_name}.stories.tsx"
|
|
205
|
+
story_content = TEMPLATES["story"].format(name=pascal_name)
|
|
206
|
+
story_file.write_text(story_content)
|
|
207
|
+
files_created.append(str(story_file))
|
|
208
|
+
|
|
209
|
+
# Generate index file
|
|
210
|
+
if with_index and not flat:
|
|
211
|
+
index_file = component_dir / "index.ts"
|
|
212
|
+
index_content = TEMPLATES["index"].format(name=pascal_name)
|
|
213
|
+
index_file.write_text(index_content)
|
|
214
|
+
files_created.append(str(index_file))
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
"name": pascal_name,
|
|
218
|
+
"type": component_type,
|
|
219
|
+
"directory": str(component_dir),
|
|
220
|
+
"files": files_created,
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def print_result(result: dict, verbose: bool = False) -> None:
|
|
225
|
+
"""Print generation result."""
|
|
226
|
+
print(f"\n{'='*50}")
|
|
227
|
+
print(f"Component Generated: {result['name']}")
|
|
228
|
+
print(f"{'='*50}")
|
|
229
|
+
print(f"Type: {result['type']}")
|
|
230
|
+
print(f"Directory: {result['directory']}")
|
|
231
|
+
print(f"\nFiles created:")
|
|
232
|
+
for file in result['files']:
|
|
233
|
+
print(f" - {file}")
|
|
234
|
+
print(f"{'='*50}\n")
|
|
235
|
+
|
|
236
|
+
# Print usage hint
|
|
237
|
+
if result['type'] != 'hook':
|
|
238
|
+
print("Usage:")
|
|
239
|
+
print(f" import {{ {result['name']} }} from '@/components/{result['name']}';")
|
|
240
|
+
print(f"\n <{result['name']}>Content</{result['name']}>")
|
|
241
|
+
else:
|
|
242
|
+
print("Usage:")
|
|
243
|
+
print(f" import {{ use{result['name']} }} from '@/hooks/use{result['name']}';")
|
|
244
|
+
print(f"\n const {{ isLoading, error }} = use{result['name']}();")
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def main():
|
|
248
|
+
parser = argparse.ArgumentParser(
|
|
249
|
+
description="Generate React/Next.js components with TypeScript and Tailwind CSS"
|
|
250
|
+
)
|
|
251
|
+
parser.add_argument(
|
|
252
|
+
"name",
|
|
253
|
+
help="Component name (PascalCase or kebab-case)"
|
|
254
|
+
)
|
|
255
|
+
parser.add_argument(
|
|
256
|
+
"--dir", "-d",
|
|
257
|
+
default="src/components",
|
|
258
|
+
help="Output directory (default: src/components)"
|
|
259
|
+
)
|
|
260
|
+
parser.add_argument(
|
|
261
|
+
"--type", "-t",
|
|
262
|
+
choices=["client", "server", "hook"],
|
|
263
|
+
default="client",
|
|
264
|
+
help="Component type (default: client)"
|
|
265
|
+
)
|
|
266
|
+
parser.add_argument(
|
|
267
|
+
"--with-test",
|
|
268
|
+
action="store_true",
|
|
269
|
+
help="Generate test file"
|
|
270
|
+
)
|
|
271
|
+
parser.add_argument(
|
|
272
|
+
"--with-story",
|
|
273
|
+
action="store_true",
|
|
274
|
+
help="Generate Storybook story file"
|
|
275
|
+
)
|
|
276
|
+
parser.add_argument(
|
|
277
|
+
"--no-index",
|
|
278
|
+
action="store_true",
|
|
279
|
+
help="Skip generating index.ts file"
|
|
280
|
+
)
|
|
281
|
+
parser.add_argument(
|
|
282
|
+
"--flat",
|
|
283
|
+
action="store_true",
|
|
284
|
+
help="Create files directly in output dir without subdirectory"
|
|
285
|
+
)
|
|
286
|
+
parser.add_argument(
|
|
287
|
+
"--dry-run",
|
|
288
|
+
action="store_true",
|
|
289
|
+
help="Show what would be generated without creating files"
|
|
290
|
+
)
|
|
291
|
+
parser.add_argument(
|
|
292
|
+
"--verbose", "-v",
|
|
293
|
+
action="store_true",
|
|
294
|
+
help="Enable verbose output"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
args = parser.parse_args()
|
|
298
|
+
|
|
299
|
+
output_dir = Path(args.dir)
|
|
300
|
+
pascal_name = to_pascal_case(args.name)
|
|
301
|
+
|
|
302
|
+
if args.dry_run:
|
|
303
|
+
print(f"\nDry run - would generate:")
|
|
304
|
+
print(f" Component: {pascal_name}")
|
|
305
|
+
print(f" Type: {args.type}")
|
|
306
|
+
print(f" Directory: {output_dir / pascal_name if not args.flat else output_dir}")
|
|
307
|
+
print(f" Test: {'Yes' if args.with_test else 'No'}")
|
|
308
|
+
print(f" Story: {'Yes' if args.with_story else 'No'}")
|
|
309
|
+
return
|
|
310
|
+
|
|
311
|
+
try:
|
|
312
|
+
result = generate_component(
|
|
313
|
+
name=args.name,
|
|
314
|
+
output_dir=output_dir,
|
|
315
|
+
component_type=args.type,
|
|
316
|
+
with_test=args.with_test,
|
|
317
|
+
with_story=args.with_story,
|
|
318
|
+
with_index=not args.no_index,
|
|
319
|
+
flat=args.flat,
|
|
320
|
+
)
|
|
321
|
+
print_result(result, args.verbose)
|
|
322
|
+
|
|
323
|
+
except Exception as e:
|
|
324
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
325
|
+
sys.exit(1)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
if __name__ == "__main__":
|
|
329
|
+
main()
|