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/dist/lib/git.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
function hasGitIdentity() {
|
|
3
|
+
try {
|
|
4
|
+
execSync('git config user.name', { stdio: 'ignore' });
|
|
5
|
+
execSync('git config user.email', { stdio: 'ignore' });
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function hasStagedFiles(targetDir) {
|
|
13
|
+
try {
|
|
14
|
+
const result = execSync('git status --porcelain', { cwd: targetDir, encoding: 'utf-8' });
|
|
15
|
+
return result.trim().length > 0;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function initGit(targetDir) {
|
|
22
|
+
const opts = { cwd: targetDir, stdio: 'ignore' };
|
|
23
|
+
execSync('git init', opts);
|
|
24
|
+
execSync('git add -A', opts);
|
|
25
|
+
if (!hasStagedFiles(targetDir)) {
|
|
26
|
+
return { committed: false, reason: 'Nothing to commit — directory is empty.' };
|
|
27
|
+
}
|
|
28
|
+
if (!hasGitIdentity()) {
|
|
29
|
+
return {
|
|
30
|
+
committed: false,
|
|
31
|
+
reason: 'Git user.name/user.email not configured. Run: git config --global user.name "Your Name" && git config --global user.email "you@example.com"',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
execSync('git commit -m "Initial commit \u2014 scaffolded by Procedure CLI"', opts);
|
|
35
|
+
return { committed: true };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,QAAQ,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtD,QAAQ,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACzF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,SAAiB;IACvC,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,QAAiB,EAAE,CAAC;IAE1D,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAE7B,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IACjF,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,6IAA6I;SACtJ,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,mEAAmE,EAAE,IAAI,CAAC,CAAC;IACpF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupPowerline(targetDir: string): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, copyFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { ensureDir, fileExists, resolveTemplatePath } from './fs.js';
|
|
4
|
+
export function setupPowerline(targetDir) {
|
|
5
|
+
const claudeDir = resolve(targetDir, '.claude');
|
|
6
|
+
ensureDir(claudeDir);
|
|
7
|
+
const settingsPath = resolve(claudeDir, 'settings.json');
|
|
8
|
+
let settings = {};
|
|
9
|
+
if (fileExists(settingsPath)) {
|
|
10
|
+
try {
|
|
11
|
+
const raw = readFileSync(settingsPath, 'utf-8');
|
|
12
|
+
settings = JSON.parse(raw);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Malformed settings.json — start fresh, original is not overwritten destructively
|
|
16
|
+
settings = {};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
settings.statusLine = {
|
|
20
|
+
type: 'command',
|
|
21
|
+
command: 'npx -y @owloops/claude-powerline@latest --config=.claude/powerline-config.json',
|
|
22
|
+
padding: 0,
|
|
23
|
+
};
|
|
24
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
25
|
+
// Copy bundled powerline-config.json to target .claude/
|
|
26
|
+
const bundledConfig = resolve(resolveTemplatePath('..'), 'config', 'powerline-config.json');
|
|
27
|
+
const destConfig = resolve(claudeDir, 'powerline-config.json');
|
|
28
|
+
copyFileSync(bundledConfig, destConfig);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=powerline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"powerline.js","sourceRoot":"","sources":["../../src/lib/powerline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAWrE,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAChD,SAAS,CAAC,SAAS,CAAC,CAAC;IAErB,MAAM,YAAY,GAAG,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAEzD,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAClC,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAChD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,mFAAmF;YACnF,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,UAAU,GAAG;QACpB,IAAI,EAAE,SAAS;QACf,OAAO,EACL,gFAAgF;QAClF,OAAO,EAAE,CAAC;KACX,CAAC;IAEF,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAE/E,wDAAwD;IACxD,MAAM,aAAa,GAAG,OAAO,CAC3B,mBAAmB,CAAC,IAAI,CAAC,EACzB,QAAQ,EACR,uBAAuB,CACxB,CAAC;IACF,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAC/D,YAAY,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WizardAnswers } from './types.js';
|
|
2
|
+
export declare function renderTemplate(templatePath: string, data: Record<string, unknown>): string;
|
|
3
|
+
export declare function writeTemplate(templatePath: string, outputPath: string, data: Record<string, unknown>): void;
|
|
4
|
+
/**
|
|
5
|
+
* Check which output files already exist in the target directory.
|
|
6
|
+
* Returns a list of file paths that would be overwritten.
|
|
7
|
+
*/
|
|
8
|
+
export declare function checkConflicts(targetDir: string): string[];
|
|
9
|
+
export declare function scaffoldAll(targetDir: string, data: WizardAnswers): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve, dirname } from 'node:path';
|
|
3
|
+
import Handlebars from 'handlebars';
|
|
4
|
+
import { ensureDir, resolveTemplatePath } from './fs.js';
|
|
5
|
+
export function renderTemplate(templatePath, data) {
|
|
6
|
+
const source = readFileSync(templatePath, 'utf-8');
|
|
7
|
+
const template = Handlebars.compile(source);
|
|
8
|
+
return template(data);
|
|
9
|
+
}
|
|
10
|
+
export function writeTemplate(templatePath, outputPath, data) {
|
|
11
|
+
const rendered = renderTemplate(templatePath, data);
|
|
12
|
+
ensureDir(dirname(outputPath));
|
|
13
|
+
writeFileSync(outputPath, rendered, 'utf-8');
|
|
14
|
+
}
|
|
15
|
+
const TEMPLATE_MAP = [
|
|
16
|
+
{ template: 'CLAUDE.md.hbs', output: 'CLAUDE.md' },
|
|
17
|
+
{ template: 'README.md.hbs', output: 'README.md' },
|
|
18
|
+
{ template: 'docs/PRD.md.hbs', output: 'docs/PRD.md' },
|
|
19
|
+
{ template: 'docs/USER-STORIES.md.hbs', output: 'docs/USER-STORIES.md' },
|
|
20
|
+
{ template: '.env.example.hbs', output: '.env.example' },
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Check which output files already exist in the target directory.
|
|
24
|
+
* Returns a list of file paths that would be overwritten.
|
|
25
|
+
*/
|
|
26
|
+
export function checkConflicts(targetDir) {
|
|
27
|
+
const allOutputs = [
|
|
28
|
+
...TEMPLATE_MAP.map((t) => t.output),
|
|
29
|
+
'.gitignore',
|
|
30
|
+
];
|
|
31
|
+
return allOutputs.filter((f) => existsSync(resolve(targetDir, f)));
|
|
32
|
+
}
|
|
33
|
+
export function scaffoldAll(targetDir, data) {
|
|
34
|
+
for (const { template, output } of TEMPLATE_MAP) {
|
|
35
|
+
const templatePath = resolveTemplatePath(template);
|
|
36
|
+
const outputPath = resolve(targetDir, output);
|
|
37
|
+
writeTemplate(templatePath, outputPath, data);
|
|
38
|
+
}
|
|
39
|
+
// Copy static .gitignore (no templating needed)
|
|
40
|
+
const gitignoreSrc = resolveTemplatePath('.gitignore');
|
|
41
|
+
const gitignoreDest = resolve(targetDir, '.gitignore');
|
|
42
|
+
const content = readFileSync(gitignoreSrc, 'utf-8');
|
|
43
|
+
ensureDir(dirname(gitignoreDest));
|
|
44
|
+
writeFileSync(gitignoreDest, content, 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/lib/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGzD,MAAM,UAAU,cAAc,CAC5B,YAAoB,EACpB,IAA6B;IAE7B,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,YAAoB,EACpB,UAAkB,EAClB,IAA6B;IAE7B,MAAM,QAAQ,GAAG,cAAc,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACpD,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/B,aAAa,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,YAAY,GAAgD;IAChE,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE;IAClD,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE;IAClD,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE;IACtD,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,EAAE,sBAAsB,EAAE;IACxE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,EAAE;CACzD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,UAAU,GAAG;QACjB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACpC,YAAY;KACb,CAAC;IACF,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,IAAmB;IAChE,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;QAChD,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC9C,aAAa,CAAC,YAAY,EAAE,UAAU,EAAE,IAA0C,CAAC,CAAC;IACtF,CAAC;IAED,gDAAgD;IAChD,MAAM,YAAY,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACpD,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IAClC,aAAa,CAAC,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type StepId = 'project-info' | 'stack-style' | 'build-test' | 'architecture' | 'product-context' | 'generation' | 'powerline';
|
|
2
|
+
export interface UserStoryScenario {
|
|
3
|
+
name: string;
|
|
4
|
+
given: string;
|
|
5
|
+
when: string;
|
|
6
|
+
then: string;
|
|
7
|
+
}
|
|
8
|
+
export interface UserStory {
|
|
9
|
+
title: string;
|
|
10
|
+
asA: string;
|
|
11
|
+
iWant: string;
|
|
12
|
+
soThat: string;
|
|
13
|
+
feature: string;
|
|
14
|
+
scenarios: UserStoryScenario[];
|
|
15
|
+
}
|
|
16
|
+
export interface EnvVar {
|
|
17
|
+
key: string;
|
|
18
|
+
comment: string;
|
|
19
|
+
}
|
|
20
|
+
export interface WizardAnswers {
|
|
21
|
+
projectName: string;
|
|
22
|
+
description: string;
|
|
23
|
+
packageManager: string;
|
|
24
|
+
license: string;
|
|
25
|
+
codeStyle: string[];
|
|
26
|
+
framework: string;
|
|
27
|
+
language: string;
|
|
28
|
+
buildCommand: string;
|
|
29
|
+
testCommand: string;
|
|
30
|
+
typecheckCommand: string;
|
|
31
|
+
lintCommand: string;
|
|
32
|
+
prCommand: string;
|
|
33
|
+
architecture: string;
|
|
34
|
+
architectureNotes: string;
|
|
35
|
+
problem: string;
|
|
36
|
+
users: string;
|
|
37
|
+
coreFeatures: string[];
|
|
38
|
+
nonGoals: string[];
|
|
39
|
+
techStack: string;
|
|
40
|
+
userStories: UserStory[];
|
|
41
|
+
envVars: EnvVar[];
|
|
42
|
+
generationSkipped: boolean;
|
|
43
|
+
setupPowerline: boolean;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const openai: import("@ai-sdk/openai").OpenAIProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,CAAC;IACjC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;CACnC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const zai: import("@ai-sdk/openai-compatible").OpenAICompatibleProvider<string, string, string, string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zai.js","sourceRoot":"","sources":["../../src/providers/zai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,CAAC,MAAM,GAAG,GAAG,sBAAsB,CAAC;IACxC,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,qBAAqB;IAC9B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;CAChC,CAAC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { GutterLine } from "../components/gutter-line.js";
|
|
5
|
+
import { GutteredSelect } from "../components/guttered-select.js";
|
|
6
|
+
const ARCHITECTURE_OPTIONS = [
|
|
7
|
+
{ label: "Monorepo — Multiple packages in one repository", value: "Monorepo" },
|
|
8
|
+
{ label: "MVC — Model-View-Controller separation", value: "MVC" },
|
|
9
|
+
{ label: "Feature folders — Co-located components, hooks, utils per feature", value: "Feature folders" },
|
|
10
|
+
{ label: "Layered — Presentation > Business > Data access layers", value: "Layered" },
|
|
11
|
+
{ label: "Microservices — Independent deployable services", value: "Microservices" },
|
|
12
|
+
{ label: "Serverless — Function-based, event-driven architecture", value: "Serverless" },
|
|
13
|
+
{ label: "Modular monolith — Single deploy, strict module boundaries", value: "Modular monolith" },
|
|
14
|
+
];
|
|
15
|
+
const ARCHITECTURE_NOTES = {
|
|
16
|
+
Monorepo: "Shared packages in packages/, apps in apps/. Use workspace protocol for cross-references.",
|
|
17
|
+
MVC: "Controllers handle HTTP, models handle data, views handle presentation. Keep business logic in models.",
|
|
18
|
+
"Feature folders": "Each feature owns its components, hooks, utils, and tests. Shared code in shared/ or lib/.",
|
|
19
|
+
Layered: "Strict dependency direction: Presentation -> Business -> Data. No skipping layers.",
|
|
20
|
+
Microservices: "Each service owns its data store. Communicate via APIs or message queues. Deploy independently.",
|
|
21
|
+
Serverless: "One function per endpoint. Keep functions stateless. Use managed services for state and storage.",
|
|
22
|
+
"Modular monolith": "Define explicit module boundaries with public APIs. No direct cross-module database access.",
|
|
23
|
+
};
|
|
24
|
+
export default function Architecture({ onComplete }) {
|
|
25
|
+
const [selected, setSelected] = useState(null);
|
|
26
|
+
function handleChange(value) {
|
|
27
|
+
const notes = ARCHITECTURE_NOTES[value] ?? "";
|
|
28
|
+
setSelected(value);
|
|
29
|
+
// Use setTimeout to allow React to render the selection before completing
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
onComplete({ architecture: value, architectureNotes: notes });
|
|
32
|
+
}, 100);
|
|
33
|
+
}
|
|
34
|
+
if (selected) {
|
|
35
|
+
return (_jsxs(_Fragment, { children: [_jsx(GutterLine, { children: _jsxs(Text, { dimColor: true, children: ["Architecture: ", selected] }) }), _jsx(GutterLine, { children: _jsxs(Text, { dimColor: true, children: ["Notes: ", ARCHITECTURE_NOTES[selected]] }) })] }));
|
|
36
|
+
}
|
|
37
|
+
return (_jsxs(_Fragment, { children: [_jsx(GutterLine, { children: _jsx(Text, { bold: true, children: "Architecture pattern:" }) }), _jsx(GutteredSelect, { options: ARCHITECTURE_OPTIONS, onChange: handleChange })] }));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=architecture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architecture.js","sourceRoot":"","sources":["../../src/steps/architecture.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAOlE,MAAM,oBAAoB,GAAG;IAC3B,EAAE,KAAK,EAAE,gDAAgD,EAAE,KAAK,EAAE,UAAU,EAAE;IAC9E,EAAE,KAAK,EAAE,wCAAwC,EAAE,KAAK,EAAE,KAAK,EAAE;IACjE,EAAE,KAAK,EAAE,mEAAmE,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACxG,EAAE,KAAK,EAAE,wDAAwD,EAAE,KAAK,EAAE,SAAS,EAAE;IACrF,EAAE,KAAK,EAAE,iDAAiD,EAAE,KAAK,EAAE,eAAe,EAAE;IACpF,EAAE,KAAK,EAAE,wDAAwD,EAAE,KAAK,EAAE,YAAY,EAAE;IACxF,EAAE,KAAK,EAAE,4DAA4D,EAAE,KAAK,EAAE,kBAAkB,EAAE;CACnG,CAAC;AAEF,MAAM,kBAAkB,GAA2B;IACjD,QAAQ,EACN,2FAA2F;IAC7F,GAAG,EACD,wGAAwG;IAC1G,iBAAiB,EACf,4FAA4F;IAC9F,OAAO,EACL,oFAAoF;IACtF,aAAa,EACX,iGAAiG;IACnG,UAAU,EACR,kGAAkG;IACpG,kBAAkB,EAChB,6FAA6F;CAChG,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,UAAU,EAAS;IACxD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAE9D,SAAS,YAAY,CAAC,KAAa;QACjC,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC9C,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,0EAA0E;QAC1E,UAAU,CAAC,GAAG,EAAE;YACd,UAAU,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CACL,8BACE,KAAC,UAAU,cACT,MAAC,IAAI,IAAC,QAAQ,qCAAgB,QAAQ,IAAQ,GACnC,EACb,KAAC,UAAU,cACT,MAAC,IAAI,IAAC,QAAQ,8BAAS,kBAAkB,CAAC,QAAQ,CAAC,IAAQ,GAChD,IACZ,CACJ,CAAC;IACJ,CAAC;IAED,OAAO,CACL,8BACE,KAAC,UAAU,cACT,KAAC,IAAI,IAAC,IAAI,4CAA6B,GAC5B,EACb,KAAC,cAAc,IAAC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,YAAY,GAAI,IACxE,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WizardAnswers } from "../lib/types.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
initialValues?: Partial<WizardAnswers>;
|
|
4
|
+
onComplete: (answers: Partial<WizardAnswers>) => void;
|
|
5
|
+
}
|
|
6
|
+
export default function BuildTest({ initialValues, onComplete }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { TextInput } from "@inkjs/ui";
|
|
5
|
+
import { GutterLine } from "../components/gutter-line.js";
|
|
6
|
+
const FIELDS = [
|
|
7
|
+
{ key: "buildCommand", label: "Build command", fallback: "npm run build", required: true },
|
|
8
|
+
{ key: "testCommand", label: "Test command", fallback: "npm run test", required: true },
|
|
9
|
+
{ key: "typecheckCommand", label: "Typecheck command", fallback: "tsc --noEmit", required: false },
|
|
10
|
+
{ key: "lintCommand", label: "Lint command", fallback: "npm run lint", required: false },
|
|
11
|
+
{ key: "prCommand", label: "Pre-PR command", fallback: "npm run lint && npm run test", required: false },
|
|
12
|
+
];
|
|
13
|
+
export default function BuildTest({ initialValues, onComplete }) {
|
|
14
|
+
const [fieldIndex, setFieldIndex] = useState(0);
|
|
15
|
+
const [answers, setAnswers] = useState({});
|
|
16
|
+
const [error, setError] = useState("");
|
|
17
|
+
const current = FIELDS[fieldIndex];
|
|
18
|
+
const preset = initialValues?.[current.key];
|
|
19
|
+
const defaultVal = preset || current.fallback;
|
|
20
|
+
function handleSubmit(value) {
|
|
21
|
+
const val = value.trim() || defaultVal;
|
|
22
|
+
if (current.required && !val) {
|
|
23
|
+
setError(`${current.label} is required`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
setError("");
|
|
27
|
+
const next = { ...answers, [current.key]: val };
|
|
28
|
+
setAnswers(next);
|
|
29
|
+
if (fieldIndex < FIELDS.length - 1) {
|
|
30
|
+
setFieldIndex(fieldIndex + 1);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
onComplete(next);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return (_jsxs(_Fragment, { children: [FIELDS.slice(0, fieldIndex).map((f) => (_jsx(GutterLine, { children: _jsxs(Text, { dimColor: true, children: [f.label, ": ", answers[f.key]] }) }, f.key))), _jsxs(GutterLine, { children: [_jsx(Text, { bold: true, children: current.label }), _jsxs(Text, { dimColor: true, children: [" (", defaultVal, ")"] }), _jsx(Text, { bold: true, children: ": " }), _jsx(TextInput, { placeholder: defaultVal, onSubmit: handleSubmit })] }), error && (_jsx(GutterLine, { children: _jsx(Text, { color: "red", children: error }) }))] }));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=build-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-test.js","sourceRoot":"","sources":["../../src/steps/build-test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WizardAnswers } from "../lib/types.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
answers: WizardAnswers;
|
|
4
|
+
onComplete: (partial: Partial<WizardAnswers>) => void;
|
|
5
|
+
}
|
|
6
|
+
export default function Generation({ answers, onComplete }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { ConfirmInput, Spinner } from "@inkjs/ui";
|
|
5
|
+
import { GutterLine } from "../components/gutter-line.js";
|
|
6
|
+
import { scaffoldAll, checkConflicts } from "../lib/template.js";
|
|
7
|
+
const FILES_TO_GENERATE = [
|
|
8
|
+
"CLAUDE.md",
|
|
9
|
+
"README.md",
|
|
10
|
+
"docs/PRD.md",
|
|
11
|
+
"docs/USER-STORIES.md",
|
|
12
|
+
".env.example",
|
|
13
|
+
".gitignore",
|
|
14
|
+
];
|
|
15
|
+
export default function Generation({ answers, onComplete }) {
|
|
16
|
+
const [phase, setPhase] = useState("summary");
|
|
17
|
+
const [errorMsg, setErrorMsg] = useState("");
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (phase !== "running")
|
|
20
|
+
return;
|
|
21
|
+
try {
|
|
22
|
+
const targetDir = process.cwd();
|
|
23
|
+
scaffoldAll(targetDir, answers);
|
|
24
|
+
setPhase("done");
|
|
25
|
+
const timer = setTimeout(() => onComplete({ generationSkipped: false }), 1500);
|
|
26
|
+
return () => clearTimeout(timer);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
setPhase("error");
|
|
30
|
+
setErrorMsg(err instanceof Error ? err.message : String(err));
|
|
31
|
+
}
|
|
32
|
+
}, [phase]);
|
|
33
|
+
function handleConfirm() {
|
|
34
|
+
setPhase("running");
|
|
35
|
+
}
|
|
36
|
+
function handleCancel() {
|
|
37
|
+
onComplete({ generationSkipped: true });
|
|
38
|
+
}
|
|
39
|
+
if (phase === "summary") {
|
|
40
|
+
const techParts = [];
|
|
41
|
+
if (answers.language)
|
|
42
|
+
techParts.push(answers.language);
|
|
43
|
+
if (answers.framework)
|
|
44
|
+
techParts.push(answers.framework);
|
|
45
|
+
const stack = techParts.length > 0 ? techParts.join(", ") : "N/A";
|
|
46
|
+
const pmAndLicense = [answers.packageManager, answers.license]
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join(", ");
|
|
49
|
+
const conflicts = checkConflicts(process.cwd());
|
|
50
|
+
return (_jsxs(_Fragment, { children: [_jsx(GutterLine, { children: _jsxs(Text, { children: ["Project: ", _jsx(Text, { bold: true, children: answers.projectName || "untitled" }), " — ", answers.description || "no description"] }) }), _jsx(GutterLine, { children: _jsxs(Text, { children: ["Stack: ", stack, pmAndLicense ? ` (${pmAndLicense})` : ""] }) }), _jsx(GutterLine, { children: _jsxs(Text, { children: ["Build: ", answers.buildCommand || "N/A", " | Test:", " ", answers.testCommand || "N/A"] }) }), _jsx(GutterLine, { children: _jsxs(Text, { children: ["Architecture: ", answers.architecture || "N/A"] }) }), _jsx(GutterLine, { children: _jsxs(Text, { children: ["Features: ", answers.coreFeatures.length, " | Non-goals:", " ", answers.nonGoals.length] }) }), _jsx(GutterLine, { children: _jsx(Text, { children: " " }) }), _jsx(GutterLine, { children: _jsx(Text, { children: "Files to generate:" }) }), _jsx(GutterLine, { children: _jsxs(Text, { children: [" ", FILES_TO_GENERATE.join(", ")] }) }), conflicts.length > 0 && (_jsxs(_Fragment, { children: [_jsx(GutterLine, { children: _jsx(Text, { children: " " }) }), _jsx(GutterLine, { children: _jsxs(Text, { color: "yellow", children: ["⚠ Will overwrite: ", conflicts.join(", ")] }) })] })), _jsx(GutterLine, { children: _jsx(Text, { children: " " }) }), _jsxs(GutterLine, { children: [_jsx(Text, { children: "Proceed? " }), _jsx(ConfirmInput, { onConfirm: handleConfirm, onCancel: handleCancel })] })] }));
|
|
51
|
+
}
|
|
52
|
+
if (phase === "running") {
|
|
53
|
+
return (_jsx(GutterLine, { children: _jsx(Spinner, { label: "Generating project files..." }) }));
|
|
54
|
+
}
|
|
55
|
+
if (phase === "error") {
|
|
56
|
+
return (_jsx(GutterLine, { children: _jsxs(Text, { color: "red", children: ["Error generating files: ", errorMsg] }) }));
|
|
57
|
+
}
|
|
58
|
+
return (_jsx(GutterLine, { children: _jsx(Text, { color: "green", children: "All project files generated successfully." }) }));
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=generation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation.js","sourceRoot":"","sources":["../../src/steps/generation.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WizardAnswers } from "../lib/types.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
answers: WizardAnswers;
|
|
4
|
+
onComplete: (answers: Partial<WizardAnswers>) => void;
|
|
5
|
+
}
|
|
6
|
+
export default function Powerline({ answers, onComplete }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { ConfirmInput, Spinner } from "@inkjs/ui";
|
|
5
|
+
import { GutterLine } from "../components/gutter-line.js";
|
|
6
|
+
import { setupPowerline } from "../lib/powerline.js";
|
|
7
|
+
import { initGit } from "../lib/git.js";
|
|
8
|
+
export default function Powerline({ answers, onComplete }) {
|
|
9
|
+
const [phase, setPhase] = useState("ask-powerline");
|
|
10
|
+
const [wantPowerline, setWantPowerline] = useState(false);
|
|
11
|
+
const [wantGit, setWantGit] = useState(false);
|
|
12
|
+
const [errorMsg, setErrorMsg] = useState("");
|
|
13
|
+
const [setupResult, setSetupResult] = useState({});
|
|
14
|
+
function runSetup(powerline, git) {
|
|
15
|
+
setPhase("running");
|
|
16
|
+
try {
|
|
17
|
+
const targetDir = process.cwd();
|
|
18
|
+
if (powerline) {
|
|
19
|
+
setupPowerline(targetDir);
|
|
20
|
+
}
|
|
21
|
+
if (git) {
|
|
22
|
+
const gitResult = initGit(targetDir);
|
|
23
|
+
setSetupResult({
|
|
24
|
+
gitCommitted: gitResult.committed,
|
|
25
|
+
gitWarning: gitResult.committed ? undefined : gitResult.reason,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
setPhase("done");
|
|
29
|
+
setTimeout(() => onComplete({ setupPowerline: powerline }), 1000);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
setPhase("error");
|
|
33
|
+
setErrorMsg(err instanceof Error ? err.message : String(err));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (phase === "ask-powerline") {
|
|
37
|
+
return (_jsxs(_Fragment, { children: [_jsx(GutterLine, { children: _jsx(Text, { bold: true, children: "Setup Claude Powerline status bar?" }) }), _jsx(GutterLine, { children: _jsx(ConfirmInput, { onConfirm: () => {
|
|
38
|
+
setWantPowerline(true);
|
|
39
|
+
setPhase("ask-git");
|
|
40
|
+
}, onCancel: () => {
|
|
41
|
+
setWantPowerline(false);
|
|
42
|
+
setPhase("ask-git");
|
|
43
|
+
} }) })] }));
|
|
44
|
+
}
|
|
45
|
+
if (phase === "ask-git") {
|
|
46
|
+
return (_jsxs(_Fragment, { children: [wantPowerline && (_jsx(GutterLine, { children: _jsx(Text, { dimColor: true, children: "Powerline: yes" }) })), _jsx(GutterLine, { children: _jsx(Text, { bold: true, children: "Initialize git repository?" }) }), _jsx(GutterLine, { children: _jsx(ConfirmInput, { onConfirm: () => {
|
|
47
|
+
setWantGit(true);
|
|
48
|
+
runSetup(wantPowerline, true);
|
|
49
|
+
}, onCancel: () => {
|
|
50
|
+
setWantGit(false);
|
|
51
|
+
runSetup(wantPowerline, false);
|
|
52
|
+
} }) })] }));
|
|
53
|
+
}
|
|
54
|
+
if (phase === "running") {
|
|
55
|
+
return (_jsx(GutterLine, { children: _jsx(Spinner, { label: "Running setup tasks..." }) }));
|
|
56
|
+
}
|
|
57
|
+
if (phase === "error") {
|
|
58
|
+
return (_jsx(GutterLine, { children: _jsxs(Text, { color: "red", children: ["Setup error: ", errorMsg] }) }));
|
|
59
|
+
}
|
|
60
|
+
return (_jsxs(_Fragment, { children: [wantPowerline && (_jsx(GutterLine, { children: _jsx(Text, { color: "green", children: "Powerline configured." }) })), wantGit && setupResult.gitCommitted && (_jsx(GutterLine, { children: _jsx(Text, { color: "green", children: "Git repository initialized." }) })), wantGit && !setupResult.gitCommitted && setupResult.gitWarning && (_jsx(GutterLine, { children: _jsxs(Text, { color: "yellow", children: ["⚠ Git: ", setupResult.gitWarning] }) })), !wantPowerline && !wantGit && (_jsx(GutterLine, { children: _jsx(Text, { dimColor: true, children: "No extras setup." }) })), _jsx(GutterLine, { children: _jsx(Text, { color: "green", bold: true, children: "Setup complete!" }) })] }));
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=powerline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"powerline.js","sourceRoot":"","sources":["../../src/steps/powerline.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WizardAnswers } from "../lib/types.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
initialValues?: Partial<WizardAnswers>;
|
|
4
|
+
onComplete: (answers: Partial<WizardAnswers>) => void;
|
|
5
|
+
}
|
|
6
|
+
export default function ProductContext({ initialValues, onComplete }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import { TextInput } from "@inkjs/ui";
|
|
5
|
+
import { GutterLine } from "../components/gutter-line.js";
|
|
6
|
+
import { GutteredMultiSelect } from "../components/guttered-select.js";
|
|
7
|
+
const TECH_STACK_OPTIONS = [
|
|
8
|
+
{ label: "React", value: "React", description: "UI component library" },
|
|
9
|
+
{ label: "Next.js", value: "Next.js", description: "Full-stack React framework" },
|
|
10
|
+
{ label: "Vue", value: "Vue", description: "Progressive UI framework" },
|
|
11
|
+
{ label: "Svelte", value: "Svelte", description: "Compile-time UI framework" },
|
|
12
|
+
{ label: "Node.js", value: "Node.js", description: "Server-side JavaScript runtime" },
|
|
13
|
+
{ label: "Express", value: "Express", description: "Minimal Node.js web framework" },
|
|
14
|
+
{ label: "Fastify", value: "Fastify", description: "High-performance Node.js framework" },
|
|
15
|
+
{ label: "PostgreSQL", value: "PostgreSQL", description: "Relational database" },
|
|
16
|
+
{ label: "MongoDB", value: "MongoDB", description: "Document database" },
|
|
17
|
+
{ label: "Redis", value: "Redis", description: "In-memory data store / cache" },
|
|
18
|
+
{ label: "Supabase", value: "Supabase", description: "Open-source Firebase alternative" },
|
|
19
|
+
{ label: "Prisma", value: "Prisma", description: "TypeScript ORM" },
|
|
20
|
+
{ label: "Docker", value: "Docker", description: "Container platform" },
|
|
21
|
+
{ label: "Tailwind CSS", value: "Tailwind CSS", description: "Utility-first CSS framework" },
|
|
22
|
+
{ label: "TypeScript", value: "TypeScript", description: "Typed JavaScript superset" },
|
|
23
|
+
{ label: "Python", value: "Python", description: "General-purpose language" },
|
|
24
|
+
{ label: "Go", value: "Go", description: "Systems programming language" },
|
|
25
|
+
{ label: "Rust", value: "Rust", description: "Memory-safe systems language" },
|
|
26
|
+
];
|
|
27
|
+
const PHASE_ORDER = ["problem", "users", "techStack", "coreFeatures", "nonGoals"];
|
|
28
|
+
export default function ProductContext({ initialValues, onComplete }) {
|
|
29
|
+
const [phaseIndex, setPhaseIndex] = useState(0);
|
|
30
|
+
const [answers, setAnswers] = useState({});
|
|
31
|
+
const [error, setError] = useState("");
|
|
32
|
+
// Prefill tech stack from Stack & Style selections (language + framework)
|
|
33
|
+
const prefillTechStack = [];
|
|
34
|
+
if (initialValues?.language) {
|
|
35
|
+
const match = TECH_STACK_OPTIONS.find((o) => o.value.toLowerCase() === initialValues.language.toLowerCase());
|
|
36
|
+
if (match)
|
|
37
|
+
prefillTechStack.push(match.value);
|
|
38
|
+
}
|
|
39
|
+
if (initialValues?.framework) {
|
|
40
|
+
const match = TECH_STACK_OPTIONS.find((o) => o.value.toLowerCase() === initialValues.framework.toLowerCase());
|
|
41
|
+
if (match)
|
|
42
|
+
prefillTechStack.push(match.value);
|
|
43
|
+
}
|
|
44
|
+
const currentPhase = PHASE_ORDER[phaseIndex];
|
|
45
|
+
function advanceToNext(key, value) {
|
|
46
|
+
const next = { ...answers, [key]: value };
|
|
47
|
+
setAnswers(next);
|
|
48
|
+
setError("");
|
|
49
|
+
if (phaseIndex < PHASE_ORDER.length - 1) {
|
|
50
|
+
setPhaseIndex(phaseIndex + 1);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
onComplete({
|
|
54
|
+
problem: next.problem,
|
|
55
|
+
users: next.users,
|
|
56
|
+
techStack: next.techStack,
|
|
57
|
+
coreFeatures: (next.coreFeatures || "")
|
|
58
|
+
.split(",")
|
|
59
|
+
.map((s) => s.trim())
|
|
60
|
+
.filter(Boolean),
|
|
61
|
+
nonGoals: (next.nonGoals || "")
|
|
62
|
+
.split(",")
|
|
63
|
+
.map((s) => s.trim())
|
|
64
|
+
.filter(Boolean),
|
|
65
|
+
userStories: [],
|
|
66
|
+
envVars: [],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function handleTextSubmit(key, required) {
|
|
71
|
+
return (value) => {
|
|
72
|
+
const val = value.trim();
|
|
73
|
+
if (required && !val) {
|
|
74
|
+
setError(`This field is required`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
advanceToNext(key, val);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function handleTechStackSubmit(values) {
|
|
81
|
+
advanceToNext("techStack", values.join(", "));
|
|
82
|
+
}
|
|
83
|
+
// Build completed fields display
|
|
84
|
+
const completedFields = PHASE_ORDER.slice(0, phaseIndex).map((key) => (_jsx(GutterLine, { children: _jsxs(Text, { dimColor: true, children: [key === "problem" && `Problem: ${answers[key]}`, key === "users" && `Users: ${answers[key]}`, key === "techStack" && `Tech stack: ${answers[key]}`, key === "coreFeatures" && `Core features: ${answers[key]}`, key === "nonGoals" && `Non-goals: ${answers[key]}`] }) }, key)));
|
|
85
|
+
const usersPlaceholder = answers["problem"]
|
|
86
|
+
? `People affected by: ${answers["problem"]}`
|
|
87
|
+
: "e.g. Developers, PMs, designers...";
|
|
88
|
+
return (_jsxs(_Fragment, { children: [completedFields, currentPhase === "problem" && (_jsxs(GutterLine, { children: [_jsx(Text, { bold: true, children: "What problem does this solve? " }), _jsx(TextInput, { placeholder: "Describe the core problem...", onSubmit: handleTextSubmit("problem", true) })] })), currentPhase === "users" && (_jsxs(GutterLine, { children: [_jsx(Text, { bold: true, children: "Who are the users? " }), _jsx(TextInput, { placeholder: usersPlaceholder, onSubmit: handleTextSubmit("users", true) })] })), currentPhase === "techStack" && (_jsxs(_Fragment, { children: [_jsx(GutterLine, { children: _jsx(Text, { bold: true, children: "Tech stack:" }) }), _jsx(GutteredMultiSelect, { options: TECH_STACK_OPTIONS, initialSelected: prefillTechStack, onSubmit: handleTechStackSubmit })] })), currentPhase === "coreFeatures" && (_jsxs(GutterLine, { children: [_jsx(Text, { bold: true, children: "Core features (comma-separated): " }), _jsx(TextInput, { placeholder: "e.g. Auth, Dashboard, API...", onSubmit: handleTextSubmit("coreFeatures", true) })] })), currentPhase === "nonGoals" && (_jsxs(GutterLine, { children: [_jsx(Text, { bold: true, children: "Non-goals (comma-separated): " }), _jsx(TextInput, { placeholder: "e.g. Mobile app, Real-time sync...", onSubmit: handleTextSubmit("nonGoals", false) })] })), error && (_jsx(GutterLine, { children: _jsx(Text, { color: "red", children: error }) }))] }));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=product-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-context.js","sourceRoot":"","sources":["../../src/steps/product-context.tsx"],"names":[],"mappings":"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"}
|