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.
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createPlanCommand(): Command;
3
+ //# sourceMappingURL=plan.d.ts.map
@@ -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();
@@ -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;AAE3C,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"}
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,6 @@
1
+ export interface BriefTemplateInput {
2
+ name: string;
3
+ description: string;
4
+ }
5
+ export declare function generateBriefTemplate(input: BriefTemplateInput): string;
6
+ //# sourceMappingURL=brief-template-generator.d.ts.map
@@ -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,6 @@
1
+ export interface PartialConfigInput {
2
+ name: string;
3
+ description: string;
4
+ }
5
+ export declare function writePartialConfig(outputDir: string, input: PartialConfigInput): Promise<string>;
6
+ //# sourceMappingURL=config-writer.d.ts.map
@@ -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,3 @@
1
+ import type { PlanInput, PlanResult } from './types.js';
2
+ export declare function runPlan(input: PlanInput): Promise<PlanResult>;
3
+ //# sourceMappingURL=plan-orchestrator.d.ts.map
@@ -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,6 @@
1
+ export interface SkillInput {
2
+ name: string;
3
+ description: string;
4
+ }
5
+ export declare function generatePlanAppSkill(input?: SkillInput): string;
6
+ //# sourceMappingURL=skill-generator.d.ts.map
@@ -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,6 @@
1
+ export function isValidSnakeCase(name) {
2
+ if (!name)
3
+ return false;
4
+ return /^[a-z][a-z0-9_]*$/.test(name);
5
+ }
6
+ //# sourceMappingURL=types.js.map
@@ -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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maxsim-flutter",
3
- "version": "1.27.0",
3
+ "version": "1.29.0",
4
4
  "description": "AI-powered Flutter app scaffolding with Clean Architecture, Riverpod, and autonomous development via Ralph",
5
5
  "type": "module",
6
6
  "bin": {