beatrina 0.9.43 → 1.0.0
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/app/Beatrina.app/Contents/Info.plist +86 -0
- package/app/Beatrina.app/Contents/MacOS/beatrina +0 -0
- package/app/Beatrina.app/Contents/Resources/icon.icns +0 -0
- package/app/beatrina.png +0 -0
- package/app/linux-arm64/beatrina +0 -0
- package/app/win-x64/Beatrina-setup.exe +0 -0
- package/beatrina_V1.0.0.html +1906 -0
- package/beatrina_V1.0.0.html.inputs.json +1 -0
- package/bin/beatrina.mjs +200 -12
- package/bin/cli.mjs +8 -3
- package/bin/finder.mjs +1 -1
- package/bin/shortcut.mjs +15 -15
- package/build-info.json +1 -1
- package/host/engine-node-job.mjs +35 -0
- package/host/engine-pool.mjs +153 -26
- package/host/engine-r.mjs +8 -1
- package/host/jobs/document-child.mjs +271 -0
- package/host/journal-store.mjs +19 -3
- package/host/latex-compile.mjs +673 -0
- package/host/main.mjs +58 -18
- package/host/planes/analyze.mjs +18 -2
- package/host/planes/choose.mjs +13 -2
- package/host/planes/expect-term.mjs +102 -0
- package/host/planes/jobs.mjs +38 -5
- package/host/planes/sessions.mjs +5 -1
- package/host/planes/terminal.mjs +23 -9
- package/host/pwa/icon-192.png +0 -0
- package/host/pwa/icon-512.png +0 -0
- package/host/quarto.mjs +118 -0
- package/host/server.mjs +83 -2
- package/host/worker-plane.mjs +7 -1
- package/kernel/check/acceptance.mjs +43 -12
- package/kernel/check/knit-file.mjs +300 -52
- package/kernel/check/session.mjs +19 -4
- package/kernel/kernel-version +1 -1
- package/kernel/knitr-run.R +8 -1
- package/kernel/mcp/beatrina-mcp.mjs +6 -5
- package/kernel/worker.R +21 -1
- package/lib/engine-labels.js +7 -1
- package/menu/Beatrina Menu.app/Contents/Info.plist +2 -2
- package/menu/Beatrina Menu.app/Contents/MacOS/Beatrina Menu +0 -0
- package/package.json +4 -3
- package/beatrina_V0.9.43.html +0 -1885
- package/beatrina_V0.9.43.html.inputs.json +0 -1
package/kernel/knitr-run.R
CHANGED
|
@@ -71,7 +71,14 @@ run_document_cell <- function(id, source, document, dims = NULL, srcname = NULL)
|
|
|
71
71
|
if (identical(frame$type, "stdout") && !is.null(options$comment) && nzchar(options$comment)) {
|
|
72
72
|
frame$text <- paste0(options$comment, " ", strsplit(frame$text, "\n", fixed = TRUE)[[1L]], collapse = "\n")
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
# A figure FILE is written only when the author asked for one by
|
|
75
|
+
# setting fig.path (a chunk option or the setup chunk's opts_chunk).
|
|
76
|
+
# knitr's own default, "figure/", is not a request: every plot of an
|
|
77
|
+
# ordinary run used to land as figure/<label>-1.png in the working
|
|
78
|
+
# directory, a folder nobody made (FINDINGS 2026-09-22 B17). The
|
|
79
|
+
# plot itself travels in the frame either way; nothing reads the file.
|
|
80
|
+
wants_file <- !identical(options$fig.path, KNIT_BASE$fig.path)
|
|
81
|
+
if (identical(frame$type, "plot") && save_figures && wants_file) {
|
|
75
82
|
plot_n <<- plot_n + 1L
|
|
76
83
|
suffix <- if (identical(frame$mime, "image/svg+xml")) ".svg" else ".png"
|
|
77
84
|
target <- paste0(options$fig.path, options$label, "-", plot_n, suffix)
|
|
@@ -437,11 +437,12 @@ const TOOLS = [
|
|
|
437
437
|
description:
|
|
438
438
|
"Run one chunk in the user's live session (its own engine: R, or Python where the session runs it) and return its output "
|
|
439
439
|
+ "(stdout, messages, errors, table/plot summaries). The run is visible "
|
|
440
|
-
+ "in the notebook exactly as if the user pressed Run.
|
|
441
|
-
+ "
|
|
442
|
-
+ "
|
|
443
|
-
+ "
|
|
444
|
-
+ "
|
|
440
|
+
+ "in the notebook exactly as if the user pressed Run. If the document is in "
|
|
441
|
+
+ "Writing mode the run first switches it to Develop — visibly, exactly as "
|
|
442
|
+
+ "pressing the Develop segment — and the reply says so (`modeChanged: "
|
|
443
|
+
+ "\"writing→development\"`); only when the page refuses that switch is the "
|
|
444
|
+
+ "run refused, and the error says to ask the user. Reading (notebook_read, "
|
|
445
|
+
+ "chunk_read) and authoring (chunk_insert, chunk_update) never change the mode. "
|
|
445
446
|
+ "A chunk with cache=TRUE and an unchanged source is RESTORED from knitr's "
|
|
446
447
|
+ "cache, not executed — the reply says so (`cached: true`) and none of the "
|
|
447
448
|
+ "chunk's side effects (setwd(), files written, seeds) happen; pass `force` "
|
package/kernel/worker.R
CHANGED
|
@@ -166,6 +166,13 @@ MAX_VIEW_COLS <- 100L
|
|
|
166
166
|
MAX_VIEW_BYTES <- 512L * 1024L
|
|
167
167
|
MAX_VIEW_CELL_CHARS <- 512L
|
|
168
168
|
MAX_VIEW_LABEL_CHARS <- 128L
|
|
169
|
+
# The viewer's page size, the same number as lib/panel.js's PAGE (pinned by
|
|
170
|
+
# spike/test-ide.R). View() pushes its first page unasked, and it
|
|
171
|
+
# used to take the `view` op's protocol default of 200, so the grid opened on
|
|
172
|
+
# "1–200 of N" and every page it asked for itself — next, search, clear — was
|
|
173
|
+
# 50 (N11, app-monkey soak 2026-09-22). The protocol default stays 200 for
|
|
174
|
+
# clients that name no limit; the push names the viewer's.
|
|
175
|
+
VIEWER_PAGE_ROWS <- 50L
|
|
169
176
|
MAX_STRUCT_CHILDREN <- 200L
|
|
170
177
|
MAX_COMPLETIONS <- 200L
|
|
171
178
|
|
|
@@ -2680,6 +2687,14 @@ emit_dataframe <- function(id, df, source = NULL) {
|
|
|
2680
2687
|
# R whether names are automatic without materialising them; explicit names
|
|
2681
2688
|
# are sliced from the raw attribute only AFTER the 10-row preview is taken.
|
|
2682
2689
|
explicit_rownames <- .row_names_info(df, type = 1L) > 0L
|
|
2690
|
+
# head(df) and df[1:n, ] store their row names EXPLICITLY as the integers
|
|
2691
|
+
# 1..n — automatic in all but storage. Shown, they were a "rowname" column of
|
|
2692
|
+
# 1, 2, 3 and the header said 5 x 3 for a 5 x 2 frame (FINDINGS 2026-09-22
|
|
2693
|
+
# B10). Only integer names are tested, so a character vector is never built.
|
|
2694
|
+
if (explicit_rownames) {
|
|
2695
|
+
raw_names <- attr(df, "row.names", exact = TRUE)
|
|
2696
|
+
if (is.integer(raw_names) && identical(raw_names, seq_len(total_rows))) explicit_rownames <- FALSE
|
|
2697
|
+
}
|
|
2683
2698
|
total_cols <- data_cols + as.integer(explicit_rownames)
|
|
2684
2699
|
data_col_cap <- max(0L, preview_cols - as.integer(explicit_rownames))
|
|
2685
2700
|
shown_cols <- if (data_cols && data_col_cap) {
|
|
@@ -2768,6 +2783,11 @@ emit_dataframe <- function(id, df, source = NULL) {
|
|
|
2768
2783
|
columns = I(names(head_df)),
|
|
2769
2784
|
types = I(source_types),
|
|
2770
2785
|
nrow = total_rows, ncol = total_cols,
|
|
2786
|
+
# The frame's OWN width: row names are labels, not a variable, so the
|
|
2787
|
+
# "n x m" a reader sees is nrow x dataCols (mtcars is 32 x 11, not 12).
|
|
2788
|
+
# `ncol` keeps counting the displayed row-name column, which is what the
|
|
2789
|
+
# column pager and `truncated` measure against.
|
|
2790
|
+
dataCols = data_cols,
|
|
2771
2791
|
shown = nrow(head_df), shownCols = ncol(head_df),
|
|
2772
2792
|
truncated = total_rows > nrow(head_df) || total_cols > ncol(head_df),
|
|
2773
2793
|
# jsonlite drops a NULL, so a frame with no name is byte-identical to what
|
|
@@ -3721,7 +3741,7 @@ beatrina_tools$View <- function(x, title = NULL) {
|
|
|
3721
3741
|
# mtcars lives in the datasets package rather than the global environment.
|
|
3722
3742
|
label <- if (!is.null(title)) title else deparse(substitute(x))
|
|
3723
3743
|
assign(".beatrina_view", x, envir = globalenv())
|
|
3724
|
-
emit_view("view-request", ".beatrina_view", label = label)
|
|
3744
|
+
emit_view("view-request", ".beatrina_view", label = label, limit = VIEWER_PAGE_ROWS)
|
|
3725
3745
|
invisible(NULL)
|
|
3726
3746
|
}
|
|
3727
3747
|
attach(beatrina_tools, name = "beatrina:tools", warn.conflicts = FALSE)
|
package/lib/engine-labels.js
CHANGED
|
@@ -118,6 +118,8 @@ export function versionMenuLabel(engine) {
|
|
|
118
118
|
*/
|
|
119
119
|
export function kernelLanguage(info) {
|
|
120
120
|
const declared = info && typeof info.language === "string" ? info.language.trim() : "";
|
|
121
|
+
// A host running no default engine (host-ready) runs no language: "".
|
|
122
|
+
if (!declared && info && info.host_only) return "";
|
|
121
123
|
return declared ? engineKey(declared) : DEFAULT_ENGINE;
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -154,6 +156,8 @@ export function kernelVersion(info) {
|
|
|
154
156
|
* has always shown for a listener that named no version.
|
|
155
157
|
*/
|
|
156
158
|
export function kernelDisplay(info) {
|
|
159
|
+
// The HOST is attached and no engine is its own (plans/getting_rid_of_R.md K2).
|
|
160
|
+
if (!kernelLanguage(info) && info) return "Beatrina";
|
|
157
161
|
const label = engineLabel(kernelLanguage(info));
|
|
158
162
|
const version = kernelVersion(info);
|
|
159
163
|
return version ? `${label} ${version}` : `${label} session`;
|
|
@@ -216,6 +220,8 @@ export function reportedEngines(info) {
|
|
|
216
220
|
if (row && !rows.some((seen) => seen.name === row.name)) rows.push(row);
|
|
217
221
|
});
|
|
218
222
|
if (!rows.length) return [];
|
|
223
|
+
// A host with no language of its own adds none.
|
|
224
|
+
if (!language) return rows;
|
|
219
225
|
// The kernel's own language is always one of its engines — a session that
|
|
220
226
|
// would not run its own language is not a thing, and a list that omitted it
|
|
221
227
|
// would strand every chunk in the notebook.
|
|
@@ -239,7 +245,7 @@ export function reportedEngines(info) {
|
|
|
239
245
|
*/
|
|
240
246
|
export function declaredEngines(info) {
|
|
241
247
|
const language = kernelLanguage(info);
|
|
242
|
-
const out = [language];
|
|
248
|
+
const out = language ? [language] : [];
|
|
243
249
|
reportedEngines(info).forEach((row) => { if (!out.includes(row.name)) out.push(row.name); });
|
|
244
250
|
return out;
|
|
245
251
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<key>CFBundleExecutable</key><string>Beatrina Menu</string>
|
|
7
7
|
<key>CFBundleIdentifier</key><string>me.saqr.beatrina.menu</string>
|
|
8
8
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
9
|
-
<key>CFBundleShortVersionString</key><string>0.
|
|
10
|
-
<key>CFBundleVersion</key><string>0.
|
|
9
|
+
<key>CFBundleShortVersionString</key><string>1.0.0</string>
|
|
10
|
+
<key>CFBundleVersion</key><string>1.0.0</string>
|
|
11
11
|
<key>LSMinimumSystemVersion</key><string>13.0</string>
|
|
12
12
|
<!-- Menu bar only: no Dock tile, no window, nothing to close by accident. -->
|
|
13
13
|
<key>LSUIElement</key><true/>
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beatrina",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Beatrina is a modern, powerful, feature-rich integrated development environment (IDE) for R, Python, and JavaScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,9 +23,10 @@
|
|
|
23
23
|
"failsafe",
|
|
24
24
|
"lib",
|
|
25
25
|
"menu",
|
|
26
|
+
"app",
|
|
26
27
|
"build-info.json",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
28
|
+
"beatrina_V1.0.0.html",
|
|
29
|
+
"beatrina_V1.0.0.html.inputs.json",
|
|
29
30
|
"README.md",
|
|
30
31
|
"LICENSE",
|
|
31
32
|
"NOTICES"
|