@mr.dj2u/cli 0.1.15 → 0.1.17

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.
Files changed (30) hide show
  1. package/bundles/claude-code/.claude-plugin/plugin.json +1 -1
  2. package/bundles/claude-code/.mcp.json +1 -1
  3. package/bundles/claude-code/commands/create-expo-super-stack.md +36 -11
  4. package/bundles/claude-code/skills/create-expo-super-stack/SKILL.md +37 -12
  5. package/bundles/codex/.codex-plugin/plugin.json +1 -1
  6. package/bundles/codex/.mcp.json +1 -1
  7. package/bundles/codex/README.md +14 -1
  8. package/bundles/codex/commands/create-expo-super-stack.md +36 -11
  9. package/bundles/codex/skills/workflow-create-expo-super-stack/SKILL.md +36 -11
  10. package/bundles/vscode-copilot/.github/prompts/create-expo-super-stack.prompt.md +36 -11
  11. package/bundles/vscode-copilot/.vscode/mcp.json +1 -1
  12. package/bundles/vscode-copilot/README.md +14 -0
  13. package/bundles/vscode-copilot/user/.copilot/skills/workflow-create-expo-super-stack/SKILL.md +36 -11
  14. package/dist/cess-intake.d.ts +1 -1
  15. package/dist/cess-intake.d.ts.map +1 -1
  16. package/dist/cess-intake.js +302 -28
  17. package/dist/cess-intake.js.map +1 -1
  18. package/dist/commands/mcp-install.d.ts +2 -2
  19. package/dist/commands/mcp-install.js +1 -1
  20. package/dist/commands/onboard.d.ts +1 -1
  21. package/dist/commands/onboard.d.ts.map +1 -1
  22. package/dist/project-memory.d.ts +1 -1
  23. package/dist/project-memory.d.ts.map +1 -1
  24. package/dist/project-memory.js +96 -194
  25. package/dist/project-memory.js.map +1 -1
  26. package/dist/roadmap.d.ts +7 -2
  27. package/dist/roadmap.d.ts.map +1 -1
  28. package/dist/roadmap.js +255 -34
  29. package/dist/roadmap.js.map +1 -1
  30. package/package.json +2 -2
