maxsim-flutter 1.27.0 → 1.29.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/dist/cli/commands/plan.d.ts +3 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +76 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/plan/brief-template-generator.d.ts +6 -0
- package/dist/plan/brief-template-generator.d.ts.map +1 -0
- package/dist/plan/brief-template-generator.js +65 -0
- package/dist/plan/brief-template-generator.js.map +1 -0
- package/dist/plan/config-writer.d.ts +6 -0
- package/dist/plan/config-writer.d.ts.map +1 -0
- package/dist/plan/config-writer.js +18 -0
- package/dist/plan/config-writer.js.map +1 -0
- package/dist/plan/plan-orchestrator.d.ts +3 -0
- package/dist/plan/plan-orchestrator.d.ts.map +1 -0
- package/dist/plan/plan-orchestrator.js +31 -0
- package/dist/plan/plan-orchestrator.js.map +1 -0
- package/dist/plan/skill-generator.d.ts +6 -0
- package/dist/plan/skill-generator.d.ts.map +1 -0
- package/dist/plan/skill-generator.js +84 -0
- package/dist/plan/skill-generator.js.map +1 -0
- package/dist/plan/types.d.ts +11 -0
- package/dist/plan/types.d.ts.map +1 -0
- package/dist/plan/types.js +6 -0
- package/dist/plan/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,iBAAiB,IAAI,OAAO,CAiB3C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import * as p from '@clack/prompts';
|
|
4
|
+
import { runPlan } from '../../plan/plan-orchestrator.js';
|
|
5
|
+
import { isValidSnakeCase } from '../../plan/types.js';
|
|
6
|
+
export function createPlanCommand() {
|
|
7
|
+
const cmd = new Command('plan');
|
|
8
|
+
cmd
|
|
9
|
+
.description('Bootstrap a planning workspace for a new Flutter app with AI-guided setup')
|
|
10
|
+
.argument('[app-name]', 'Name of the Flutter application (snake_case)')
|
|
11
|
+
.option('--description <text>', 'Short description of your app (1-2 sentences)')
|
|
12
|
+
.action(async (appName, options) => {
|
|
13
|
+
try {
|
|
14
|
+
await runPlanCommand(appName, options);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return cmd;
|
|
22
|
+
}
|
|
23
|
+
async function runPlanCommand(appName, options) {
|
|
24
|
+
p.intro('maxsim-flutter — Bootstrap a planning workspace');
|
|
25
|
+
// Prompt for project name if not provided
|
|
26
|
+
let name = appName;
|
|
27
|
+
if (!name) {
|
|
28
|
+
const nameResult = await p.text({
|
|
29
|
+
message: 'What is your project name? (snake_case)',
|
|
30
|
+
placeholder: 'my_flutter_app',
|
|
31
|
+
validate: (value) => {
|
|
32
|
+
if (!isValidSnakeCase(value)) {
|
|
33
|
+
return 'Project name must be snake_case (lowercase letters, digits, and underscores only)';
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
if (p.isCancel(nameResult)) {
|
|
39
|
+
p.cancel('Planning cancelled.');
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
name = nameResult;
|
|
43
|
+
}
|
|
44
|
+
else if (!isValidSnakeCase(name)) {
|
|
45
|
+
p.log.error(`Invalid project name "${name}". Must be snake_case (e.g., my_app).`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
// Prompt for description if not provided
|
|
49
|
+
let description = options.description;
|
|
50
|
+
if (!description) {
|
|
51
|
+
const descResult = await p.text({
|
|
52
|
+
message: 'Briefly describe your app (1-2 sentences):',
|
|
53
|
+
placeholder: 'A productivity app that helps teams collaborate on daily tasks.',
|
|
54
|
+
validate: (value) => {
|
|
55
|
+
if (!value.trim())
|
|
56
|
+
return 'Description cannot be empty';
|
|
57
|
+
return undefined;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
if (p.isCancel(descResult)) {
|
|
61
|
+
p.cancel('Planning cancelled.');
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
description = descResult;
|
|
65
|
+
}
|
|
66
|
+
const outputDir = join(process.cwd(), name);
|
|
67
|
+
p.log.info(`Creating planning workspace in ./${name}/`);
|
|
68
|
+
const result = await runPlan({ name, description, outputDir });
|
|
69
|
+
p.log.success(`Created ${result.filesCreated.length} files`);
|
|
70
|
+
p.outro(`Planning workspace ready! Next steps:\n\n` +
|
|
71
|
+
` 1. cd ${name}\n` +
|
|
72
|
+
` 2. Fill in docs/project-brief-template.md\n` +
|
|
73
|
+
` 3. Open Claude Code: claude\n` +
|
|
74
|
+
` 4. Run the planning skill: /plan-app\n`);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/cli/commands/plan.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createAddCommand } from './commands/add.js';
|
|
|
6
6
|
import { createMigrateCommand } from './commands/migrate.js';
|
|
7
7
|
import { createListCommand } from './commands/list.js';
|
|
8
8
|
import { createUpgradeCommand } from './commands/upgrade.js';
|
|
9
|
+
import { createPlanCommand } from './commands/plan.js';
|
|
9
10
|
import { checkForUpdate } from './version-check.js';
|
|
10
11
|
const program = new Command();
|
|
11
12
|
program
|
|
@@ -18,6 +19,7 @@ program.addCommand(createAddCommand());
|
|
|
18
19
|
program.addCommand(createMigrateCommand());
|
|
19
20
|
program.addCommand(createListCommand());
|
|
20
21
|
program.addCommand(createUpgradeCommand());
|
|
22
|
+
program.addCommand(createPlanCommand());
|
|
21
23
|
program.parse();
|
|
22
24
|
// Non-blocking update nudge (fires after the command completes)
|
|
23
25
|
const opts = program.opts();
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,4GAA4G,CAAC;KACzH,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC,CAAC;AAE5D,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,4GAA4G,CAAC;KACzH,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC,CAAC;AAE5D,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAExC,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,gEAAgE;AAChE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAA4B,CAAC;AACtD,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;IAC/B,cAAc,EAAE;SACb,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE;QACtB,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,OAAO,CAAC;YAC7C,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CACV,uBAAuB,OAAO,MAAM,aAAa,gDAAgD,CAClG,CACF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,EAAE;QACV,kBAAkB;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief-template-generator.d.ts","sourceRoot":"","sources":["../../src/plan/brief-template-generator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CA+DvE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export function generateBriefTemplate(input) {
|
|
2
|
+
return `# Project Brief — ${input.name}
|
|
3
|
+
|
|
4
|
+
## App Description
|
|
5
|
+
|
|
6
|
+
${input.description}
|
|
7
|
+
|
|
8
|
+
## Problem Statement
|
|
9
|
+
|
|
10
|
+
<!-- What specific problem does this app solve? Why does it need to exist? -->
|
|
11
|
+
|
|
12
|
+
## Target Users
|
|
13
|
+
|
|
14
|
+
<!-- Who are the primary users of this app? -->
|
|
15
|
+
|
|
16
|
+
### Persona: [Primary User Type]
|
|
17
|
+
|
|
18
|
+
- **Role**: (e.g., freelancer, student, team manager)
|
|
19
|
+
- **Goal**: What they want to accomplish
|
|
20
|
+
- **Pain point**: What frustrates them today
|
|
21
|
+
- **Tech comfort**: Low / Medium / High
|
|
22
|
+
|
|
23
|
+
### Persona: [Secondary User Type] (optional)
|
|
24
|
+
|
|
25
|
+
- **Role**:
|
|
26
|
+
- **Goal**:
|
|
27
|
+
- **Pain point**:
|
|
28
|
+
|
|
29
|
+
## Core User Journeys
|
|
30
|
+
|
|
31
|
+
<!-- Describe the 3-5 most important flows a user will complete. -->
|
|
32
|
+
|
|
33
|
+
1. **[Journey 1]**: (e.g., Sign up → complete profile → create first item)
|
|
34
|
+
2. **[Journey 2]**:
|
|
35
|
+
3. **[Journey 3]**:
|
|
36
|
+
4.
|
|
37
|
+
5.
|
|
38
|
+
|
|
39
|
+
## Explicit Non-Goals
|
|
40
|
+
|
|
41
|
+
<!-- What are you NOT building in v1? Be specific to avoid scope creep. -->
|
|
42
|
+
|
|
43
|
+
- Not building:
|
|
44
|
+
- Not supporting:
|
|
45
|
+
- Deferred to v2:
|
|
46
|
+
|
|
47
|
+
## Success Metrics
|
|
48
|
+
|
|
49
|
+
<!-- How will you know the app is successful? -->
|
|
50
|
+
|
|
51
|
+
- Activation: (e.g., X% of users complete onboarding)
|
|
52
|
+
- Engagement: (e.g., DAU/MAU ratio)
|
|
53
|
+
- Retention: (e.g., 30-day retention rate)
|
|
54
|
+
|
|
55
|
+
## Technical Constraints
|
|
56
|
+
|
|
57
|
+
<!-- Platform targets, integrations, performance requirements. -->
|
|
58
|
+
|
|
59
|
+
- Platforms: iOS, Android
|
|
60
|
+
- Authentication:
|
|
61
|
+
- Backend / API:
|
|
62
|
+
- Offline support: Yes / No
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=brief-template-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief-template-generator.js","sourceRoot":"","sources":["../../src/plan/brief-template-generator.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,qBAAqB,CAAC,KAAyB;IAC7D,OAAO,qBAAqB,KAAK,CAAC,IAAI;;;;EAItC,KAAK,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDlB,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../src/plan/config-writer.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBtG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
export async function writePartialConfig(outputDir, input) {
|
|
4
|
+
await mkdir(outputDir, { recursive: true });
|
|
5
|
+
const content = [
|
|
6
|
+
`project:`,
|
|
7
|
+
` name: ${input.name}`,
|
|
8
|
+
` description: >-`,
|
|
9
|
+
` ${input.description}`,
|
|
10
|
+
``,
|
|
11
|
+
`# Run maxsim-flutter create to complete your project setup`,
|
|
12
|
+
`# after filling in the project-brief-template.md`,
|
|
13
|
+
].join('\n');
|
|
14
|
+
const filePath = join(outputDir, 'maxsim.config.yaml');
|
|
15
|
+
await writeFile(filePath, content, 'utf-8');
|
|
16
|
+
return filePath;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=config-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../src/plan/config-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAOpD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB,EAAE,KAAyB;IACnF,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG;QACd,UAAU;QACV,WAAW,KAAK,CAAC,IAAI,EAAE;QACvB,mBAAmB;QACnB,OAAO,KAAK,CAAC,WAAW,EAAE;QAC1B,EAAE;QACF,4DAA4D;QAC5D,kDAAkD;KACnD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACvD,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-orchestrator.d.ts","sourceRoot":"","sources":["../../src/plan/plan-orchestrator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKxD,wBAAsB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA6BnE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { writePartialConfig } from './config-writer.js';
|
|
4
|
+
import { generateBriefTemplate } from './brief-template-generator.js';
|
|
5
|
+
import { generatePlanAppSkill } from './skill-generator.js';
|
|
6
|
+
export async function runPlan(input) {
|
|
7
|
+
const { name, description, outputDir } = input;
|
|
8
|
+
const filesCreated = [];
|
|
9
|
+
// Create project directory
|
|
10
|
+
await mkdir(outputDir, { recursive: true });
|
|
11
|
+
// Write partial maxsim.config.yaml
|
|
12
|
+
const configPath = await writePartialConfig(outputDir, { name, description });
|
|
13
|
+
filesCreated.push(configPath);
|
|
14
|
+
// Write .claude/skills/plan-app.md
|
|
15
|
+
const skillsDir = join(outputDir, '.claude', 'skills');
|
|
16
|
+
await mkdir(skillsDir, { recursive: true });
|
|
17
|
+
const skillPath = join(skillsDir, 'plan-app.md');
|
|
18
|
+
await writeFile(skillPath, generatePlanAppSkill({ name, description }), 'utf-8');
|
|
19
|
+
filesCreated.push(skillPath);
|
|
20
|
+
// Write docs/project-brief-template.md
|
|
21
|
+
const docsDir = join(outputDir, 'docs');
|
|
22
|
+
await mkdir(docsDir, { recursive: true });
|
|
23
|
+
const briefPath = join(docsDir, 'project-brief-template.md');
|
|
24
|
+
await writeFile(briefPath, generateBriefTemplate({ name, description }), 'utf-8');
|
|
25
|
+
filesCreated.push(briefPath);
|
|
26
|
+
return {
|
|
27
|
+
projectDir: outputDir,
|
|
28
|
+
filesCreated,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=plan-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-orchestrator.js","sourceRoot":"","sources":["../../src/plan/plan-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAgB;IAC5C,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,2BAA2B;IAC3B,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,mCAAmC;IACnC,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC9E,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAE9B,mCAAmC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACjD,MAAM,SAAS,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IACjF,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE7B,uCAAuC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;IAC7D,MAAM,SAAS,CAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAClF,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE7B,OAAO;QACL,UAAU,EAAE,SAAS;QACrB,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-generator.d.ts","sourceRoot":"","sources":["../../src/plan/skill-generator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAmF/D"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export function generatePlanAppSkill(input) {
|
|
2
|
+
const name = input?.name ?? 'your_app';
|
|
3
|
+
const description = input?.description ?? 'A Flutter app';
|
|
4
|
+
return `---
|
|
5
|
+
description: AI-guided planning for ${name}. Leads through vision, features, technical decisions, and PRD generation. Ask questions one at a time.
|
|
6
|
+
model: claude-opus-4-6
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /plan-app — ${name}
|
|
10
|
+
|
|
11
|
+
You are a product planning expert helping design a Flutter app using maxsim-flutter.
|
|
12
|
+
|
|
13
|
+
**Project**: ${name}
|
|
14
|
+
**Description**: ${description}
|
|
15
|
+
|
|
16
|
+
> **Important**: Ask questions one at a time. Wait for the user's answer before asking the next question.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Step 1: Understand Vision
|
|
21
|
+
|
|
22
|
+
Start by understanding the core problem this app solves.
|
|
23
|
+
|
|
24
|
+
**Question 1.1** — What specific problem does **${name}** solve, and for whom?
|
|
25
|
+
*(Understanding the problem before building ensures you build the right thing.)*
|
|
26
|
+
|
|
27
|
+
**Question 1.2** — Walk me through the most important user journey: what does the user do from the moment they open the app to achieving their goal?
|
|
28
|
+
*(This reveals the critical path and core feature set.)*
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Step 2: Define Core Features
|
|
33
|
+
|
|
34
|
+
Narrow down what the app will actually build.
|
|
35
|
+
|
|
36
|
+
**Question 2.1** — What are the top 3 features that **must** exist in v1? (Ignore "nice to haves" for now.)
|
|
37
|
+
*(Focused scope prevents the most common cause of project failure.)*
|
|
38
|
+
|
|
39
|
+
**Question 2.2** — What are the explicit **non-goals** — features you are intentionally NOT building in v1?
|
|
40
|
+
*(Saying "no" early saves months of scope creep.)*
|
|
41
|
+
|
|
42
|
+
**Question 2.3** — Is this a solo project or will you work with a team?
|
|
43
|
+
*(This affects architecture complexity, auth requirements, and CI/CD needs.)*
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Step 3: Technical Decisions
|
|
48
|
+
|
|
49
|
+
Use this decision tree to guide module selection. Ask each sub-question only if relevant.
|
|
50
|
+
|
|
51
|
+
### Auth Decision
|
|
52
|
+
**Question 3.1** — Does the app require user accounts?
|
|
53
|
+
- **Yes** → Which provider? Firebase Auth / Supabase / Custom backend
|
|
54
|
+
- **No** → Skip auth module
|
|
55
|
+
|
|
56
|
+
### Backend & Database Decision
|
|
57
|
+
**Question 3.2** — Does the app need to store or sync data across devices?
|
|
58
|
+
- **Cloud sync** → Which backend? Firebase Firestore / Supabase / REST API
|
|
59
|
+
- **Local only** → Use the \`database\` module (SQLite/Hive)
|
|
60
|
+
- **No persistence** → Skip database module
|
|
61
|
+
|
|
62
|
+
### Platform Decision
|
|
63
|
+
**Question 3.3** — Which platforms must ship in v1?
|
|
64
|
+
- iOS and Android (default)
|
|
65
|
+
- Web app as well?
|
|
66
|
+
- Desktop (macOS / Windows / Linux)?
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## After Collecting Answers
|
|
71
|
+
|
|
72
|
+
Once you have answers to all questions, generate:
|
|
73
|
+
|
|
74
|
+
1. **Updated \`maxsim.config.yaml\`** with selected modules
|
|
75
|
+
2. **\`prd.json\`** with user stories organized by phase
|
|
76
|
+
3. **\`docs/architecture.md\`** with system design overview
|
|
77
|
+
|
|
78
|
+
Then tell the user:
|
|
79
|
+
\`\`\`
|
|
80
|
+
maxsim-flutter create --config maxsim.config.yaml
|
|
81
|
+
\`\`\`
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=skill-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-generator.js","sourceRoot":"","sources":["../../src/plan/skill-generator.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,oBAAoB,CAAC,KAAkB;IACrD,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,UAAU,CAAC;IACvC,MAAM,WAAW,GAAG,KAAK,EAAE,WAAW,IAAI,eAAe,CAAC;IAE1D,OAAO;sCAC6B,IAAI;;;;gBAI1B,IAAI;;;;eAIL,IAAI;mBACA,WAAW;;;;;;;;;;kDAUoB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DrD,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface PlanInput {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
outputDir: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PlanResult {
|
|
7
|
+
projectDir: string;
|
|
8
|
+
filesCreated: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function isValidSnakeCase(name: string): boolean;
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plan/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plan/types.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
|