@beastmode-develeap/beastmode 0.1.296 → 0.1.298
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/web/board.html +204 -13
- package/dist/web/build-commit.txt +1 -1
- package/dist/web/build-stamp.txt +1 -1
- package/package.json +1 -1
package/dist/web/board.html
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
}
|
|
16
16
|
</script>
|
|
17
17
|
<!--BOARD_DATA-->
|
|
18
|
-
<script>window.__BUILD_STAMP__ = "20260517-
|
|
18
|
+
<script>window.__BUILD_STAMP__ = "20260517-110542-fd318ea";</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">
|
|
@@ -8589,6 +8589,122 @@ function EnvironmentPanel({ projectName }) {
|
|
|
8589
8589
|
`;
|
|
8590
8590
|
}
|
|
8591
8591
|
|
|
8592
|
+
// ================================================================
|
|
8593
|
+
// Codebase Guide Panel — surfaced per project on the Projects page
|
|
8594
|
+
// ================================================================
|
|
8595
|
+
|
|
8596
|
+
function CodebaseGuidePanel({ projectName }) {
|
|
8597
|
+
const [status, setStatus] = useState('idle');
|
|
8598
|
+
const [guideContent, setGuideContent] = useState(null);
|
|
8599
|
+
const [expanded, setExpanded] = useState(false);
|
|
8600
|
+
const [error, setError] = useState(null);
|
|
8601
|
+
|
|
8602
|
+
const fetchStatus = useCallback(async () => {
|
|
8603
|
+
try {
|
|
8604
|
+
const data = await api('GET', '/api/projects/' + projectName + '/analyze/status');
|
|
8605
|
+
const next = (data && data.status) ? data.status : 'idle';
|
|
8606
|
+
setStatus(next);
|
|
8607
|
+
return next;
|
|
8608
|
+
} catch (e) {
|
|
8609
|
+
setStatus('idle');
|
|
8610
|
+
return 'idle';
|
|
8611
|
+
}
|
|
8612
|
+
}, [projectName]);
|
|
8613
|
+
|
|
8614
|
+
const fetchGuide = useCallback(async () => {
|
|
8615
|
+
try {
|
|
8616
|
+
const data = await api('GET', '/api/projects/' + projectName + '/codebase-guide?level=l1');
|
|
8617
|
+
let content = (data && (data.content || data.guide || data.l1)) || '';
|
|
8618
|
+
if (typeof data === 'string') content = data;
|
|
8619
|
+
if (content && content.startsWith('# ')) {
|
|
8620
|
+
const nl = content.indexOf('\n');
|
|
8621
|
+
content = nl >= 0 ? content.slice(nl + 1).replace(/^\s*\n/, '') : '';
|
|
8622
|
+
}
|
|
8623
|
+
setGuideContent(content || '');
|
|
8624
|
+
} catch (e) {
|
|
8625
|
+
if (e && /404/.test(String(e.message || ''))) {
|
|
8626
|
+
setGuideContent('Guide not available');
|
|
8627
|
+
} else {
|
|
8628
|
+
setGuideContent(null);
|
|
8629
|
+
}
|
|
8630
|
+
}
|
|
8631
|
+
}, [projectName]);
|
|
8632
|
+
|
|
8633
|
+
useEffect(() => { fetchStatus(); }, [fetchStatus]);
|
|
8634
|
+
|
|
8635
|
+
useEffect(() => {
|
|
8636
|
+
if (status === 'complete' || status === 'cached') {
|
|
8637
|
+
fetchGuide();
|
|
8638
|
+
}
|
|
8639
|
+
}, [status, fetchGuide]);
|
|
8640
|
+
|
|
8641
|
+
useEffect(() => {
|
|
8642
|
+
if (status !== 'running') return undefined;
|
|
8643
|
+
const id = setInterval(() => { fetchStatus(); }, 3000);
|
|
8644
|
+
return () => clearInterval(id);
|
|
8645
|
+
}, [status, fetchStatus]);
|
|
8646
|
+
|
|
8647
|
+
const reanalyze = async () => {
|
|
8648
|
+
try {
|
|
8649
|
+
setError(null);
|
|
8650
|
+
setGuideContent(null);
|
|
8651
|
+
setExpanded(false);
|
|
8652
|
+
await api('POST', '/api/projects/' + projectName + '/analyze?force=true', {});
|
|
8653
|
+
setStatus('running');
|
|
8654
|
+
} catch (e) {
|
|
8655
|
+
setError(e.message);
|
|
8656
|
+
}
|
|
8657
|
+
};
|
|
8658
|
+
|
|
8659
|
+
const pillLabel =
|
|
8660
|
+
status === 'complete' ? '✓ Analyzed'
|
|
8661
|
+
: status === 'cached' ? '✓ Analyzed'
|
|
8662
|
+
: status === 'running' ? '⏳ Analyzing…'
|
|
8663
|
+
: status === 'failed' ? '✗ Failed'
|
|
8664
|
+
: '—';
|
|
8665
|
+
const pillBg =
|
|
8666
|
+
(status === 'complete' || status === 'cached') ? 'var(--success)'
|
|
8667
|
+
: status === 'running' ? 'var(--warning)'
|
|
8668
|
+
: status === 'failed' ? 'var(--danger)'
|
|
8669
|
+
: 'var(--muted)';
|
|
8670
|
+
const pillStyle = 'display:inline-block;padding:2px 8px;border-radius:10px;background:' + pillBg + ';color:white;font-size:11px;font-weight:600;';
|
|
8671
|
+
|
|
8672
|
+
const canShowContent = (status === 'complete' || status === 'cached');
|
|
8673
|
+
const canReanalyze = (status === 'complete' || status === 'cached' || status === 'failed');
|
|
8674
|
+
|
|
8675
|
+
return html`
|
|
8676
|
+
<div class="ext-item"
|
|
8677
|
+
data-testid=${'codebase-guide-panel-' + projectName}
|
|
8678
|
+
style="flex-basis:100%;flex-direction:column;align-items:stretch;gap:8px;">
|
|
8679
|
+
<div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
|
|
8680
|
+
<div style="display:flex;align-items:center;gap:8px;">
|
|
8681
|
+
<span style="font-size:12px;color:var(--text-secondary);">Codebase Guide</span>
|
|
8682
|
+
<span data-testid=${'guide-status-pill-' + projectName} style=${pillStyle}>${pillLabel}</span>
|
|
8683
|
+
</div>
|
|
8684
|
+
<div style="display:flex;gap:6px;">
|
|
8685
|
+
${canShowContent ? html`
|
|
8686
|
+
<button class="btn btn-sm btn-secondary"
|
|
8687
|
+
onClick=${() => setExpanded(e => !e)}>
|
|
8688
|
+
${expanded ? 'Collapse' : 'Expand'}
|
|
8689
|
+
</button>
|
|
8690
|
+
` : null}
|
|
8691
|
+
${canReanalyze ? html`
|
|
8692
|
+
<button class="btn btn-sm btn-secondary" onClick=${reanalyze}>Re-analyze</button>
|
|
8693
|
+
` : null}
|
|
8694
|
+
</div>
|
|
8695
|
+
</div>
|
|
8696
|
+
${error ? html`<div class="error-msg" style="margin:0;">${error}</div>` : null}
|
|
8697
|
+
${(canShowContent && expanded) ? html`
|
|
8698
|
+
<div data-testid=${'guide-content-' + projectName}
|
|
8699
|
+
class="guide-content"
|
|
8700
|
+
style="max-height:300px;overflow-y:auto;font-size:0.85rem;white-space:pre-wrap;background:var(--bg-secondary);padding:8px;border-radius:var(--radius-sm);border:1px solid var(--border);">
|
|
8701
|
+
${guideContent === null ? 'Loading…' : guideContent}
|
|
8702
|
+
</div>
|
|
8703
|
+
` : null}
|
|
8704
|
+
</div>
|
|
8705
|
+
`;
|
|
8706
|
+
}
|
|
8707
|
+
|
|
8592
8708
|
// ================================================================
|
|
8593
8709
|
// Projects Page
|
|
8594
8710
|
// ================================================================
|
|
@@ -8605,6 +8721,9 @@ function ProjectsPage({ selectedProject, onProjectChange }) {
|
|
|
8605
8721
|
const [onboardingTier, setOnboardingTier] = useState('standard');
|
|
8606
8722
|
const [showPicker, setShowPicker] = useState(false);
|
|
8607
8723
|
const [adding, setAdding] = useState(false);
|
|
8724
|
+
const [analysisStage, setAnalysisStage] = useState(null);
|
|
8725
|
+
const [fullTierGuide, setFullTierGuide] = useState(null);
|
|
8726
|
+
const [fullTierProject, setFullTierProject] = useState(null);
|
|
8608
8727
|
|
|
8609
8728
|
const fetchProjects = useCallback(() => {
|
|
8610
8729
|
api('GET', '/api/projects')
|
|
@@ -8634,21 +8753,69 @@ function ProjectsPage({ selectedProject, onProjectChange }) {
|
|
|
8634
8753
|
setSuccess(isGithub ? `Cloned and added: ${registeredPath}` : 'Project added successfully');
|
|
8635
8754
|
|
|
8636
8755
|
if (onboardingTier === 'standard' || onboardingTier === 'full') {
|
|
8637
|
-
|
|
8756
|
+
const tier = onboardingTier;
|
|
8757
|
+
setAnalysisStage('clone');
|
|
8758
|
+
setSuccess('Cloning repository...');
|
|
8638
8759
|
try {
|
|
8639
8760
|
await api('POST', '/api/projects/' + projName + '/analyze', {});
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8761
|
+
} catch {
|
|
8762
|
+
setAnalysisStage(null);
|
|
8763
|
+
setSuccess('Project added (analysis failed — can retry later)');
|
|
8764
|
+
setTimeout(() => setSuccess(null), 5000);
|
|
8765
|
+
fetchProjects();
|
|
8766
|
+
return;
|
|
8767
|
+
}
|
|
8768
|
+
const startedAt = Date.now();
|
|
8769
|
+
const poll = setInterval(async () => {
|
|
8770
|
+
let st = 'running';
|
|
8771
|
+
try {
|
|
8772
|
+
const data = await api('GET', '/api/projects/' + projName + '/analyze/status');
|
|
8773
|
+
st = (data && data.status) ? data.status : 'running';
|
|
8774
|
+
} catch {
|
|
8775
|
+
return;
|
|
8776
|
+
}
|
|
8777
|
+
if (st === 'running') {
|
|
8778
|
+
const elapsed = (Date.now() - startedAt) / 1000;
|
|
8779
|
+
const stage = elapsed < 3 ? 'clone' : (elapsed < 6 ? 'detect' : 'analyze');
|
|
8780
|
+
setAnalysisStage(stage);
|
|
8781
|
+
setSuccess(
|
|
8782
|
+
stage === 'clone' ? 'Cloning repository...'
|
|
8783
|
+
: stage === 'detect' ? 'Detecting stack...'
|
|
8784
|
+
: 'Analyzing codebase...'
|
|
8785
|
+
);
|
|
8786
|
+
} else if (st === 'complete' || st === 'cached') {
|
|
8787
|
+
clearInterval(poll);
|
|
8788
|
+
setAnalysisStage('ready');
|
|
8789
|
+
setSuccess('✓ Analysis complete — codebase guide ready');
|
|
8790
|
+
fetchProjects();
|
|
8791
|
+
if (tier === 'full') {
|
|
8792
|
+
try {
|
|
8793
|
+
const data = await api('GET', '/api/projects/' + projName + '/codebase-guide?level=l1');
|
|
8794
|
+
let content = (data && (data.content || data.guide || data.l1)) || '';
|
|
8795
|
+
if (typeof data === 'string') content = data;
|
|
8796
|
+
if (content && content.startsWith('# ')) {
|
|
8797
|
+
const nl = content.indexOf('\n');
|
|
8798
|
+
content = nl >= 0 ? content.slice(nl + 1).replace(/^\s*\n/, '') : '';
|
|
8799
|
+
}
|
|
8800
|
+
setFullTierGuide(content || '');
|
|
8801
|
+
setFullTierProject(projName);
|
|
8802
|
+
} catch {
|
|
8803
|
+
setFullTierGuide('Guide not available');
|
|
8804
|
+
setFullTierProject(projName);
|
|
8805
|
+
}
|
|
8806
|
+
}
|
|
8807
|
+
setTimeout(() => setSuccess(null), 3000);
|
|
8808
|
+
} else if (st === 'failed') {
|
|
8809
|
+
clearInterval(poll);
|
|
8810
|
+
setAnalysisStage(null);
|
|
8811
|
+
setSuccess('Analysis failed — can retry from project settings');
|
|
8812
|
+
setTimeout(() => setSuccess(null), 5000);
|
|
8813
|
+
}
|
|
8814
|
+
}, 2000);
|
|
8815
|
+
} else {
|
|
8816
|
+
setTimeout(() => setSuccess(null), 5000);
|
|
8649
8817
|
}
|
|
8650
8818
|
|
|
8651
|
-
setTimeout(() => setSuccess(null), 5000);
|
|
8652
8819
|
fetchProjects();
|
|
8653
8820
|
} catch (e) { setError(e.message); }
|
|
8654
8821
|
finally { setAdding(false); }
|
|
@@ -8673,7 +8840,30 @@ function ProjectsPage({ selectedProject, onProjectChange }) {
|
|
|
8673
8840
|
</div>
|
|
8674
8841
|
|
|
8675
8842
|
${error ? html`<div class="error-msg">${error}</div>` : null}
|
|
8676
|
-
${success ? html
|
|
8843
|
+
${success ? html`
|
|
8844
|
+
<div class="success-msg" data-testid="analysis-toast">
|
|
8845
|
+
<span data-testid="analysis-stage">${success}</span>
|
|
8846
|
+
</div>
|
|
8847
|
+
` : null}
|
|
8848
|
+
${fullTierGuide !== null ? html`
|
|
8849
|
+
<div class="card" data-testid="full-tier-guide-panel"
|
|
8850
|
+
style="margin-bottom:16px;border-left:3px solid var(--success);">
|
|
8851
|
+
<div class="card-header">
|
|
8852
|
+
<h3>📋 Codebase Guide: ${fullTierProject}</h3>
|
|
8853
|
+
</div>
|
|
8854
|
+
<div style="max-height:200px;overflow-y:auto;white-space:pre-wrap;font-size:0.85rem;background:var(--bg-secondary);padding:8px;border-radius:var(--radius-sm);border:1px solid var(--border);margin-bottom:12px;">
|
|
8855
|
+
${fullTierGuide || 'Guide not available'}
|
|
8856
|
+
</div>
|
|
8857
|
+
<button class="btn btn-primary"
|
|
8858
|
+
data-testid="full-tier-start-session"
|
|
8859
|
+
onClick=${() => {
|
|
8860
|
+
if (onProjectChange) onProjectChange(fullTierProject);
|
|
8861
|
+
navigate('#/new-session');
|
|
8862
|
+
}}>
|
|
8863
|
+
Start Session →
|
|
8864
|
+
</button>
|
|
8865
|
+
</div>
|
|
8866
|
+
` : null}
|
|
8677
8867
|
|
|
8678
8868
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:24px;">
|
|
8679
8869
|
<div class="card" style="margin-bottom:0;">
|
|
@@ -8754,6 +8944,7 @@ function ProjectsPage({ selectedProject, onProjectChange }) {
|
|
|
8754
8944
|
<button class="btn btn-sm btn-danger" onClick=${() => removeProject(proj.name)}>Remove</button>
|
|
8755
8945
|
</div>
|
|
8756
8946
|
<${EnvironmentPanel} projectName=${proj.name} />
|
|
8947
|
+
<${CodebaseGuidePanel} projectName=${proj.name} />
|
|
8757
8948
|
</div>
|
|
8758
8949
|
`)}
|
|
8759
8950
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
fd318eaec11e30ebe601cbd90b2b8c3f7cb3b7cd
|
package/dist/web/build-stamp.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
20260517-
|
|
1
|
+
20260517-110542-fd318ea
|