procedure-cli 0.1.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/.claude/settings.local.json +23 -0
- package/.env.example +2 -0
- package/AGENTS.md +113 -0
- package/CLAUDE.md +136 -0
- package/CODE-FIXED.md +124 -0
- package/CODE-REVIEW.md +253 -0
- package/README.md +130 -0
- package/config/defaults.json +8 -0
- package/config/powerline-config.json +52 -0
- package/config/stacks/typescript-node.json +15 -0
- package/dist/app.d.ts +1 -0
- package/dist/app.js +131 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -0
- package/dist/components/banner.d.ts +1 -0
- package/dist/components/banner.js +11 -0
- package/dist/components/banner.js.map +1 -0
- package/dist/components/gutter-line.d.ts +5 -0
- package/dist/components/gutter-line.js +9 -0
- package/dist/components/gutter-line.js.map +1 -0
- package/dist/components/guttered-select.d.ts +25 -0
- package/dist/components/guttered-select.js +68 -0
- package/dist/components/guttered-select.js.map +1 -0
- package/dist/components/step-indicator.d.ts +7 -0
- package/dist/components/step-indicator.js +12 -0
- package/dist/components/step-indicator.js.map +1 -0
- package/dist/components/timeline.d.ts +13 -0
- package/dist/components/timeline.js +26 -0
- package/dist/components/timeline.js.map +1 -0
- package/dist/lib/fs.d.ts +3 -0
- package/dist/lib/fs.js +15 -0
- package/dist/lib/fs.js.map +1 -0
- package/dist/lib/git.d.ts +4 -0
- package/dist/lib/git.js +37 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/powerline.d.ts +1 -0
- package/dist/lib/powerline.js +30 -0
- package/dist/lib/powerline.js.map +1 -0
- package/dist/lib/template.d.ts +9 -0
- package/dist/lib/template.js +46 -0
- package/dist/lib/template.js.map +1 -0
- package/dist/lib/types.d.ts +44 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/providers/openai.d.ts +1 -0
- package/dist/providers/openai.js +5 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/zai.d.ts +1 -0
- package/dist/providers/zai.js +7 -0
- package/dist/providers/zai.js.map +1 -0
- package/dist/steps/architecture.d.ts +6 -0
- package/dist/steps/architecture.js +39 -0
- package/dist/steps/architecture.js.map +1 -0
- package/dist/steps/build-test.d.ts +7 -0
- package/dist/steps/build-test.js +38 -0
- package/dist/steps/build-test.js.map +1 -0
- package/dist/steps/generation.d.ts +7 -0
- package/dist/steps/generation.js +60 -0
- package/dist/steps/generation.js.map +1 -0
- package/dist/steps/powerline.d.ts +7 -0
- package/dist/steps/powerline.js +62 -0
- package/dist/steps/powerline.js.map +1 -0
- package/dist/steps/product-context.d.ts +7 -0
- package/dist/steps/product-context.js +90 -0
- package/dist/steps/product-context.js.map +1 -0
- package/dist/steps/project-info.d.ts +6 -0
- package/dist/steps/project-info.js +61 -0
- package/dist/steps/project-info.js.map +1 -0
- package/dist/steps/stack-style.d.ts +6 -0
- package/dist/steps/stack-style.js +67 -0
- package/dist/steps/stack-style.js.map +1 -0
- package/docs/GIAI-THICH-CLAUDE-MD.md +206 -0
- package/docs/PRD.md +130 -0
- package/docs/USER-STORIES.md +181 -0
- package/package.json +38 -0
- package/src/app.tsx +201 -0
- package/src/cli.tsx +6 -0
- package/src/components/banner.tsx +23 -0
- package/src/components/gutter-line.tsx +10 -0
- package/src/components/guttered-select.tsx +137 -0
- package/src/components/step-indicator.tsx +19 -0
- package/src/components/timeline.tsx +49 -0
- package/src/lib/fs.ts +18 -0
- package/src/lib/git.ts +41 -0
- package/src/lib/powerline.ts +48 -0
- package/src/lib/template.ts +59 -0
- package/src/lib/types.ts +68 -0
- package/src/providers/openai.ts +5 -0
- package/src/providers/zai.ts +7 -0
- package/src/steps/architecture.tsx +71 -0
- package/src/steps/build-test.tsx +78 -0
- package/src/steps/generation.tsx +146 -0
- package/src/steps/powerline.tsx +149 -0
- package/src/steps/product-context.tsx +182 -0
- package/src/steps/project-info.tsx +135 -0
- package/src/steps/stack-style.tsx +117 -0
- package/templates/.env.example.hbs +6 -0
- package/templates/CLAUDE.md.hbs +105 -0
- package/templates/README.md.hbs +26 -0
- package/templates/docs/PRD.md.hbs +29 -0
- package/templates/docs/USER-STORIES.md.hbs +46 -0
- package/tsconfig.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Procedure CLI
|
|
2
|
+
|
|
3
|
+
Interactive CLI wizard that scaffolds projects with AI-driven documentation and best practices. Inspired by [Skills.sh](https://skills.sh) visual style.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Procedure CLI generates a complete project foundation including:
|
|
8
|
+
|
|
9
|
+
| File | Purpose |
|
|
10
|
+
|------|---------|
|
|
11
|
+
| `CLAUDE.md` | AI-ready development guide with architecture, code style, workflow |
|
|
12
|
+
| `README.md` | Project overview with quick start, tech stack, and docs links |
|
|
13
|
+
| `docs/PRD.md` | Product Requirements Document with vision, features, tech stack |
|
|
14
|
+
| `docs/USER-STORIES.md` | Gherkin-formatted acceptance criteria and user stories |
|
|
15
|
+
| `.env.example` | Environment variables template |
|
|
16
|
+
| `.gitignore` | Sensible git ignore defaults |
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx procedure-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Visual Style
|
|
25
|
+
|
|
26
|
+
Procedure CLI uses a Skills.sh / @clack/prompts-inspired vertical timeline UI:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
█▀█ █▀█ █▀█ █▀▀ █▀▀ █▀▄ █ █ █▀█ █▀▀
|
|
30
|
+
█▀▀ █▀▄ █ █ █ █▀▀ █ █ █ █ █▀▄ █▀▀
|
|
31
|
+
▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀ ▀ ▀▀▀
|
|
32
|
+
Bootstrap any project with a battle-tested
|
|
33
|
+
CLAUDE.md, PRD, user stories, and powerline.
|
|
34
|
+
───────────────────────────────────────────
|
|
35
|
+
◇ Project Info
|
|
36
|
+
│ my-app — A task management tool
|
|
37
|
+
│
|
|
38
|
+
◆ Stack & Style
|
|
39
|
+
│ ❯ QuickStart (use a preset)
|
|
40
|
+
│ Advanced (manual config)
|
|
41
|
+
│
|
|
42
|
+
○ Build & Test
|
|
43
|
+
│
|
|
44
|
+
○ Architecture
|
|
45
|
+
│
|
|
46
|
+
○ Product Context
|
|
47
|
+
│
|
|
48
|
+
○ Generation
|
|
49
|
+
│
|
|
50
|
+
○ Powerline
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- `◇` completed step (green) — summary on separate `│` line
|
|
54
|
+
- `◆` active step (green, bold) — content with `│` gutter
|
|
55
|
+
- `○` pending step (dim)
|
|
56
|
+
- `│` continuous vertical gutter connecting all steps
|
|
57
|
+
|
|
58
|
+
## The 7 Wizard Steps
|
|
59
|
+
|
|
60
|
+
1. **Project Info** — Name, description, package manager (select), license (select)
|
|
61
|
+
2. **Stack & Style** — QuickStart preset or advanced manual config (language, framework, code style)
|
|
62
|
+
3. **Build & Test** — Build/test/typecheck/lint/pre-PR commands with smart defaults
|
|
63
|
+
4. **Architecture** — Select from 7 patterns (Monorepo, MVC, Feature folders, etc.) with auto-generated best-practice notes
|
|
64
|
+
5. **Product Context** — Problem, users, tech stack (multi-select with 18 technologies, prefilled from Step 2), core features, non-goals
|
|
65
|
+
6. **Generation** — Review summary, see overwrite warnings, and confirm before writing files (or skip)
|
|
66
|
+
7. **Powerline** — Optional Claude Code powerline setup + git init (commit only when applicable)
|
|
67
|
+
|
|
68
|
+
## UI Components
|
|
69
|
+
|
|
70
|
+
| Component | File | Purpose |
|
|
71
|
+
|-----------|------|---------|
|
|
72
|
+
| Banner | `src/components/banner.tsx` | ASCII art header + tagline + horizontal rule |
|
|
73
|
+
| Timeline | `src/components/timeline.tsx` | Vertical step flow with `◇`/`◆`/`○` indicators |
|
|
74
|
+
| StepIndicator | `src/components/step-indicator.tsx` | Single step dot + label rendering |
|
|
75
|
+
| GutterLine | `src/components/gutter-line.tsx` | `│ ` prefix wrapper for content lines |
|
|
76
|
+
| GutteredSelect | `src/components/guttered-select.tsx` | Single-select with `│ ❯` gutter (replaces @inkjs/ui Select) |
|
|
77
|
+
| GutteredMultiSelect | `src/components/guttered-select.tsx` | Multi-select with `●`/`○` toggle + prefill support |
|
|
78
|
+
|
|
79
|
+
## Tech Stack
|
|
80
|
+
|
|
81
|
+
- **Language:** TypeScript (strict mode, ESM)
|
|
82
|
+
- **UI Framework:** Ink 6 (React for CLI)
|
|
83
|
+
- **UI Components:** Custom guttered select/multi-select (not @inkjs/ui Select)
|
|
84
|
+
- **Templating:** Handlebars (.hbs)
|
|
85
|
+
- **AI:** Vercel AI SDK 6, Z.ai (GLM models), OpenAI
|
|
86
|
+
- **Build:** tsc
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm run dev # Run CLI in dev mode (⚠️ run in a temp dir, not here!)
|
|
92
|
+
npm run build # Compile TypeScript
|
|
93
|
+
npm run typecheck # Type check only
|
|
94
|
+
npm run lint # Alias of typecheck in this repo
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
> **Warning:** Never run `npm run dev` from the procedure project directory — scaffolding writes to cwd and will overwrite procedure's own files. Always `cd` to a temp directory first.
|
|
98
|
+
|
|
99
|
+
## Review & Fix Workflow
|
|
100
|
+
|
|
101
|
+
This repo tracks review/fix cycles with two append-only logs:
|
|
102
|
+
|
|
103
|
+
- `CODE-REVIEW.md` — review entries (`CR-YYYYMMDD-###`)
|
|
104
|
+
- `CODE-FIXED.md` — fix entries (`CF-YYYYMMDD-###`)
|
|
105
|
+
|
|
106
|
+
Process:
|
|
107
|
+
1. Start review by reading latest `CODE-REVIEW.md` and `CODE-FIXED.md`.
|
|
108
|
+
2. Append new review findings to `CODE-REVIEW.md` only.
|
|
109
|
+
3. During implementation, write fix actions to `CODE-FIXED.md` only.
|
|
110
|
+
4. Re-review and update finding statuses in a new review entry.
|
|
111
|
+
|
|
112
|
+
Verification standard after fixes: run `npm run typecheck` and `npm run build`.
|
|
113
|
+
|
|
114
|
+
## Recent Behavior Updates
|
|
115
|
+
|
|
116
|
+
- Generation step now warns when target files already exist before writing.
|
|
117
|
+
- If generation is skipped, final summary explicitly states no files were written.
|
|
118
|
+
- Git setup no longer hard-fails on empty directories; it reports a warning when nothing is committed.
|
|
119
|
+
- `docs/USER-STORIES.md` now includes fallback starter content when no stories are provided.
|
|
120
|
+
|
|
121
|
+
## Documentation
|
|
122
|
+
|
|
123
|
+
- [CLAUDE.md](./CLAUDE.md) — Project development guide
|
|
124
|
+
- [docs/PRD.md](./docs/PRD.md) — Procedure CLI product requirements
|
|
125
|
+
- [docs/USER-STORIES.md](./docs/USER-STORIES.md) — User stories and acceptance criteria
|
|
126
|
+
- [docs/GIAI-THICH-CLAUDE-MD.md](./docs/GIAI-THICH-CLAUDE-MD.md) — 4-layer CLAUDE.md methodology (Vietnamese)
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
ISC
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"theme": "tokyo-night",
|
|
3
|
+
"display": {
|
|
4
|
+
"style": "powerline",
|
|
5
|
+
"colorCompatibility": "auto",
|
|
6
|
+
"lines": [
|
|
7
|
+
{
|
|
8
|
+
"segments": {
|
|
9
|
+
"directory": { "enabled": true, "showBasename": true },
|
|
10
|
+
"model": { "enabled": true },
|
|
11
|
+
"git": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"showSha": false,
|
|
14
|
+
"showWorkingTree": false,
|
|
15
|
+
"showOperation": false,
|
|
16
|
+
"showTag": true,
|
|
17
|
+
"showTimeSinceCommit": false,
|
|
18
|
+
"showStashCount": false,
|
|
19
|
+
"showUpstream": false,
|
|
20
|
+
"showRepoName": false
|
|
21
|
+
},
|
|
22
|
+
"context": { "enabled": true, "showPercentageOnly": true }
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"segments": {
|
|
27
|
+
"block": {
|
|
28
|
+
"enabled": true,
|
|
29
|
+
"type": "time",
|
|
30
|
+
"burnType": "both"
|
|
31
|
+
},
|
|
32
|
+
"session": {
|
|
33
|
+
"enabled": true,
|
|
34
|
+
"type": "both",
|
|
35
|
+
"costSource": "calculated"
|
|
36
|
+
},
|
|
37
|
+
"today": { "enabled": true, "type": "both" },
|
|
38
|
+
"version": { "enabled": false },
|
|
39
|
+
"metrics": {
|
|
40
|
+
"enabled": false,
|
|
41
|
+
"showResponseTime": true,
|
|
42
|
+
"showLastResponseTime": true,
|
|
43
|
+
"showDuration": true,
|
|
44
|
+
"showMessageCount": true,
|
|
45
|
+
"showLinesAdded": true,
|
|
46
|
+
"showLinesRemoved": true
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"codeStyle": [
|
|
3
|
+
"TypeScript strict mode, ESM imports",
|
|
4
|
+
"camelCase for variables, PascalCase for types",
|
|
5
|
+
"stdlib -> external -> internal import ordering",
|
|
6
|
+
"Return errors, don't throw"
|
|
7
|
+
],
|
|
8
|
+
"buildCommand": "npm run build",
|
|
9
|
+
"testCommand": "npm run test",
|
|
10
|
+
"typecheckCommand": "npm run typecheck",
|
|
11
|
+
"lintCommand": "npm run lint",
|
|
12
|
+
"architectureNotes": "",
|
|
13
|
+
"framework": "Node.js",
|
|
14
|
+
"language": "TypeScript"
|
|
15
|
+
}
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function App(): import("react/jsx-runtime").JSX.Element;
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text, useInput } from "ink";
|
|
4
|
+
import Banner from "./components/banner.js";
|
|
5
|
+
import Timeline from "./components/timeline.js";
|
|
6
|
+
import ProjectInfo from "./steps/project-info.js";
|
|
7
|
+
import StackStyle from "./steps/stack-style.js";
|
|
8
|
+
import BuildTest from "./steps/build-test.js";
|
|
9
|
+
import Architecture from "./steps/architecture.js";
|
|
10
|
+
import ProductContext from "./steps/product-context.js";
|
|
11
|
+
import Generation from "./steps/generation.js";
|
|
12
|
+
import Powerline from "./steps/powerline.js";
|
|
13
|
+
const STEP_NAMES = [
|
|
14
|
+
"Project Info",
|
|
15
|
+
"Stack & Style",
|
|
16
|
+
"Build & Test",
|
|
17
|
+
"Architecture",
|
|
18
|
+
"Product Context",
|
|
19
|
+
"Generation",
|
|
20
|
+
"Powerline",
|
|
21
|
+
];
|
|
22
|
+
const EMPTY_ANSWERS = {
|
|
23
|
+
projectName: "",
|
|
24
|
+
description: "",
|
|
25
|
+
packageManager: "npm",
|
|
26
|
+
license: "ISC",
|
|
27
|
+
codeStyle: [],
|
|
28
|
+
framework: "",
|
|
29
|
+
language: "",
|
|
30
|
+
buildCommand: "",
|
|
31
|
+
testCommand: "",
|
|
32
|
+
typecheckCommand: "",
|
|
33
|
+
lintCommand: "",
|
|
34
|
+
prCommand: "",
|
|
35
|
+
architecture: "",
|
|
36
|
+
architectureNotes: "",
|
|
37
|
+
problem: "",
|
|
38
|
+
users: "",
|
|
39
|
+
coreFeatures: [],
|
|
40
|
+
nonGoals: [],
|
|
41
|
+
techStack: "",
|
|
42
|
+
userStories: [],
|
|
43
|
+
envVars: [],
|
|
44
|
+
generationSkipped: false,
|
|
45
|
+
setupPowerline: false,
|
|
46
|
+
};
|
|
47
|
+
function getSummary(stepIndex, answers) {
|
|
48
|
+
switch (stepIndex) {
|
|
49
|
+
case 0: {
|
|
50
|
+
const name = answers.projectName || "untitled";
|
|
51
|
+
const desc = answers.description || "no description";
|
|
52
|
+
return `${name} — ${desc}`;
|
|
53
|
+
}
|
|
54
|
+
case 1: {
|
|
55
|
+
const parts = [];
|
|
56
|
+
if (answers.language)
|
|
57
|
+
parts.push(answers.language);
|
|
58
|
+
if (answers.framework)
|
|
59
|
+
parts.push(answers.framework);
|
|
60
|
+
return parts.length > 0 ? parts.join(", ") : "configured";
|
|
61
|
+
}
|
|
62
|
+
case 2: {
|
|
63
|
+
const cmds = [];
|
|
64
|
+
if (answers.buildCommand)
|
|
65
|
+
cmds.push(`build: ${answers.buildCommand}`);
|
|
66
|
+
if (answers.testCommand)
|
|
67
|
+
cmds.push(`test: ${answers.testCommand}`);
|
|
68
|
+
return cmds.length > 0 ? cmds.join(", ") : "configured";
|
|
69
|
+
}
|
|
70
|
+
case 3: {
|
|
71
|
+
return answers.architecture || "configured";
|
|
72
|
+
}
|
|
73
|
+
case 4: {
|
|
74
|
+
const features = answers.coreFeatures.length;
|
|
75
|
+
const nonGoals = answers.nonGoals.length;
|
|
76
|
+
const parts = [];
|
|
77
|
+
if (features > 0)
|
|
78
|
+
parts.push(`${features} feature${features !== 1 ? "s" : ""}`);
|
|
79
|
+
if (nonGoals > 0)
|
|
80
|
+
parts.push(`${nonGoals} non-goal${nonGoals !== 1 ? "s" : ""}`);
|
|
81
|
+
return parts.length > 0 ? parts.join(", ") : "configured";
|
|
82
|
+
}
|
|
83
|
+
case 5:
|
|
84
|
+
return answers.generationSkipped ? "skipped" : "files generated";
|
|
85
|
+
case 6: {
|
|
86
|
+
return answers.setupPowerline ? "Powerline: yes" : "Powerline: no";
|
|
87
|
+
}
|
|
88
|
+
default:
|
|
89
|
+
return "done";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export default function App() {
|
|
93
|
+
const [currentStep, setCurrentStep] = useState(0);
|
|
94
|
+
const [answers, setAnswers] = useState(EMPTY_ANSWERS);
|
|
95
|
+
const [finished, setFinished] = useState(false);
|
|
96
|
+
useInput((input, key) => {
|
|
97
|
+
if (key.escape) {
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
function handleStepComplete(partial) {
|
|
102
|
+
const merged = { ...answers, ...partial };
|
|
103
|
+
setAnswers(merged);
|
|
104
|
+
if (currentStep < STEP_NAMES.length - 1) {
|
|
105
|
+
setCurrentStep(currentStep + 1);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
setFinished(true);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (finished) {
|
|
112
|
+
const steps = STEP_NAMES.map((name, i) => ({
|
|
113
|
+
name,
|
|
114
|
+
status: "completed",
|
|
115
|
+
summary: getSummary(i, answers),
|
|
116
|
+
}));
|
|
117
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Banner, {}), _jsx(Timeline, { steps: steps, children: _jsx(Box, {}) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { bold: true, color: "green", children: ["✔", " Procedure CLI setup complete!"] }), _jsx(Text, { children: " " }), answers.generationSkipped ? (_jsx(Text, { dimColor: true, children: "Generation was skipped \u2014 no files were written." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["Project ", _jsxs(Text, { bold: true, color: "cyan", children: ["\"", answers.projectName, "\""] }), " has been scaffolded."] }), _jsx(Text, { dimColor: true, children: "Check the generated CLAUDE.md, PRD.md, and USER-STORIES.md." })] }))] })] }));
|
|
118
|
+
}
|
|
119
|
+
const steps = STEP_NAMES.map((name, i) => {
|
|
120
|
+
if (i < currentStep) {
|
|
121
|
+
return { name, status: "completed", summary: getSummary(i, answers) };
|
|
122
|
+
}
|
|
123
|
+
if (i === currentStep) {
|
|
124
|
+
return { name, status: "active" };
|
|
125
|
+
}
|
|
126
|
+
return { name, status: "pending" };
|
|
127
|
+
});
|
|
128
|
+
const activeContent = (_jsxs(_Fragment, { children: [currentStep === 0 && (_jsx(ProjectInfo, { onComplete: handleStepComplete })), currentStep === 1 && (_jsx(StackStyle, { onComplete: handleStepComplete })), currentStep === 2 && (_jsx(BuildTest, { initialValues: answers, onComplete: handleStepComplete })), currentStep === 3 && (_jsx(Architecture, { onComplete: handleStepComplete })), currentStep === 4 && (_jsx(ProductContext, { initialValues: answers, onComplete: handleStepComplete })), currentStep === 5 && (_jsx(Generation, { answers: answers, onComplete: handleStepComplete })), currentStep === 6 && (_jsx(Powerline, { answers: answers, onComplete: handleStepComplete }))] }));
|
|
129
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Banner, {}), _jsx(Timeline, { steps: steps, children: activeContent })] }));
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":";;AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,MAAM,CAAC,KAAC,GAAG,KAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function Banner(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
const BANNER_LINES = [
|
|
4
|
+
"█▀█ █▀█ █▀█ █▀▀ █▀▀ █▀▄ █ █ █▀█ █▀▀",
|
|
5
|
+
"█▀▀ █▀▄ █ █ █ █▀▀ █ █ █ █ █▀▄ █▀▀",
|
|
6
|
+
"▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀ ▀ ▀▀▀",
|
|
7
|
+
];
|
|
8
|
+
export default function Banner() {
|
|
9
|
+
return (_jsxs(Box, { flexDirection: "column", marginBottom: 0, children: [BANNER_LINES.map((line, i) => (_jsx(Text, { color: "cyan", children: line }, i))), _jsx(Text, { children: "Bootstrap any project with a battle-tested" }), _jsx(Text, { children: "CLAUDE.md, PRD, user stories, and powerline." }), _jsx(Text, { dimColor: true, children: "─".repeat(43) })] }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/components/banner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,YAAY,GAAG;IACnB,qCAAqC;IACrC,qCAAqC;IACrC,qCAAqC;CACtC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,MAAM;IAC5B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aACxC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC7B,KAAC,IAAI,IAAS,KAAK,EAAC,MAAM,YACvB,IAAI,IADI,CAAC,CAEL,CACR,CAAC,EACF,KAAC,IAAI,6DAAkD,EACvD,KAAC,IAAI,+DAAoD,EACzD,KAAC,IAAI,IAAC,QAAQ,kBAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAQ,IAClC,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
export function GutterLine({ children }) {
|
|
4
|
+
return _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "│ " }), children] });
|
|
5
|
+
}
|
|
6
|
+
export function EmptyGutter() {
|
|
7
|
+
return _jsx(Text, { dimColor: true, children: "│" });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=gutter-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gutter-line.js","sourceRoot":"","sources":["../../src/components/gutter-line.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAkC;IACrE,OAAO,MAAC,IAAI,eAAC,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,EAAC,QAAQ,IAAQ,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,KAAC,IAAI,IAAC,QAAQ,kBAAE,GAAG,GAAQ,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface Option {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
interface GutteredSelectProps {
|
|
7
|
+
options: Option[];
|
|
8
|
+
onChange: (value: string) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A custom Select component that renders each option with the vertical
|
|
12
|
+
* gutter prefix (│) so the timeline line stays continuous.
|
|
13
|
+
*/
|
|
14
|
+
export declare function GutteredSelect({ options, onChange }: GutteredSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
interface GutteredMultiSelectProps {
|
|
16
|
+
options: Option[];
|
|
17
|
+
initialSelected?: string[];
|
|
18
|
+
onSubmit: (values: string[]) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Multi-select with gutter. Space to toggle, Enter to confirm.
|
|
22
|
+
* Shows ● for selected, ○ for unselected. Hint at bottom.
|
|
23
|
+
*/
|
|
24
|
+
export declare function GutteredMultiSelect({ options, initialSelected, onSubmit }: GutteredMultiSelectProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Box, Text, useInput } from "ink";
|
|
4
|
+
/**
|
|
5
|
+
* A custom Select component that renders each option with the vertical
|
|
6
|
+
* gutter prefix (│) so the timeline line stays continuous.
|
|
7
|
+
*/
|
|
8
|
+
export function GutteredSelect({ options, onChange }) {
|
|
9
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
10
|
+
useInput((input, key) => {
|
|
11
|
+
if (key.upArrow) {
|
|
12
|
+
setActiveIndex((prev) => (prev > 0 ? prev - 1 : prev));
|
|
13
|
+
}
|
|
14
|
+
else if (key.downArrow) {
|
|
15
|
+
setActiveIndex((prev) => prev < options.length - 1 ? prev + 1 : prev);
|
|
16
|
+
}
|
|
17
|
+
else if (key.return) {
|
|
18
|
+
const selected = options[activeIndex];
|
|
19
|
+
if (selected) {
|
|
20
|
+
onChange(selected.value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return (_jsx(Box, { flexDirection: "column", children: options.map((option, index) => {
|
|
25
|
+
const isActive = index === activeIndex;
|
|
26
|
+
return (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "│ " }), isActive ? (_jsx(Text, { color: "cyan", bold: true, children: "❯ " })) : (_jsx(Text, { children: " " })), _jsx(Text, { bold: isActive, children: option.label }), option.description && (_jsx(Text, { dimColor: true, children: " " + option.description }))] }, option.value));
|
|
27
|
+
}) }));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Multi-select with gutter. Space to toggle, Enter to confirm.
|
|
31
|
+
* Shows ● for selected, ○ for unselected. Hint at bottom.
|
|
32
|
+
*/
|
|
33
|
+
export function GutteredMultiSelect({ options, initialSelected, onSubmit }) {
|
|
34
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
35
|
+
const [selected, setSelected] = useState(new Set(initialSelected ?? []));
|
|
36
|
+
useInput((input, key) => {
|
|
37
|
+
if (key.upArrow) {
|
|
38
|
+
setActiveIndex((prev) => (prev > 0 ? prev - 1 : prev));
|
|
39
|
+
}
|
|
40
|
+
else if (key.downArrow) {
|
|
41
|
+
setActiveIndex((prev) => prev < options.length - 1 ? prev + 1 : prev);
|
|
42
|
+
}
|
|
43
|
+
else if (input === " ") {
|
|
44
|
+
const option = options[activeIndex];
|
|
45
|
+
if (option) {
|
|
46
|
+
setSelected((prev) => {
|
|
47
|
+
const next = new Set(prev);
|
|
48
|
+
if (next.has(option.value)) {
|
|
49
|
+
next.delete(option.value);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
next.add(option.value);
|
|
53
|
+
}
|
|
54
|
+
return next;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (key.return) {
|
|
59
|
+
onSubmit(Array.from(selected));
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return (_jsxs(Box, { flexDirection: "column", children: [options.map((option, index) => {
|
|
63
|
+
const isActive = index === activeIndex;
|
|
64
|
+
const isSelected = selected.has(option.value);
|
|
65
|
+
return (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "│ " }), isActive ? (_jsx(Text, { color: "cyan", bold: true, children: "❯ " })) : (_jsx(Text, { children: " " })), isSelected ? (_jsx(Text, { color: "green", children: "● " })) : (_jsx(Text, { dimColor: true, children: "○ " })), _jsx(Text, { bold: isActive, children: option.label }), option.description && (_jsx(Text, { dimColor: true, children: " — " + option.description }))] }, option.value));
|
|
66
|
+
}), _jsxs(Text, { dimColor: true, children: ["│ ", " ↑↓ move, space toggle, enter confirm"] }), selected.size > 0 && (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "│ " }), _jsx(Text, { color: "green", children: "Selected: " }), _jsx(Text, { children: Array.from(selected).join(", ") })] }))] }));
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=guttered-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guttered-select.js","sourceRoot":"","sources":["../../src/components/guttered-select.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAc1C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAuB;IACvE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElD,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YACzB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CACtB,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAC5C,CAAC;QACJ,CAAC;aAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAC7B,MAAM,QAAQ,GAAG,KAAK,KAAK,WAAW,CAAC;YACvC,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,EAC5B,QAAQ,CAAC,CAAC,CAAC,CACV,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kBAAE,IAAI,GAAQ,CACtC,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,cAAE,IAAI,GAAQ,CACpB,EACD,KAAC,IAAI,IAAC,IAAI,EAAE,QAAQ,YAAG,MAAM,CAAC,KAAK,GAAQ,EAC1C,MAAM,CAAC,WAAW,IAAI,CACrB,KAAC,IAAI,IAAC,QAAQ,kBAAE,GAAG,GAAG,MAAM,CAAC,WAAW,GAAQ,CACjD,KAVQ,MAAM,CAAC,KAAK,CAWhB,CACR,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAA4B;IAClG,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CACtC,IAAI,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAC/B,CAAC;IAEF,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YACzB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CACtB,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAC5C,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YACpC,IAAI,MAAM,EAAE,CAAC;gBACX,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE;oBACnB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACzB,CAAC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACtB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gBAC7B,MAAM,QAAQ,GAAG,KAAK,KAAK,WAAW,CAAC;gBACvC,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC9C,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,EAC5B,QAAQ,CAAC,CAAC,CAAC,CACV,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,kBAAE,IAAI,GAAQ,CACtC,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,cAAE,IAAI,GAAQ,CACpB,EACA,UAAU,CAAC,CAAC,CAAC,CACZ,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,IAAI,GAAQ,CAClC,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,QAAQ,kBAAE,IAAI,GAAQ,CAC7B,EACD,KAAC,IAAI,IAAC,IAAI,EAAE,QAAQ,YAAG,MAAM,CAAC,KAAK,GAAQ,EAC1C,MAAM,CAAC,WAAW,IAAI,CACrB,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAG,MAAM,CAAC,WAAW,GAAQ,CACnD,KAfQ,MAAM,CAAC,KAAK,CAgBhB,CACR,CAAC;YACJ,CAAC,CAAC,EACF,MAAC,IAAI,IAAC,QAAQ,mBAAE,KAAK,EAAE,wCAAwC,IAAQ,EACtE,QAAQ,CAAC,IAAI,GAAG,CAAC,IAAI,CACpB,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,EAC7B,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,YAAY,GAAQ,EACzC,KAAC,IAAI,cAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAQ,IACzC,CACR,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
export default function StepIndicator({ status, label }) {
|
|
4
|
+
if (status === "completed") {
|
|
5
|
+
return _jsxs(Text, { children: [_jsx(Text, { color: "green", children: "◇" }), " ", _jsx(Text, { color: "green", children: label })] });
|
|
6
|
+
}
|
|
7
|
+
if (status === "active") {
|
|
8
|
+
return _jsxs(Text, { children: [_jsx(Text, { color: "green", bold: true, children: "◆" }), " ", _jsx(Text, { bold: true, color: "green", children: label })] });
|
|
9
|
+
}
|
|
10
|
+
return _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: "○" }), " ", _jsx(Text, { dimColor: true, children: label })] });
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=step-indicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-indicator.js","sourceRoot":"","sources":["../../src/components/step-indicator.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAS3B,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAS;IAC5D,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,OAAO,MAAC,IAAI,eAAC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,GAAG,GAAQ,EAAC,IAAI,EAAC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,KAAK,GAAQ,IAAO,CAAC;IAC/F,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,MAAC,IAAI,eAAC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,kBAAE,GAAG,GAAQ,EAAC,IAAI,EAAC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,OAAO,YAAE,KAAK,GAAQ,IAAO,CAAC;IACzG,CAAC;IACD,OAAO,MAAC,IAAI,eAAC,KAAC,IAAI,IAAC,QAAQ,kBAAE,GAAG,GAAQ,EAAC,IAAI,EAAC,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,IAAO,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { StepStatus } from "./step-indicator.js";
|
|
3
|
+
export interface TimelineStep {
|
|
4
|
+
name: string;
|
|
5
|
+
status: StepStatus;
|
|
6
|
+
summary?: string;
|
|
7
|
+
}
|
|
8
|
+
interface Props {
|
|
9
|
+
steps: TimelineStep[];
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export default function Timeline({ steps, children }: Props): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import StepIndicator from "./step-indicator.js";
|
|
5
|
+
export default function Timeline({ steps, children }) {
|
|
6
|
+
const elements = [];
|
|
7
|
+
steps.forEach((step, i) => {
|
|
8
|
+
const isLast = i === steps.length - 1;
|
|
9
|
+
// Step indicator line
|
|
10
|
+
elements.push(_jsx(StepIndicator, { status: step.status, label: step.name }, `ind-${i}`));
|
|
11
|
+
// Completed step: show summary on SEPARATE line with gutter
|
|
12
|
+
if (step.status === "completed" && step.summary) {
|
|
13
|
+
elements.push(_jsxs(Text, { dimColor: true, children: ["│ ", step.summary] }, `sum-${i}`));
|
|
14
|
+
}
|
|
15
|
+
// Active step: render children (they handle their own GutterLine)
|
|
16
|
+
if (step.status === "active") {
|
|
17
|
+
elements.push(_jsx(React.Fragment, { children: children }, `content-${i}`));
|
|
18
|
+
}
|
|
19
|
+
// Gutter spacer between steps
|
|
20
|
+
if (!isLast) {
|
|
21
|
+
elements.push(_jsx(Text, { dimColor: true, children: "│" }, `bar-${i}`));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return _jsx(Box, { flexDirection: "column", children: elements });
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/components/timeline.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAchD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAS;IACzD,MAAM,QAAQ,GAAsB,EAAE,CAAC;IAEvC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAEtC,sBAAsB;QACtB,QAAQ,CAAC,IAAI,CACX,KAAC,aAAa,IAAkB,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,IAAjD,OAAO,CAAC,EAAE,CAA2C,CAC1E,CAAC;QAEF,4DAA4D;QAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAChD,QAAQ,CAAC,IAAI,CACX,MAAC,IAAI,IAAkB,QAAQ,mBAAE,KAAK,EAAE,IAAI,CAAC,OAAO,KAAzC,OAAO,CAAC,EAAE,CAAuC,CAC7D,CAAC;QACJ,CAAC;QAED,kEAAkE;QAClE,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CACX,KAAC,KAAK,CAAC,QAAQ,cAAuB,QAAQ,IAAzB,WAAW,CAAC,EAAE,CAA6B,CACjE,CAAC;QACJ,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,QAAQ,CAAC,IAAI,CAAC,KAAC,IAAI,IAAkB,QAAQ,kBAAE,GAAG,IAAzB,OAAO,CAAC,EAAE,CAAuB,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YAAE,QAAQ,GAAO,CAAC;AACtD,CAAC"}
|
package/dist/lib/fs.d.ts
ADDED
package/dist/lib/fs.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = dirname(__filename);
|
|
6
|
+
export function ensureDir(dirPath) {
|
|
7
|
+
mkdirSync(dirPath, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
export function fileExists(filePath) {
|
|
10
|
+
return existsSync(filePath);
|
|
11
|
+
}
|
|
12
|
+
export function resolveTemplatePath(templateName) {
|
|
13
|
+
return resolve(__dirname, '..', '..', 'templates', templateName);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/lib/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;AACnE,CAAC"}
|