procedure-cli 0.1.8 → 0.1.9
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/dist/app.js +6 -2
- package/dist/app.js.map +1 -1
- package/dist/lib/types.d.ts +1 -0
- package/dist/steps/generation.js +6 -53
- package/dist/steps/generation.js.map +1 -1
- package/dist/steps/powerline.js +32 -24
- package/dist/steps/powerline.js.map +1 -1
- package/dist/steps/stack-style.js +145 -40
- package/dist/steps/stack-style.js.map +1 -1
- package/package.json +1 -1
- package/src/app.tsx +4 -2
- package/src/lib/types.ts +2 -1
- package/src/steps/generation.tsx +18 -117
- package/src/steps/powerline.tsx +120 -32
- package/src/steps/stack-style.tsx +158 -56
|
@@ -9,13 +9,149 @@ interface Props {
|
|
|
9
9
|
onComplete: (answers: Partial<WizardAnswers>) => void;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
type Mode = "
|
|
12
|
+
type Mode = "quickstart" | "advanced";
|
|
13
13
|
type AdvancedStep = "language" | "framework" | "codeStyle";
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// ─── Presets ────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
interface Preset {
|
|
18
|
+
label: string;
|
|
19
|
+
description: string;
|
|
20
|
+
answers: Partial<WizardAnswers>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const PRESETS: Record<string, Preset> = {
|
|
24
|
+
"typescript-node": {
|
|
25
|
+
label: "TypeScript + Node.js",
|
|
26
|
+
description: "Best for: CLI tools, backend APIs, npm packages, scripts",
|
|
27
|
+
answers: {
|
|
28
|
+
language: "TypeScript",
|
|
29
|
+
framework: "Node.js",
|
|
30
|
+
codeStyle: [
|
|
31
|
+
"TypeScript strict mode, ESM imports",
|
|
32
|
+
"camelCase for variables, PascalCase for types",
|
|
33
|
+
"stdlib → external → internal import ordering",
|
|
34
|
+
"Return errors, don't throw",
|
|
35
|
+
],
|
|
36
|
+
buildCommand: "tsc",
|
|
37
|
+
testCommand: "node --test",
|
|
38
|
+
typecheckCommand: "tsc --noEmit",
|
|
39
|
+
lintCommand: "eslint src/",
|
|
40
|
+
prCommand: "npm run typecheck && npm run test",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
"nextjs-fullstack": {
|
|
44
|
+
label: "Next.js Full-Stack",
|
|
45
|
+
description: "Best for: SaaS apps, marketing sites, SSR/SSG, API routes",
|
|
46
|
+
answers: {
|
|
47
|
+
language: "TypeScript",
|
|
48
|
+
framework: "Next.js",
|
|
49
|
+
codeStyle: [
|
|
50
|
+
"TypeScript strict mode",
|
|
51
|
+
"camelCase for variables, PascalCase for components",
|
|
52
|
+
"Server components by default, client components only when needed",
|
|
53
|
+
"Co-locate components with their routes",
|
|
54
|
+
],
|
|
55
|
+
buildCommand: "next build",
|
|
56
|
+
testCommand: "vitest",
|
|
57
|
+
typecheckCommand: "tsc --noEmit",
|
|
58
|
+
lintCommand: "next lint",
|
|
59
|
+
prCommand: "npm run typecheck && npm run lint",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
"react-spa": {
|
|
63
|
+
label: "React SPA",
|
|
64
|
+
description: "Best for: Dashboards, admin panels, SPAs without SSR",
|
|
65
|
+
answers: {
|
|
66
|
+
language: "TypeScript",
|
|
67
|
+
framework: "React",
|
|
68
|
+
codeStyle: [
|
|
69
|
+
"TypeScript strict mode",
|
|
70
|
+
"Functional components only, no class components",
|
|
71
|
+
"Prefer functional patterns, immutability",
|
|
72
|
+
"camelCase for variables, PascalCase for components",
|
|
73
|
+
],
|
|
74
|
+
buildCommand: "vite build",
|
|
75
|
+
testCommand: "vitest",
|
|
76
|
+
typecheckCommand: "tsc --noEmit",
|
|
77
|
+
lintCommand: "eslint src/",
|
|
78
|
+
prCommand: "npm run typecheck && npm run test",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
"python-fastapi": {
|
|
82
|
+
label: "Python + FastAPI",
|
|
83
|
+
description: "Best for: AI/ML backends, REST APIs, data services",
|
|
84
|
+
answers: {
|
|
85
|
+
language: "Python",
|
|
86
|
+
framework: "FastAPI",
|
|
87
|
+
codeStyle: [
|
|
88
|
+
"Type hints on all functions and class attributes",
|
|
89
|
+
"Black formatting, 88 char line length",
|
|
90
|
+
"Pydantic models for request/response schemas",
|
|
91
|
+
"Return errors explicitly, avoid bare exceptions",
|
|
92
|
+
],
|
|
93
|
+
buildCommand: "python -m py_compile src/",
|
|
94
|
+
testCommand: "pytest",
|
|
95
|
+
typecheckCommand: "mypy .",
|
|
96
|
+
lintCommand: "ruff check .",
|
|
97
|
+
prCommand: "mypy . && pytest",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
"go-service": {
|
|
101
|
+
label: "Go HTTP Service",
|
|
102
|
+
description: "Best for: High-perf APIs, microservices, concurrent workloads",
|
|
103
|
+
answers: {
|
|
104
|
+
language: "Go",
|
|
105
|
+
framework: "net/http",
|
|
106
|
+
codeStyle: [
|
|
107
|
+
"gofmt enforced, no exceptions",
|
|
108
|
+
"Errors are values — always handle, never ignore",
|
|
109
|
+
"Table-driven tests with t.Run subtests",
|
|
110
|
+
"Keep interfaces small, accept interfaces return structs",
|
|
111
|
+
],
|
|
112
|
+
buildCommand: "go build ./...",
|
|
113
|
+
testCommand: "go test ./...",
|
|
114
|
+
typecheckCommand: "go vet ./...",
|
|
115
|
+
lintCommand: "golangci-lint run",
|
|
116
|
+
prCommand: "go vet ./... && go test ./...",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
"react-native-expo": {
|
|
120
|
+
label: "React Native + Expo",
|
|
121
|
+
description: "Best for: Cross-platform mobile apps (iOS + Android)",
|
|
122
|
+
answers: {
|
|
123
|
+
language: "TypeScript",
|
|
124
|
+
framework: "React Native",
|
|
125
|
+
codeStyle: [
|
|
126
|
+
"TypeScript strict mode",
|
|
127
|
+
"Functional components with hooks",
|
|
128
|
+
"StyleSheet.create for styles, no inline objects",
|
|
129
|
+
"Platform-specific code via Platform.select or .ios.tsx / .android.tsx",
|
|
130
|
+
],
|
|
131
|
+
buildCommand: "expo build",
|
|
132
|
+
testCommand: "jest",
|
|
133
|
+
typecheckCommand: "tsc --noEmit",
|
|
134
|
+
lintCommand: "eslint .",
|
|
135
|
+
prCommand: "npm run typecheck && npm run test",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const QUICKSTART_OPTIONS = [
|
|
141
|
+
...Object.entries(PRESETS).map(([value, preset]) => ({
|
|
142
|
+
label: preset.label,
|
|
143
|
+
value,
|
|
144
|
+
description: preset.description,
|
|
145
|
+
})),
|
|
146
|
+
{
|
|
147
|
+
label: "Configure manually →",
|
|
148
|
+
value: "advanced",
|
|
149
|
+
description: "Choose languages, frameworks, and code style step by step",
|
|
150
|
+
},
|
|
17
151
|
];
|
|
18
152
|
|
|
153
|
+
// ─── Advanced options ────────────────────────────────────────────────────────
|
|
154
|
+
|
|
19
155
|
const LANGUAGE_OPTIONS = [
|
|
20
156
|
{ label: "TypeScript", value: "TypeScript", description: "Typed JavaScript, strict mode recommended" },
|
|
21
157
|
{ label: "JavaScript", value: "JavaScript", description: "Dynamic, runs everywhere" },
|
|
@@ -57,83 +193,49 @@ const CODE_STYLE_OPTIONS = [
|
|
|
57
193
|
function getFrameworkPreselect(languages: string[]): string[] {
|
|
58
194
|
const langSet = new Set(languages.map((l) => l.toLowerCase()));
|
|
59
195
|
const preselect: string[] = [];
|
|
60
|
-
if (langSet.has("typescript") || langSet.has("javascript"))
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (langSet.has("python")) {
|
|
64
|
-
preselect.push("Django");
|
|
65
|
-
}
|
|
66
|
-
if (langSet.has("ruby")) {
|
|
67
|
-
preselect.push("Rails");
|
|
68
|
-
}
|
|
196
|
+
if (langSet.has("typescript") || langSet.has("javascript")) preselect.push("Node.js");
|
|
197
|
+
if (langSet.has("python")) preselect.push("Django");
|
|
198
|
+
if (langSet.has("ruby")) preselect.push("Rails");
|
|
69
199
|
return preselect;
|
|
70
200
|
}
|
|
71
201
|
|
|
72
|
-
|
|
73
|
-
"typescript-node": {
|
|
74
|
-
language: "TypeScript",
|
|
75
|
-
framework: "Node.js",
|
|
76
|
-
codeStyle: [
|
|
77
|
-
"TypeScript strict mode, ESM imports",
|
|
78
|
-
"camelCase for variables, PascalCase for types",
|
|
79
|
-
"stdlib -> external -> internal import ordering",
|
|
80
|
-
"Return errors, don't throw",
|
|
81
|
-
],
|
|
82
|
-
buildCommand: "npm run build",
|
|
83
|
-
testCommand: "npm run test",
|
|
84
|
-
typecheckCommand: "npm run typecheck",
|
|
85
|
-
lintCommand: "npm run lint",
|
|
86
|
-
},
|
|
87
|
-
};
|
|
202
|
+
// ─── Component ───────────────────────────────────────────────────────────────
|
|
88
203
|
|
|
89
204
|
export default function StackStyle({ onComplete }: Props) {
|
|
90
|
-
const [mode, setMode] = useState<Mode>("
|
|
205
|
+
const [mode, setMode] = useState<Mode>("quickstart");
|
|
91
206
|
const [advancedStep, setAdvancedStep] = useState<AdvancedStep>("language");
|
|
92
207
|
const [selectedLanguages, setSelectedLanguages] = useState<string[]>([]);
|
|
93
208
|
const [selectedFrameworks, setSelectedFrameworks] = useState<string[]>([]);
|
|
94
209
|
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<>
|
|
98
|
-
<GutterLine>
|
|
99
|
-
<Text bold>Setup mode:</Text>
|
|
100
|
-
</GutterLine>
|
|
101
|
-
<GutteredSelect
|
|
102
|
-
options={[
|
|
103
|
-
{ label: "QuickStart (use a preset)", value: "quickstart" },
|
|
104
|
-
{ label: "Advanced (manual config)", value: "advanced" },
|
|
105
|
-
]}
|
|
106
|
-
onChange={(val) => setMode(val as Mode)}
|
|
107
|
-
/>
|
|
108
|
-
</>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
210
|
+
// ── QuickStart ──
|
|
112
211
|
if (mode === "quickstart") {
|
|
113
212
|
return (
|
|
114
213
|
<>
|
|
115
214
|
<GutterLine>
|
|
116
|
-
<Text bold>Select a
|
|
215
|
+
<Text bold>Select a preset:</Text>
|
|
117
216
|
</GutterLine>
|
|
118
217
|
<GutteredSelect
|
|
119
|
-
options={
|
|
218
|
+
options={QUICKSTART_OPTIONS}
|
|
120
219
|
onChange={(val) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
220
|
+
if (val === "advanced") {
|
|
221
|
+
setMode("advanced");
|
|
222
|
+
return;
|
|
124
223
|
}
|
|
224
|
+
const preset = PRESETS[val];
|
|
225
|
+
if (preset) onComplete(preset.answers);
|
|
125
226
|
}}
|
|
126
227
|
/>
|
|
127
228
|
</>
|
|
128
229
|
);
|
|
129
230
|
}
|
|
130
231
|
|
|
131
|
-
// Advanced
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (advStep === "language") {
|
|
232
|
+
// ── Advanced ──
|
|
233
|
+
if (advancedStep === "language") {
|
|
135
234
|
return (
|
|
136
235
|
<>
|
|
236
|
+
<GutterLine>
|
|
237
|
+
<Text color={C.overlay1}>Mode: manual configuration</Text>
|
|
238
|
+
</GutterLine>
|
|
137
239
|
<GutterLine>
|
|
138
240
|
<Text bold>Programming languages:</Text>
|
|
139
241
|
</GutterLine>
|
|
@@ -150,7 +252,7 @@ export default function StackStyle({ onComplete }: Props) {
|
|
|
150
252
|
);
|
|
151
253
|
}
|
|
152
254
|
|
|
153
|
-
if (
|
|
255
|
+
if (advancedStep === "framework") {
|
|
154
256
|
return (
|
|
155
257
|
<>
|
|
156
258
|
<GutterLine>
|