create-flowmo 1.2.2 → 1.2.4

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/index.js CHANGED
@@ -139,22 +139,10 @@ export default defineConfig({
139
139
  `;
140
140
  await fs.writeFile(path.join(projectPath, 'vite.config.js'), viteConfig);
141
141
 
142
- // Create a root index.html entry point
142
+ // Copy root index.html and inject project name
143
143
  const safeName = projectName.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
144
- const indexHtml = `<!DOCTYPE html>
145
- <html lang="en">
146
- <head>
147
- <meta charset="UTF-8" />
148
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
149
- <title>${safeName}</title>
150
- </head>
151
- <body>
152
- <h1>${safeName}</h1>
153
- <p>Open any screen from the <code>screens/</code> folder:</p>
154
- <ul id="screen-list"></ul>
155
- </body>
156
- </html>
157
- `;
144
+ let indexHtml = await fs.readFile(path.join(templateDir, 'index.html'), 'utf-8');
145
+ indexHtml = indexHtml.replaceAll('{{PROJECT_NAME}}', safeName);
158
146
  await fs.writeFile(path.join(projectPath, 'index.html'), indexHtml);
159
147
 
160
148
  s.stop('Project scaffolded successfully!');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-flowmo",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "Scaffold an OutSystems-Lite project with screens, data, logic, and built-in agent skills",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@ Build pixel-perfect OutSystems-compatible `.visual.html` prototypes using only t
20
20
  ## General Rules
21
21
 
22
22
  1. **Utility-first styling** — use OSUI utility classes (`.padding-m`, `.text-bold`, `.background-primary`). Never use raw CSS properties or inline `style=""` attributes.
23
- 2. **12-column grid** — use `.columns2` through `.columns6` for responsive layouts. These auto-stack on mobiledo not add custom media queries.
23
+ 2. **12-column grid** — use `.columns.columns2` through `.columns.columns6` for responsive layouts. The parent div MUST have BOTH the `.columns` base class AND the number class (e.g. `class="columns columns3 gutter-base"`). Children MUST use `.columns-item` NOT `.column`. Without `.columns`, `display: flex` is missing and items stack vertically.
24
24
  3. **No external JavaScript** — all interaction patterns are CSS/class-driven.
25
25
  4. **Layout is CRITICAL** — every screen MUST use one of the three OutSystems layouts. Pick the right one and use the exact HTML structure from the layout template files. The `.active-screen` wrapper is REQUIRED or utility classes will not resolve. See the **Layouts** section below.
26
26
  5. **Scroll model** — OSUI sets `html { overflow: hidden }`. The `.active-screen` div is the actual scroll container. The `grid.css` file provides `.active-screen { overflow-y: auto; height: 100vh; }` — make sure `grid.css` is linked.
@@ -559,6 +559,7 @@ Follow this checklist when creating or editing a screen. Do not skip steps.
559
559
 
560
560
  ## Gotchas
561
561
 
562
+ - **Columns require TWO classes on the parent + `.columns-item` children** — The parent MUST have both `.columns` AND the number class: `class="columns columns3 gutter-base"`. The `.columns` class provides `display: flex` — without it, items stack vertically. Children MUST be `class="columns-item"` — NOT `class="column"` (that class does not exist in OSUI). Wrong: `<div class="columns3"><div class="column">`. Right: `<div class="columns columns3 gutter-base"><div class="columns-item">`.
562
563
  - `.active-screen` is **REQUIRED** as the outermost wrapper. Without it, utility classes and CSS variables will NOT resolve. It also serves as the **scroll container** \u2014 OSUI sets `html { overflow: hidden }` so `.active-screen` must have `overflow-y: auto; height: 100vh` (provided by `grid.css`).\n- **`.ThemeGrid_MarginGutter` needs `grid.css`** \u2014 this class is used for menu link spacing and form field gutters, but its `margin-left` value is NOT in `outsystems-ui.css`. It comes from `grid.css`. Without it, menu links will bunch together with no spacing.
563
564
  - **Button + color utilities don't mix** — `.btn` overrides `color` and `background-color` at high specificity. Stacking `.btn .background-neutral-0 .text-primary` will produce invisible text (white on white). Create custom button classes in `theme.css` instead.
564
565
  - **Header menu links vanish on dark headers** — OSUI link color defaults to `var(--color-primary)`. On a dark header where `--color-primary` is also dark (e.g. navy), menu links become invisible. Fix: add a custom class in `theme.css` that forces light link color in the header (e.g. `.header__link { color: #fff; }`).
@@ -82,10 +82,10 @@
82
82
  <!-- Feature Cards Section -->
83
83
  <div data-block="Layouts.LayoutBaseSection" class="full-width-section padding-y-xxl background-neutral-0">
84
84
  <div class="ThemeGrid_Container">
85
- <div class="columns3">
86
- <div class="column">{{feature-1}}</div>
87
- <div class="column">{{feature-2}}</div>
88
- <div class="column">{{feature-3}}</div>
85
+ <div class="columns columns3 gutter-base phone-break-all">
86
+ <div class="columns-item">{{feature-1}}</div>
87
+ <div class="columns-item">{{feature-2}}</div>
88
+ <div class="columns-item">{{feature-3}}</div>
89
89
  </div>
90
90
  </div>
91
91
  </div>
@@ -22,8 +22,8 @@ KPI cards on top, chart area in the middle, recent activity list at the bottom.
22
22
  <!-- Goes inside .content-middle -->
23
23
  <div class="main-content padding-base">
24
24
  <!-- KPI Row -->
25
- <div class="columns4 margin-bottom-l">
26
- <div class="column">
25
+ <div class="columns columns4 gutter-base tablet-break-middle phone-break-all margin-bottom-l">
26
+ <div class="columns-item">
27
27
  <div class="card padding-base">
28
28
  <div class="counter">
29
29
  <div class="counter-value font-size-display text-primary">{{kpi-1-value}}</div>
@@ -31,7 +31,7 @@ KPI cards on top, chart area in the middle, recent activity list at the bottom.
31
31
  </div>
32
32
  </div>
33
33
  </div>
34
- <div class="column">
34
+ <div class="columns-item">
35
35
  <div class="card padding-base">
36
36
  <div class="counter">
37
37
  <div class="counter-value font-size-display text-success">{{kpi-2-value}}</div>
@@ -39,7 +39,7 @@ KPI cards on top, chart area in the middle, recent activity list at the bottom.
39
39
  </div>
40
40
  </div>
41
41
  </div>
42
- <div class="column">
42
+ <div class="columns-item">
43
43
  <div class="card padding-base">
44
44
  <div class="counter">
45
45
  <div class="counter-value font-size-display text-warning">{{kpi-3-value}}</div>
@@ -47,7 +47,7 @@ KPI cards on top, chart area in the middle, recent activity list at the bottom.
47
47
  </div>
48
48
  </div>
49
49
  </div>
50
- <div class="column">
50
+ <div class="columns-item">
51
51
  <div class="card padding-base">
52
52
  <div class="counter">
53
53
  <div class="counter-value font-size-display text-error">{{kpi-4-value}}</div>
@@ -58,8 +58,8 @@ KPI cards on top, chart area in the middle, recent activity list at the bottom.
58
58
  </div>
59
59
 
60
60
  <!-- Chart Area -->
61
- <div class="columns2 margin-bottom-l">
62
- <div class="column">
61
+ <div class="columns columns2 gutter-base phone-break-all margin-bottom-l">
62
+ <div class="columns-item">
63
63
  <div class="card">
64
64
  <div class="card-header padding-base">
65
65
  <h5 class="margin-bottom-none">{{chart-1-title}}</h5>
@@ -67,7 +67,7 @@ KPI cards on top, chart area in the middle, recent activity list at the bottom.
67
67
  <div class="card-content padding-base">{{chart-1-placeholder}}</div>
68
68
  </div>
69
69
  </div>
70
- <div class="column">
70
+ <div class="columns-item">
71
71
  <div class="card">
72
72
  <div class="card-header padding-base">
73
73
  <h5 class="margin-bottom-none">{{chart-2-title}}</h5>
@@ -101,11 +101,11 @@ Searchable table with pagination. The standard CRUD list view.
101
101
  ```html
102
102
  <div class="layout active-screen">
103
103
  <header class="header">
104
- <div class="columns2">
105
- <div class="column">
104
+ <div class="columns columns2 gutter-base phone-break-all">
105
+ <div class="columns-item">
106
106
  <h1 class="font-size-h2 margin-bottom-none">{{entity-name-plural}}</h1>
107
107
  </div>
108
- <div class="column" style="text-align: right;">
108
+ <div class="columns-item" style="text-align: right;">
109
109
  <button class="btn btn-primary">Create New</button>
110
110
  </div>
111
111
  </div>
@@ -175,11 +175,11 @@ Read-only view of a single record with sections.
175
175
  <span class="breadcrumb-separator">/</span>
176
176
  <span class="breadcrumb-item active">{{record-name}}</span>
177
177
  </div>
178
- <div class="columns2">
179
- <div class="column">
178
+ <div class="columns columns2 gutter-base phone-break-all">
179
+ <div class="columns-item">
180
180
  <h1 class="font-size-h2 margin-bottom-none">{{record-name}}</h1>
181
181
  </div>
182
- <div class="column" style="text-align: right;">
182
+ <div class="columns-item" style="text-align: right;">
183
183
  <button class="btn">Edit</button>
184
184
  <button class="btn btn-error">Delete</button>
185
185
  </div>
@@ -193,8 +193,8 @@ Read-only view of a single record with sections.
193
193
  <h5 class="section-title">General Information</h5>
194
194
  </div>
195
195
  <div class="section-content">
196
- <div class="columns2">
197
- <div class="column">
196
+ <div class="columns columns2 gutter-base phone-break-all">
197
+ <div class="columns-item">
198
198
  <div class="margin-bottom-base">
199
199
  <div class="font-size-s text-neutral-6">{{field-1-label}}</div>
200
200
  <div>{{field-1-value}}</div>
@@ -204,7 +204,7 @@ Read-only view of a single record with sections.
204
204
  <div>{{field-2-value}}</div>
205
205
  </div>
206
206
  </div>
207
- <div class="column">
207
+ <div class="columns-item">
208
208
  <div class="margin-bottom-base">
209
209
  <div class="font-size-s text-neutral-6">{{field-3-label}}</div>
210
210
  <div>{{field-3-value}}</div>
@@ -262,8 +262,8 @@ Create/edit form for a single record.
262
262
  <main class="main-content padding-base">
263
263
  <div class="card padding-l">
264
264
  <form class="form">
265
- <div class="columns2">
266
- <div class="column">
265
+ <div class="columns columns2 gutter-base phone-break-all">
266
+ <div class="columns-item">
267
267
  <div class="form-group">
268
268
  <label class="form-label">{{field-1-label}}</label>
269
269
  <input type="text" class="form-control" placeholder="{{field-1-placeholder}}" />
@@ -273,7 +273,7 @@ Create/edit form for a single record.
273
273
  <input type="text" class="form-control" placeholder="{{field-2-placeholder}}" />
274
274
  </div>
275
275
  </div>
276
- <div class="column">
276
+ <div class="columns-item">
277
277
  <div class="form-group">
278
278
  <label class="form-label">{{field-3-label}}</label>
279
279
  <div class="dropdown">
@@ -0,0 +1,172 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>{{PROJECT_NAME}}</title>
7
+ <link rel="stylesheet" href="theme/outsystems-ui.css" />
8
+ <link rel="stylesheet" href="theme/grid.css" />
9
+ <link rel="stylesheet" href="theme/theme.css" />
10
+ <style>
11
+ :root {
12
+ --w-fg: #171717;
13
+ --w-muted: #687076;
14
+ --w-bg: #ffffff;
15
+ --w-border: #e8e8e8;
16
+ --w-code-bg: #f2f2f2;
17
+ }
18
+
19
+ @media (prefers-color-scheme: dark) {
20
+ :root {
21
+ --w-fg: #ededed;
22
+ --w-muted: #8f8f8f;
23
+ --w-bg: #0a0a0a;
24
+ --w-border: #2e2e2e;
25
+ --w-code-bg: #1a1a1a;
26
+ }
27
+ .layout { background: var(--w-bg); }
28
+ .header { background: var(--w-bg) !important; border-bottom-color: var(--w-border) !important; }
29
+ .content { background: var(--w-bg); }
30
+ .heading6, span { color: var(--w-fg); }
31
+ }
32
+
33
+ .welcome-page {
34
+ display: flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ justify-content: center;
38
+ min-height: calc(100vh - 120px);
39
+ padding: 2rem;
40
+ }
41
+
42
+ .welcome-top {
43
+ display: flex;
44
+ justify-content: space-between;
45
+ align-items: center;
46
+ width: 100%;
47
+ max-width: 1024px;
48
+ margin-bottom: 4rem;
49
+ font-size: 0.875rem;
50
+ color: var(--w-muted);
51
+ }
52
+
53
+ .welcome-top code {
54
+ font-family: 'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace;
55
+ font-size: 0.8125rem;
56
+ background: var(--w-code-bg);
57
+ border: 1px solid var(--w-border);
58
+ padding: 0.25rem 0.625rem;
59
+ border-radius: 6px;
60
+ color: var(--w-fg);
61
+ }
62
+
63
+ .welcome-top .by {
64
+ display: flex;
65
+ align-items: center;
66
+ gap: 0.375rem;
67
+ color: var(--w-muted);
68
+ font-size: 0.8125rem;
69
+ }
70
+
71
+ .welcome-top .by a {
72
+ color: var(--w-fg);
73
+ text-decoration: none;
74
+ font-weight: 600;
75
+ }
76
+
77
+ .welcome-logo {
78
+ font-size: 4.5rem;
79
+ font-weight: 700;
80
+ letter-spacing: -0.05em;
81
+ color: var(--w-fg);
82
+ text-align: center;
83
+ margin-bottom: 4rem;
84
+ }
85
+
86
+ .welcome-logo span { font-weight: 300; font-size: 2rem; vertical-align: super; color: var(--w-muted); }
87
+
88
+ .welcome-links {
89
+ display: grid;
90
+ grid-template-columns: repeat(4, 1fr);
91
+ width: 100%;
92
+ max-width: 1024px;
93
+ border-top: 1px solid var(--w-border);
94
+ }
95
+
96
+ .welcome-link {
97
+ padding: 1.5rem 1.25rem;
98
+ text-decoration: none;
99
+ color: var(--w-fg);
100
+ border-left: 1px solid var(--w-border);
101
+ transition: background 0.15s;
102
+ }
103
+
104
+ .welcome-link:first-child { border-left: none; }
105
+
106
+ .welcome-link:hover { background: var(--w-code-bg); }
107
+
108
+ .welcome-link h2 {
109
+ font-size: 1rem;
110
+ font-weight: 600;
111
+ margin-bottom: 0.5rem;
112
+ }
113
+
114
+ .welcome-link:hover h2::after { margin-left: 4px; }
115
+
116
+ .welcome-link p {
117
+ font-size: 0.8125rem;
118
+ color: var(--w-muted);
119
+ line-height: 1.55;
120
+ }
121
+
122
+ @media (max-width: 640px) {
123
+ .welcome-links { grid-template-columns: 1fr; }
124
+ .welcome-link { border-left: none; border-bottom: 1px solid var(--w-border); }
125
+ .welcome-top { flex-direction: column; gap: 1rem; text-align: center; }
126
+ .welcome-logo { font-size: 3rem; }
127
+ }
128
+ </style>
129
+ </head>
130
+ <body>
131
+ <div class="active-screen">
132
+ <div data-block="Layouts.LayoutTopMenu" class="layout layout-top fixed-header">
133
+ <div class="main">
134
+
135
+
136
+ <!-- Content -->
137
+ <div class="content">
138
+ <div class="main-content" role="main">
139
+
140
+ <div class="welcome-page">
141
+
142
+ <div class="welcome-logo">flowmo</div>
143
+
144
+ <div class="welcome-links">
145
+ <a class="welcome-link" href="screens/home.visual.html">
146
+ <h2>Home</h2>
147
+ <p>Open the starter screen to see OutSystems UI patterns in action.</p>
148
+ </a>
149
+ <div class="welcome-link">
150
+ <h2>Screens</h2>
151
+ <p>Create .visual.html files in the screens/ folder.</p>
152
+ </div>
153
+ <div class="welcome-link">
154
+ <h2>Logic</h2>
155
+ <p>Define actions as .flowchart.md files in logic/.</p>
156
+ </div>
157
+ <div class="welcome-link">
158
+ <h2>Data</h2>
159
+ <p>Model entities as Markdown tables. Write SQL in data/sql/.</p>
160
+ </div>
161
+ </div>
162
+ </div>
163
+
164
+ </div>
165
+ </div>
166
+
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <script src="scripts/device-detect.js"></script>
171
+ </body>
172
+ </html>
@@ -7,6 +7,83 @@
7
7
  <link rel="stylesheet" href="../theme/outsystems-ui.css">
8
8
  <link rel="stylesheet" href="../theme/grid.css">
9
9
  <link rel="stylesheet" href="../theme/theme.css">
10
+ <style>
11
+ :root {
12
+ --w-fg: #171717;
13
+ --w-muted: #687076;
14
+ --w-bg: #ffffff;
15
+ --w-border: #e8e8e8;
16
+ }
17
+
18
+ @media (prefers-color-scheme: dark) {
19
+ :root {
20
+ --w-fg: #ededed;
21
+ --w-muted: #8f8f8f;
22
+ --w-bg: #0a0a0a;
23
+ --w-border: #2e2e2e;
24
+ }
25
+ .layout { background: var(--w-bg); }
26
+ .header { background: var(--w-bg) !important; border-bottom-color: var(--w-border) !important; }
27
+ .content { background: var(--w-bg); }
28
+ .footer { background: var(--w-bg) !important; }
29
+ .heading1, .heading6, .paragraph, span, a { color: var(--w-fg); }
30
+ .text-neutral-6 { color: var(--w-muted) !important; }
31
+ }
32
+
33
+ .home-hero {
34
+ text-align: center;
35
+ padding: 4rem 1rem;
36
+ }
37
+
38
+ .home-hero .heading1 {
39
+ font-size: 2rem;
40
+ letter-spacing: -0.03em;
41
+ margin-bottom: 0.75rem;
42
+ color: var(--w-fg);
43
+ }
44
+
45
+ .home-hero .paragraph {
46
+ color: var(--w-muted);
47
+ font-size: 1rem;
48
+ max-width: 480px;
49
+ margin: 0 auto 2rem;
50
+ line-height: 1.6;
51
+ }
52
+
53
+ .home-steps {
54
+ max-width: 480px;
55
+ margin: 0 auto;
56
+ text-align: left;
57
+ }
58
+
59
+ .home-step {
60
+ padding: 0.875rem 0;
61
+ border-bottom: 1px solid var(--w-border);
62
+ display: flex;
63
+ gap: 0.75rem;
64
+ align-items: baseline;
65
+ }
66
+
67
+ .home-step:last-child { border-bottom: none; }
68
+
69
+ .home-step-num {
70
+ font-size: 0.75rem;
71
+ font-weight: 600;
72
+ color: var(--w-muted);
73
+ flex-shrink: 0;
74
+ }
75
+
76
+ .home-step p {
77
+ font-size: 0.875rem;
78
+ color: var(--w-fg);
79
+ line-height: 1.5;
80
+ }
81
+
82
+ .home-step code {
83
+ font-size: 0.8125rem;
84
+ color: var(--w-muted);
85
+ }
86
+ </style>
10
87
  </head>
11
88
  <body>
12
89
  <div class="active-screen">
@@ -49,18 +126,33 @@
49
126
  <!-- Content -->
50
127
  <div class="content">
51
128
  <div class="main-content ThemeGrid_Container" role="main">
52
- <div class="content-top display-flex align-items-center">
53
- <div class="content-top-title heading1">Welcome</div>
54
- </div>
55
- <div class="content-middle">
56
- <p class="paragraph">Start building your screen here. Open this file in the Visual Inspector to see the layer structure.</p>
129
+
130
+ <div class="home-hero">
131
+ <div class="heading1">Welcome to your app</div>
132
+ <p class="paragraph">This is a starter screen. Edit it, duplicate it, or replace it entirely.</p>
133
+
134
+ <div class="home-steps">
135
+ <div class="home-step">
136
+ <span class="home-step-num">01</span>
137
+ <p>Create screens as <code>.visual.html</code> files in <code>screens/</code>.</p>
138
+ </div>
139
+ <div class="home-step">
140
+ <span class="home-step-num">02</span>
141
+ <p>Define actions as <code>.flowchart.md</code> files in <code>logic/</code>.</p>
142
+ </div>
143
+ <div class="home-step">
144
+ <span class="home-step-num">03</span>
145
+ <p>Document your database in <code>data/</code> and write advanced queries in <code>data/sql/</code>.</p>
146
+ </div>
147
+ </div>
57
148
  </div>
149
+
58
150
  </div>
59
151
 
60
152
  <!-- Footer -->
61
153
  <footer role="contentinfo" class="content-bottom">
62
154
  <div class="footer ThemeGrid_Container">
63
- <p class="paragraph text-neutral-6">Built with Flowmo</p>
155
+ <p class="paragraph text-neutral-6">Powered by Flowmo</p>
64
156
  </div>
65
157
  </footer>
66
158
  </div>