@beastmode-develeap/beastmode 0.1.367 → 0.1.369

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.
@@ -15,7 +15,7 @@
15
15
  }
16
16
  </script>
17
17
  <!--BOARD_DATA-->
18
- <script>window.__BUILD_STAMP__ = "20260605-070459-d9280de";</script>
18
+ <script>window.__BUILD_STAMP__ = "20260605-090928-0ba16dd";</script>
19
19
  <link rel="preconnect" href="https://fonts.googleapis.com">
20
20
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
21
21
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
@@ -4281,7 +4281,7 @@ function Sidebar({ currentHash, factoryName, theme, onToggleTheme, selectedProje
4281
4281
  api('GET', '/api/projects')
4282
4282
  .then(data => setProjects(data.projects || []))
4283
4283
  .catch(() => {});
4284
- }, []);
4284
+ }, [selectedProject]);
4285
4285
 
4286
4286
  const links = [
4287
4287
  { path: '#/dashboard', icon: 'dashboard', label: 'Dashboard' },
@@ -8989,8 +8989,8 @@ function ProjectsPage({ selectedProject, onProjectChange }) {
8989
8989
  <div class="card" style="margin-bottom:0;">
8990
8990
  <div class="card-header"><h3>Start from Scratch</h3></div>
8991
8991
  <p style="font-size:13px;color:var(--text-secondary);margin-bottom:12px;">
8992
- Build a new product from an idea. BeastMode guides you through brainstorming,
8993
- PRD, architecture, and creates the project for you.
8992
+ Start a new product from an idea. BeastMode creates a new project for it
8993
+ and guides you through brainstorming, PRD, and architecture.
8994
8994
  </p>
8995
8995
  <button class="btn btn-primary" onclick=${() => navigate('#/new-product')}>
8996
8996
  <${Icon} name="plus" size=${14} />
@@ -10618,7 +10618,7 @@ function PhaseProgress({ phases, currentPhase }) {
10618
10618
  `;
10619
10619
  }
10620
10620
 
10621
- function InceptionSetup({ methodologies, onStart, onCancel }) {
10621
+ function InceptionSetup({ methodologies, onStart, onCancel, error }) {
10622
10622
  const [productName, setProductName] = useState('');
10623
10623
  const [idea, setIdea] = useState('');
10624
10624
  const [methodology, setMethodology] = useState('bmad');
@@ -10656,6 +10656,7 @@ function InceptionSetup({ methodologies, onStart, onCancel }) {
10656
10656
  <option value="fully_autonomous">Fully autonomous — generate everything, I approve (2-5 min)</option>
10657
10657
  </select>
10658
10658
  </div>
10659
+ ${error ? html`<div class="error-msg">${error}</div>` : ''}
10659
10660
  <div style="display:flex;gap:8px;justify-content:flex-end;margin-top:16px;">
10660
10661
  <button class="btn" onClick=${onCancel}>Cancel</button>
10661
10662
  <button class="btn btn-primary" disabled=${!productName.trim() || !idea.trim()}
@@ -11160,10 +11161,21 @@ function ToolResultCard({ content, extra }) {
11160
11161
  // Strategy Start Screen — 1-liner prompt or Product inception form
11161
11162
  // ================================================================
11162
11163
 
11163
- function StrategyStartPage({ selectedProject, sessionType }) {
11164
+ // Derive a board/namespace slug from a product name: lowercase, collapse
11165
+ // runs of non-[a-z0-9] to a single hyphen, strip leading/trailing hyphens.
11166
+ function slugifyProduct(name) {
11167
+ return String(name || '')
11168
+ .trim()
11169
+ .toLowerCase()
11170
+ .replace(/[^a-z0-9]+/g, '-')
11171
+ .replace(/^-+|-+$/g, '');
11172
+ }
11173
+
11174
+ function StrategyStartPage({ selectedProject, sessionType, onProjectChange }) {
11164
11175
  const [topic, setTopic] = useState('');
11165
11176
  const [approach, setApproach] = useState('auto');
11166
11177
  const [methodologies, setMethodologies] = useState([]);
11178
+ const [productError, setProductError] = useState('');
11167
11179
 
11168
11180
  useEffect(() => {
11169
11181
  api('GET', '/api/methodologies').then(data => setMethodologies(data.methodologies || [])).catch(() => {});
@@ -11173,17 +11185,40 @@ function StrategyStartPage({ selectedProject, sessionType }) {
11173
11185
  if (sessionType === 'product') {
11174
11186
  return html`<${InceptionSetup}
11175
11187
  methodologies=${methodologies}
11176
- onStart=${(config) => {
11177
- api('POST', '/api/strategy/' + selectedProject + '/sessions', {
11178
- name: config.productName,
11179
- idea: config.idea,
11180
- methodology: config.methodology,
11181
- interactionMode: config.interactionMode,
11182
- sessionType: 'product',
11183
- approach: config.methodology,
11184
- }).then(session => {
11188
+ error=${productError}
11189
+ onStart=${async (config) => {
11190
+ setProductError('');
11191
+ const slug = slugifyProduct(config.productName);
11192
+ if (!slug) {
11193
+ setProductError('Enter a valid product name (letters or numbers).');
11194
+ return;
11195
+ }
11196
+ try {
11197
+ const projData = await api('GET', '/api/projects');
11198
+ const existing = (projData && projData.projects) || [];
11199
+ if (existing.some(p => p.name === slug)) {
11200
+ setProductError("A project named '" + slug + "' already exists — choose a different product name.");
11201
+ return;
11202
+ }
11203
+ await api('POST', '/api/products', {
11204
+ productName: slug,
11205
+ idea: config.idea,
11206
+ methodology: config.methodology,
11207
+ interactionMode: config.interactionMode,
11208
+ });
11209
+ const session = await api('POST', '/api/strategy/' + slug + '/sessions', {
11210
+ name: config.productName,
11211
+ idea: config.idea,
11212
+ methodology: config.methodology,
11213
+ interactionMode: config.interactionMode,
11214
+ sessionType: 'product',
11215
+ approach: config.methodology,
11216
+ });
11217
+ if (onProjectChange) onProjectChange(slug);
11185
11218
  navigate('#/strategy-session/' + session.sessionId);
11186
- });
11219
+ } catch (e) {
11220
+ setProductError('Failed to start product inception: ' + (e && e.message ? e.message : e));
11221
+ }
11187
11222
  }}
11188
11223
  onCancel=${() => navigate('#/strategy')}
11189
11224
  />`;
@@ -12409,7 +12444,7 @@ function App() {
12409
12444
  default:
12410
12445
  if (route.startsWith('#/strategy-start/')) {
12411
12446
  const sessionType = route.replace('#/strategy-start/', '');
12412
- page = html`<${StrategyStartPage} selectedProject=${selectedProject} sessionType=${sessionType} />`;
12447
+ page = html`<${StrategyStartPage} selectedProject=${selectedProject} sessionType=${sessionType} onProjectChange=${setSelectedProject} />`;
12413
12448
  } else if (route.startsWith('#/strategy-session/')) {
12414
12449
  const sessionId = route.replace('#/strategy-session/', '');
12415
12450
  page = html`<${ChatPage} selectedProject=${selectedProject} resumeSession=${sessionId} />`;
@@ -1 +1 @@
1
- d9280de452f96fc4673e8a051b52b44432bebd15
1
+ 0ba16dd83cb39405da62c80462d21a312cd1bdb6
@@ -1 +1 @@
1
- 20260605-070459-d9280de
1
+ 20260605-090928-0ba16dd
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beastmode-develeap/beastmode",
3
- "version": "0.1.367",
3
+ "version": "0.1.369",
4
4
  "description": "BeastMode Dark Factory — turn intent into verified software",
5
5
  "type": "module",
6
6
  "bin": {