@@ -45,26 +45,22 @@ const DEFAULT_GUIDELINES_TEMPLATE_PATH = path.join(PACKAGE_ROOT, 'templates', 'p
45
45
  const STYLIST_SCREEN_TEMPLATE_PATH = path.join(PACKAGE_ROOT, 'templates', 'stylist-screen.template.tsx');
46
46
  const EMBEDDED_FONTS_TEMPLATE_PATH = path.join(PACKAGE_ROOT, 'templates', 'embedded-fonts.template.ts');
47
47
  const EXPO_SDK_56_SCREEN_UNIVERSAL_TEMPLATE_PATH = path.join(PACKAGE_ROOT, 'templates', 'expo-sdk-56-screen-universal.template.tsx');
48
- const CESS_SNAPSHOT_START = '<!-- MDS_CESS_SNAPSHOT_START -->';
49
- const CESS_SNAPSHOT_END = '<!-- MDS_CESS_SNAPSHOT_END -->';
50
48
  const INFO_HEADINGS = [
49
+ 'App Name',
51
50
  'Overview',
52
51
  'Target Users',
52
+ 'Problem this app solves',
53
53
  'Product Goals',
54
54
  'Non-Goals',
55
- 'Core Features',
56
- 'Core User Flows',
57
- 'Must-Include Screens Or Flows',
58
- 'Data And Backend',
55
+ 'First User Flow',
56
+ 'Core Flows and Features',
57
+ 'Screens',
59
58
  'Platforms',
60
- 'Package Choices',
61
59
  'Monetization Strategy',
62
60
  'Team Context',
63
- 'Release Strategy',
64
- 'Questions To Revisit',
65
- 'Open Questions',
66
- 'Resources',
67
- 'Tech Stack & MDS Onboarding',
61
+ 'Later Scope & Possibilities',
62
+ 'Research, Notes, and References',
63
+ 'Tech Stack & CESS Onboarding',
68
64
  ];
69
65
  const STYLE_HEADINGS = [
70
66
  'Visual Direction',
@@ -217,9 +213,15 @@ export async function scaffoldRichBoilerplate(projectPath, answers, force, optio
217
213
  export function renderInfo(projectPath, answers, existingInfo) {
218
214
  const importedNotes = renderImportedNotes(existingInfo, INFO_HEADINGS);
219
215
  const hasConcreteCoreFlows = !isGenericCoreFlowsText(answers.coreFlows);
216
+ const firstFlow = hasConcreteCoreFlows
217
+ ? extractFirstNonEmptyLine(answers.coreFlows)
218
+ : '# TodoForContext(optional): Describe the first real end-to-end user flow the MVP should support.';
220
219
  return [
221
220
  `# ${answers.appName} Project Info`,
222
221
  '',
222
+ '## App Name',
223
+ answers.appName,
224
+ '',
223
225
  '## Overview',
224
226
  '',
225
227
  `Build an Expo app for ${answers.audience}.`,
@@ -228,6 +230,9 @@ export function renderInfo(projectPath, answers, existingInfo) {
228
230
  '',
229
231
  answers.audience,
230
232
  '',
233
+ '## Problem this app solves',
234
+ '# TodoForContext(optional): Explain the user problem or pain this app exists to solve.',
235
+ '',
231
236
  '## Product Goals',
232
237
  '',
233
238
  '# TodoForContext(optional): Add the business/product outcomes that would make this app successful.',
@@ -236,49 +241,26 @@ export function renderInfo(projectPath, answers, existingInfo) {
236
241
  '',
237
242
  '# TodoForContext(optional): Add anything this app should intentionally avoid for the MVP.',
238
243
  '',
239
- '## Core Features',
244
+ '## First User Flow',
240
245
  '',
241
- hasConcreteCoreFlows
242
- ? `Derived from the first planned flows: ${answers.coreFlows}`
243
- : '# TodoForContext(optional): List the first core features the MVP should deliver.',
246
+ firstFlow,
244
247
  '',
245
- '## Core User Flows',
248
+ '## Core Flows and Features',
246
249
  '',
247
250
  hasConcreteCoreFlows
248
251
  ? answers.coreFlows
249
- : '# TodoForContext(optional): Describe the first real end-to-end user flow the MVP should support.',
252
+ : '# TodoForContext(optional): List the first core flows and features the MVP should deliver.',
250
253
  '',
251
- '## Must-Include Screens Or Flows',
254
+ '## Screens',
252
255
  '',
253
256
  answers.screens?.trim()
254
257
  ? answers.screens
255
- : '# TodoForContext(optional): List any known screens or flows that must be included in planning and implementation.',
256
- '',
257
- '## Data And Backend',
258
- '',
259
- answers.dataNeeds,
260
- '',
261
- `Starting mode: ${formatDataStart(answers.dataStart)}.`,
258
+ : '# TodoForContext(optional): List any known screens that must be included in planning and implementation.',
262
259
  '',
263
260
  '## Platforms',
264
261
  '',
265
262
  `- Target platforms: ${answers.targetPlatforms.join(', ') || 'none selected'}`,
266
263
  `- First MVP platform: ${answers.firstTargetPlatform}`,
267
- `- Expo Router app directory: ${formatAppDirectory(answers.appDirectory)}`,
268
- `- Platform-specific organization: ${formatPlatformStrategy(answers.platformFileStrategy)}`,
269
- `- Platform layout mode: ${formatPlatformLayoutMode(answers.platformLayoutMode)}`,
270
- `- Web output: ${answers.webOutput}`,
271
- `- Deployed server: ${formatServerChoice(answers.deployedServer)}`,
272
- `- Expo UI: ${formatBoolean(answers.usesExpoUi)}`,
273
- `- Expo UI Universal components: ${formatBoolean(answers.usesExpoUiUniversalComponents)}`,
274
- `- Expo Native Tabs: ${formatBoolean(answers.usesExpoNativeTabs)}`,
275
- '',
276
- '## Package Choices',
277
- '',
278
- answers.defaults.map((item) => `- ${item}`).join('\n'),
279
- '',
280
- '- Software Mansion core examples are included for Reanimated/Worklets, Gesture Handler, Screens, SVG, and Keyboard Controller.',
281
- '- Prune package examples and dependencies after reviewing the exposition pages.',
282
264
  '',
283
265
  '## Monetization Strategy',
284
266
  '',
@@ -288,58 +270,50 @@ export function renderInfo(projectPath, answers, existingInfo) {
288
270
  '',
289
271
  '# TodoForContext(optional): Add team size, roles, delegated responsibilities, stakeholders, and client contacts if useful.',
290
272
  '',
291
- '## Release Strategy',
273
+ '## Later Scope & Possibilities',
292
274
  '',
293
- `- Deployment plan: ${answers.deploymentTarget}`,
294
- `- EAS usage: ${answers.easUses.length > 0 ? answers.easUses.join(', ') : 'not planned yet'}`,
295
- `- Test-to-main safeguards: ${formatBoolean(answers.testToMainSafeguards)}`,
275
+ '# TodoForContext(optional): Add future ideas or enhancements outside the first MVP.',
296
276
  '',
297
- '## Questions To Revisit',
298
- '',
299
- '',
300
- '## Resources',
277
+ '## Research, Notes, and References',
301
278
  '',
302
279
  `- Source project: ${projectPath}`,
303
280
  '- # TodoForContext(optional): Add designs, repos, docs, client notes, analytics, credentials process, or research links.',
304
281
  '',
305
282
  ...importedNotes,
306
283
  '',
307
- '## Tech Stack & MDS Onboarding',
284
+ '# Tech Stack & CESS Onboarding',
308
285
  '',
309
- '> Quick-reference stack summary for agents and collaborators. Fill in or correct any items marked below.',
286
+ `- TypeScript: ${formatYesNo(answers.generatorScriptLanguage !== 'javascript')}`,
287
+ `- Package Manager: ${answers.generatorPackageManager ?? 'npm'}`,
288
+ `- Navigation: ${formatGeneratorNavigation(answers.generatorNavigationLibrary)}`,
289
+ `- Type of Navigation: ${formatGeneratorNavigationType(answers.generatorReactNavigationLayout)}`,
290
+ `- Expo Router app directory: ${formatAppDirectory(answers.appDirectory)}`,
291
+ `- Platform-specific organization: ${formatPlatformStrategy(answers.platformFileStrategy)}`,
292
+ `- Platform layout mode: ${formatPlatformLayoutMode(answers.platformLayoutMode)}`,
293
+ `- Web output: ${answers.webOutput}`,
310
294
  '',
311
- CESS_SNAPSHOT_START,
312
- '```json',
313
- JSON.stringify(buildCessSnapshot(answers), null, 2),
314
- '```',
315
- CESS_SNAPSHOT_END,
316
- '',
317
- `- **App:** ${answers.appName} — ${answers.audience}`,
318
- `- **Language:** ${formatGeneratorLanguage(answers.generatorScriptLanguage)}`,
319
- `- **Package manager:** ${formatGeneratorPackageManager(answers.generatorPackageManager)}`,
320
- `- **Routing:** ${formatGeneratorRouting(answers)}`,
321
- `- **Styling:** ${formatStyleStack(answers)}`,
322
- `- **State management:** ${formatGeneratorStateManagement(answers.generatorStateManagement)}`,
323
- `- **Auth:** ${formatAuthSummary(answers)}`,
324
- `- **Data:** ${formatDataStart(answers.dataStart)}`,
325
- `- **Platforms:** ${answers.targetPlatforms.join(', ') || 'none selected'}, first MVP target: ${answers.firstTargetPlatform}`,
326
- `- **Code organization:** ${formatCodeOrg(answers)}`,
327
- `- **Deployed server:** ${formatServerAdapterSummary(answers)}`,
328
- `- **Distribution:** ${answers.deploymentTarget}`,
329
- `- **EAS:** ${answers.easUses.length > 0 ? answers.easUses.join(', ') : 'not planned yet'}`,
330
- '',
331
- '### MDS Onboarding Decisions',
332
- '',
333
- `- Advanced package setup: ${formatBoolean(answers.advancedPackageSetup)}`,
334
- `- Create Expo starter components: ${formatBoolean(answers.includeCreateExpoComponents)}`,
335
- `- EAS starter selected during generation: ${formatBoolean(answers.generatorEasSetup ?? answers.easUses.length > 0)}`,
336
- `- MDS guidelines template: yes`,
337
- `- Expo UI: ${formatBoolean(answers.usesExpoUi)}`,
338
- `- Expo UI Universal components: ${formatBoolean(answers.usesExpoUiUniversalComponents)}`,
339
- `- Expo Native Tabs: ${formatBoolean(answers.usesExpoNativeTabs)}`,
340
- `- Test-to-main safeguards: ${formatBoolean(answers.testToMainSafeguards)}`,
341
- `- Data start: ${formatDataStart(answers.dataStart)}`,
342
- `- Defaults selected: ${answers.defaults.join(', ')}`,
295
+ `- Style Library: ${formatCessStyleLibrary(answers)}`,
296
+ '- Which NativeWindUI components: All',
297
+ `- Components from create-expo-app: ${formatYesNo(answers.includeCreateExpoComponents)}`,
298
+ `- Expo UI: ${formatYesNo(answers.usesExpoUi)}`,
299
+ `- Expo UI Universal components: ${formatYesNo(answers.usesExpoUiUniversalComponents)}`,
300
+ `- Expo Native Tabs: ${formatYesNo(answers.usesExpoNativeTabs)}`,
301
+ '',
302
+ '- Which Software Mansion packages: All',
303
+ `- State management library: ${formatGeneratorStateManagement(answers.generatorStateManagement)}`,
304
+ `- Auth: ${formatGeneratorAuth(answers.generatorAuthBackend)}`,
305
+ `- Data Categories: ${answers.dataNeeds}`,
306
+ `- Starting Data mode: ${formatDataStart(answers.dataStart)}.`,
307
+ '',
308
+ '- Internationalization: None',
309
+ '- Analytics: None',
310
+ `- EAS: ${formatYesNo(answers.generatorEasSetup ?? answers.easUses.length > 0)}`,
311
+ `- EAS Usage: ${answers.easUses.length > 0 ? answers.easUses.join(', ') : 'not planned yet'}`,
312
+ `- Deployed server: ${formatServerChoice(answers.deployedServer)}`,
313
+ `- Initial Deployment plan: ${answers.deploymentTarget}`,
314
+ '',
315
+ `- Start with MDS project guidelines template: ${formatYesNo(true)}`,
316
+ `- Use test-to-main safeguards: ${formatYesNo(answers.testToMainSafeguards)}`,
343
317
  '',
344
318
  ].join('\n');
345
319
  }
@@ -354,6 +328,9 @@ export function renderTodo(answers) {
354
328
  '- [ ] Review `project/` files for accuracy and planning adjustments.',
355
329
  '- [ ] Run or defer `eject-stylist`; mark this todo done after ejection or deciding to defer (if you want to keep the stylist around for tinkering).',
356
330
  '- [ ] Run `mds eject exposition` and keep only the generated sections you want to retain.',
331
+ ...(answers.generatorEasSetup ?? answers.easUses.length > 0
332
+ ? ['- [ ] Sign in and set up EAS in the terminal.']
333
+ : []),
357
334
  '- [ ] Resolve every `# TodoForContext(optional):` marker in `project/info.md` by filling the section underneath or deleting the marker line to acknowledge no extra context is needed.',
358
335
  '- [ ] Confirm visual direction in `project/style.md` after using the Stylist page.',
359
336
  '- [ ] After the `project/info.md` markers are resolved, refresh the agent-derived roadmap from `project/info.md` and review it for accuracy.',
@@ -880,22 +857,6 @@ function formatServerChoice(value) {
880
857
  function formatDataStart(value) {
881
858
  return value === 'supabase' ? 'Supabase from the start' : 'local dummy data with Expo SQLite';
882
859
  }
883
- function formatServerAdapterSummary(answers) {
884
- if (answers.webOutput === 'none')
885
- return 'none (native-only)';
886
- switch (answers.expoServerAdapter) {
887
- case 'eas':
888
- return 'EAS hosting';
889
- case 'express':
890
- return 'Express adapter (node server.js, port 3000)';
891
- case 'bun':
892
- return 'Bun adapter (node server.js)';
893
- case 'other':
894
- return 'custom (not yet specified)';
895
- default:
896
- return formatServerChoice(answers.deployedServer);
897
- }
898
- }
899
860
  function deriveServeProdScript(answers) {
900
861
  if (answers.expoServerAdapter === 'express' || answers.expoServerAdapter === 'bun') {
901
862
  return 'node server.js';
@@ -908,105 +869,53 @@ function deriveServeProdFreshScript(answers) {
908
869
  }
909
870
  return `${MDS_NPX_COMMAND} free-port 8081 && npm run build:web && npx expo serve`;
910
871
  }
911
- function formatStyleStack(answers) {
912
- if (answers.defaults.includes('uniwind')) {
913
- return 'Uniwind / Tailwind CSS v4';
914
- }
915
- if (answers.defaults.includes('nativewindui')) {
916
- return 'NativeWindUI / NativeWind';
872
+ function extractFirstNonEmptyLine(value) {
873
+ return (value
874
+ .split(/\r?\n/u)
875
+ .map((line) => line.replace(/^[-*]\s+/u, '').trim())
876
+ .find(Boolean) ?? value.trim());
877
+ }
878
+ function formatYesNo(value) {
879
+ return value ? 'Yes' : 'No';
880
+ }
881
+ function formatGeneratorNavigation(value) {
882
+ return value === 'react-navigation' ? 'React Navigation' : 'Expo Router';
883
+ }
884
+ function formatGeneratorNavigationType(value) {
885
+ if (value === 'tabs') {
886
+ return 'Tabs';
917
887
  }
918
- if (answers.defaults.includes('nativewind')) {
919
- return 'NativeWind / Tailwind CSS';
888
+ if (value === 'drawer') {
889
+ return 'Drawer + Tabs';
920
890
  }
921
- if (answers.defaults.includes('unistyles')) {
922
- return 'Unistyles';
891
+ return 'Stack';
892
+ }
893
+ function formatCessStyleLibrary(answers) {
894
+ if (answers.generatorStylingSystem === 'nativewindui' || answers.defaults.includes('nativewindui')) {
895
+ return 'NativeWindUI';
923
896
  }
924
- if (answers.defaults.includes('restyle')) {
925
- return 'Shopify Restyle';
897
+ if (answers.generatorStylingSystem === 'nativewind' || answers.defaults.includes('nativewind')) {
898
+ return 'NativeWind';
926
899
  }
927
- if (answers.defaults.includes('tamagui')) {
900
+ if (answers.generatorStylingSystem === 'tamagui' || answers.defaults.includes('tamagui')) {
928
901
  return 'Tamagui';
929
902
  }
930
- return 'standard React Native StyleSheet';
931
- }
932
- function formatAuthSummary(answers) {
933
- if (answers.dataStart === 'supabase' || answers.defaults.includes('supabase')) {
934
- return 'Supabase auth (available via supabase-js)';
903
+ if (answers.generatorStylingSystem === 'restyle' || answers.defaults.includes('restyle')) {
904
+ return 'Restyle';
935
905
  }
936
- return 'no auth planned yet';
937
- }
938
- function formatCodeOrg(answers) {
939
- const parts = [
940
- formatPlatformStrategy(answers.platformFileStrategy),
941
- `${formatAppDirectory(answers.appDirectory)} routes`,
942
- formatPlatformLayoutMode(answers.platformLayoutMode),
943
- ];
944
- if (answers.webOutput === 'none') {
945
- parts.push('no web');
946
- }
947
- else {
948
- parts.push(`web: ${answers.webOutput}`);
906
+ if (answers.generatorStylingSystem === 'stylesheet') {
907
+ return 'StyleSheet';
949
908
  }
950
- return parts.join(', ');
909
+ return 'Uniwind';
951
910
  }
952
- function buildCessSnapshot(answers) {
953
- return {
954
- version: 1,
955
- displayAppName: answers.appName,
956
- folderSlug: toKebabCase(answers.appName),
957
- answers: {
958
- scriptLanguage: answers.generatorScriptLanguage,
959
- packageManager: answers.generatorPackageManager,
960
- navigationLibrary: answers.generatorNavigationLibrary,
961
- reactNavigationLayout: answers.generatorReactNavigationLayout,
962
- stylingSystem: answers.generatorStylingSystem,
963
- stateManagement: answers.generatorStateManagement,
964
- authBackend: answers.generatorAuthBackend,
965
- easSetup: answers.generatorEasSetup,
966
- displayAppName: answers.appName,
967
- audience: answers.audience,
968
- coreFlows: answers.coreFlows,
969
- screens: answers.screens,
970
- targetPlatforms: answers.targetPlatforms,
971
- firstTargetPlatform: answers.firstTargetPlatform,
972
- platformStrategy: answers.platformFileStrategy,
973
- appDirectory: answers.appDirectory,
974
- platformLayouts: answers.platformLayoutMode,
975
- webOutput: answers.webOutput,
976
- expoServerAdapter: answers.expoServerAdapter,
977
- customBackend: answers.customBackend,
978
- customBackendEntry: answers.customBackendEntry,
979
- deploymentTarget: answers.deploymentTarget,
980
- includeCreateExpoComponents: answers.includeCreateExpoComponents,
981
- usesExpoUi: answers.usesExpoUi,
982
- usesExpoUiUniversalComponents: answers.usesExpoUiUniversalComponents,
983
- usesExpoNativeTabs: answers.usesExpoNativeTabs,
984
- easUses: answers.easUses,
985
- guidelinesTemplate: true,
986
- dataStart: answers.dataStart,
987
- testToMainSafeguards: answers.testToMainSafeguards,
988
- },
989
- };
990
- }
991
- function formatGeneratorLanguage(value) {
992
- return value === 'javascript' ? 'JavaScript' : value === 'typescript' ? 'TypeScript' : '# TodoForContext(optional): TypeScript / JavaScript';
993
- }
994
- function formatGeneratorPackageManager(value) {
995
- return value ?? '# TodoForContext(optional): pnpm / npm / yarn / bun';
996
- }
997
- function formatGeneratorRouting(answers) {
998
- if (answers.generatorNavigationLibrary === 'react-navigation') {
999
- const layout = answers.generatorReactNavigationLayout === 'tabs'
1000
- ? 'Tabs'
1001
- : answers.generatorReactNavigationLayout === 'drawer'
1002
- ? 'Drawer + Tabs'
1003
- : 'Stack';
1004
- return `React Navigation (${layout})`;
911
+ function formatGeneratorAuth(value) {
912
+ if (value === 'supabase') {
913
+ return 'Supabase';
1005
914
  }
1006
- if (answers.generatorNavigationLibrary === 'expo-router') {
1007
- return `Expo Router (${formatAppDirectory(answers.appDirectory)})`;
915
+ if (value === 'firebase') {
916
+ return 'Firebase';
1008
917
  }
1009
- return `# TodoForContext(optional): Expo Router / React Navigation (${formatAppDirectory(answers.appDirectory)})`;
918
+ return 'None';
1010
919
  }
1011
920
  function formatGeneratorStateManagement(value) {
1012
921
  if (value === 'zustand') {
@@ -1017,13 +926,6 @@ function formatGeneratorStateManagement(value) {
1017
926
  }
1018
927
  return '# TodoForContext(optional): Zustand / Jotai / React context / none';
1019
928
  }
1020
- function toKebabCase(value) {
1021
- return value
1022
- .trim()
1023
- .toLowerCase()
1024
- .replace(/[^a-z0-9]+/gu, '-')
1025
- .replace(/^-+|-+$/gu, '') || 'expo-app';
1026
- }
1027
929
  function hasThinOnboardingAnswers(answers) {
1028
930
  const genericValues = new Set([
1029
931
  'Expo app users',