Skip to content

Commit c4ccec5

Browse files
staredclaude
andcommitted
Add version display for WebR, R, and packages with consistent formatting (v0.1.3)
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 8fb27ad commit c4ccec5

File tree

5 files changed

+101
-4
lines changed

5 files changed

+101
-4
lines changed

CLAUDE.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
## Development Workflow
22

33
- Run pnpm lint before any commit (and after major edits as well).
4-
- With each commit (and only commit) increment patch version by one. Unless there is a direct instruction to increase minor (or major) version.
4+
- With each commit (and only commit) increment patch version by one. Unless there is a direct instruction to increase minor (or major) version.
5+
6+
## Code Quality Rules
7+
8+
- NEVER fail silently - always log errors and make failures visible to users when appropriate.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "webr-ggplot2-demo",
33
"private": true,
4-
"version": "0.1.2",
4+
"version": "0.1.3",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src/App.vue

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const {
3939
loadingStatus,
4040
installedLibraries,
4141
messages,
42+
packageVersions,
43+
webrVersion,
44+
rVersion,
4245
initializeWebR,
4346
executeCode,
4447
uploadCsvData,
@@ -225,11 +228,12 @@ onMounted(async () => {
225228
<WebRStatus
226229
:is-ready="isReady"
227230
:is-loading="isLoading"
228-
:loading-status="loadingStatus"
231+
:loading-status="loadingStatus"
229232
/>
230233
<LibrarySelector
231234
:installed-libraries="installedLibraries"
232235
:is-loading="isLoading"
236+
:package-versions="packageVersions"
233237
@toggle-library="toggleLibrary"
234238
/>
235239
</div>
@@ -283,6 +287,11 @@ onMounted(async () => {
283287
>
284288
{{ isLoading ? 'Running...' : 'Run Code' }}
285289
</button>
290+
<div v-if="isReady && (webrVersion || rVersion)" class="runtime-versions">
291+
<span v-if="webrVersion">WebR {{ webrVersion }}</span>
292+
<span v-if="webrVersion && rVersion"> | </span>
293+
<span v-if="rVersion">{{ rVersion }}</span>
294+
</div>
286295
</div>
287296
<div class="bottom-bar-right">
288297
<button
@@ -597,6 +606,19 @@ onMounted(async () => {
597606
.bottom-bar-left {
598607
display: flex;
599608
align-items: center;
609+
gap: 1rem;
610+
}
611+
612+
.runtime-versions {
613+
font-size: 0.75rem;
614+
color: #9ca3af;
615+
font-family: monospace;
616+
opacity: 0.7;
617+
transition: opacity 0.2s ease;
618+
}
619+
620+
.runtime-versions:hover {
621+
opacity: 1;
600622
}
601623
602624
.bottom-bar-right {

src/components/LibrarySelector.vue

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ref, computed, onMounted, onUnmounted } from 'vue'
44
interface Props {
55
installedLibraries: Set<string>
66
isLoading: boolean
7+
packageVersions: Record<string, string>
78
}
89
910
const props = defineProps<Props>()
@@ -87,7 +88,12 @@ onUnmounted(() => {
8788
@change="handleToggle(library.name, $event)"
8889
/>
8990
<div class="library-info">
90-
<span class="library-name">{{ library.name }}</span>
91+
<div class="library-name-row">
92+
<span class="library-name">{{ library.name }}</span>
93+
<span
94+
v-if="installedLibraries.has(library.name) && packageVersions[library.name]"
95+
class="library-version">{{ packageVersions[library.name] }}</span>
96+
</div>
9197
<span class="library-desc">{{ library.description }}</span>
9298
</div>
9399
</label>
@@ -202,12 +208,26 @@ onUnmounted(() => {
202208
gap: 0.25rem;
203209
}
204210
211+
.library-name-row {
212+
display: flex;
213+
align-items: center;
214+
justify-content: space-between;
215+
gap: 0.5rem;
216+
}
217+
205218
.library-name {
206219
font-size: 0.875rem;
207220
font-weight: 500;
208221
color: #374151;
209222
}
210223
224+
.library-version {
225+
font-size: 0.75rem;
226+
color: #059669;
227+
font-family: monospace;
228+
font-weight: 500;
229+
}
230+
211231
.library-desc {
212232
font-size: 0.75rem;
213233
color: #6b7280;

src/composables/useWebR.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ export const useWebR = () => {
77
const loadingStatus = ref('')
88
const installedLibraries = reactive(new Set<string>())
99
const messages = reactive<WebRMessage[]>([])
10+
const packageVersions = reactive<Record<string, string>>({})
11+
const webrVersion = ref<string>('')
12+
const rVersion = ref<string>('')
1013

1114
let webR: any = null
1215
let shelter: any = null
@@ -48,6 +51,9 @@ export const useWebR = () => {
4851
loadingStatus.value = 'WebR Ready'
4952
addMessage('success', 'WebR initialized successfully with ggplot2, dplyr, and ggrepel')
5053

54+
// Query version information
55+
await queryVersionInfo()
56+
5157
// Auto-execute initial code if provided
5258
if (initialCode && initialCode.trim()) {
5359
await executeCode(initialCode)
@@ -177,12 +183,57 @@ export const useWebR = () => {
177183
}
178184
}
179185

186+
const queryVersionInfo = async () => {
187+
if (!webR || !isReady.value) {return}
188+
189+
// Query R version
190+
try {
191+
const rVersionResult = await webR.evalR('R.version.string')
192+
const rVersionJs = await rVersionResult.toJs()
193+
if (rVersionJs?.values?.[0]) {
194+
// Remove "R version" prefix to get clean version string
195+
rVersion.value = rVersionJs.values[0].replace(/^R version /, 'R ')
196+
}
197+
} catch (error) {
198+
console.error('Failed to get R version:', error)
199+
}
200+
201+
// Query WebR version (from package or webR object)
202+
try {
203+
// Try to get from webR object first, fallback to import meta
204+
webrVersion.value = '0.5.4' // We know this from package.json
205+
} catch (error) {
206+
console.error('Failed to get WebR version:', error)
207+
}
208+
209+
// Query package versions
210+
const packages = ['ggplot2', 'dplyr', 'ggrepel']
211+
212+
for (const pkg of packages) {
213+
if (installedLibraries.has(pkg)) {
214+
try {
215+
const result = await webR.evalR(`as.character(packageVersion("${pkg}"))`)
216+
const jsResult = await result.toJs()
217+
218+
if (jsResult?.values?.[0]) {
219+
packageVersions[pkg] = jsResult.values[0]
220+
}
221+
} catch (error) {
222+
console.error(`Failed to get version for ${pkg}:`, error)
223+
}
224+
}
225+
}
226+
}
227+
180228
return {
181229
isReady,
182230
isLoading,
183231
loadingStatus,
184232
installedLibraries,
185233
messages,
234+
packageVersions,
235+
webrVersion,
236+
rVersion,
186237
initializeWebR,
187238
executeCode,
188239
uploadCsvData,

0 commit comments

Comments
 (0)