pi-studio 0.9.57 → 0.9.58

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/client/studio.css CHANGED
@@ -362,6 +362,55 @@
362
362
  user-select: none;
363
363
  }
364
364
 
365
+ body[data-studio-layout="editor-top"] main,
366
+ body[data-studio-layout="response-top"] main {
367
+ grid-template-columns: minmax(0, 1fr);
368
+ gap: 0;
369
+ }
370
+
371
+ body[data-studio-layout="editor-top"] main {
372
+ grid-template-rows: minmax(140px, var(--studio-left-pane-fr, 1fr)) 10px minmax(140px, var(--studio-right-pane-fr, 1fr));
373
+ }
374
+
375
+ body[data-studio-layout="response-top"] main {
376
+ grid-template-rows: minmax(140px, var(--studio-right-pane-fr, 1fr)) 10px minmax(140px, var(--studio-left-pane-fr, 1fr));
377
+ }
378
+
379
+ body[data-studio-layout="editor-top"] .pane-resize-handle,
380
+ body[data-studio-layout="response-top"] .pane-resize-handle {
381
+ display: block;
382
+ align-self: stretch;
383
+ min-width: 0;
384
+ min-height: 10px;
385
+ cursor: row-resize;
386
+ }
387
+
388
+ body[data-studio-layout="editor-top"] .pane-resize-handle::before,
389
+ body[data-studio-layout="response-top"] .pane-resize-handle::before {
390
+ top: 50%;
391
+ right: 8px;
392
+ bottom: auto;
393
+ left: 8px;
394
+ width: auto;
395
+ height: 2px;
396
+ transform: translateY(-50%);
397
+ }
398
+
399
+ body[data-studio-layout="editor-top"] .pane-resize-handle:hover::before,
400
+ body[data-studio-layout="editor-top"] .pane-resize-handle:focus-visible::before,
401
+ body[data-studio-layout="editor-top"].pane-resizing .pane-resize-handle::before,
402
+ body[data-studio-layout="response-top"] .pane-resize-handle:hover::before,
403
+ body[data-studio-layout="response-top"] .pane-resize-handle:focus-visible::before,
404
+ body[data-studio-layout="response-top"].pane-resizing .pane-resize-handle::before {
405
+ width: auto;
406
+ height: 3px;
407
+ }
408
+
409
+ body[data-studio-layout="editor-top"].pane-resizing,
410
+ body[data-studio-layout="response-top"].pane-resizing {
411
+ cursor: row-resize;
412
+ }
413
+
365
414
  section {
366
415
  border: 1px solid var(--panel-border);
367
416
  border-radius: 10px;
@@ -387,6 +436,13 @@
387
436
  gap: 12px;
388
437
  }
389
438
 
439
+ body[data-studio-layout="editor-top"].pane-focus-left main,
440
+ body[data-studio-layout="editor-top"].pane-focus-right main,
441
+ body[data-studio-layout="response-top"].pane-focus-left main,
442
+ body[data-studio-layout="response-top"].pane-focus-right main {
443
+ grid-template-rows: minmax(0, 1fr);
444
+ }
445
+
390
446
  body.pane-focus-left #rightPane,
391
447
  body.pane-focus-right #leftPane,
392
448
  body.pane-focus-left #paneResizeHandle,
@@ -4579,6 +4635,107 @@
4579
4635
  background: var(--error-soft);
4580
4636
  }
4581
4637
 
4638
+ .repl-quick-composer {
4639
+ display: flex;
4640
+ flex-direction: column;
4641
+ gap: 8px;
4642
+ padding: 10px;
4643
+ border: 1px solid var(--panel-border);
4644
+ border-radius: 8px;
4645
+ background: color-mix(in srgb, var(--panel-2) 58%, var(--panel));
4646
+ }
4647
+
4648
+ .repl-quick-header,
4649
+ .repl-quick-actions {
4650
+ display: flex;
4651
+ align-items: center;
4652
+ justify-content: space-between;
4653
+ gap: 10px;
4654
+ }
4655
+
4656
+ .repl-quick-header > div,
4657
+ .repl-quick-actions > div {
4658
+ display: flex;
4659
+ align-items: center;
4660
+ gap: 8px;
4661
+ min-width: 0;
4662
+ }
4663
+
4664
+ .repl-quick-target {
4665
+ display: inline-flex;
4666
+ align-items: center;
4667
+ gap: 4px;
4668
+ max-width: min(48vw, 460px);
4669
+ min-height: 0;
4670
+ margin-left: 5px;
4671
+ padding: 2px 4px;
4672
+ overflow: hidden;
4673
+ border-color: transparent;
4674
+ border-radius: 5px;
4675
+ background: transparent;
4676
+ color: var(--muted);
4677
+ font-family: var(--font-mono);
4678
+ font-size: 11px;
4679
+ line-height: 1.25;
4680
+ vertical-align: bottom;
4681
+ white-space: nowrap;
4682
+ }
4683
+
4684
+ .repl-quick-target:not(:disabled):hover,
4685
+ .repl-quick-target:focus-visible {
4686
+ border-color: transparent;
4687
+ background: var(--studio-header-action-hover-bg, var(--panel-2));
4688
+ color: var(--text);
4689
+ }
4690
+
4691
+ .repl-quick-target-label {
4692
+ min-width: 0;
4693
+ overflow: hidden;
4694
+ text-overflow: ellipsis;
4695
+ }
4696
+
4697
+ .repl-quick-target-arrow {
4698
+ flex: 0 0 auto;
4699
+ color: var(--studio-info-text, var(--muted));
4700
+ font-family: var(--font-ui);
4701
+ font-size: 10px;
4702
+ font-weight: 700;
4703
+ }
4704
+
4705
+ .repl-quick-hint,
4706
+ .repl-quick-actions > span {
4707
+ color: var(--muted);
4708
+ font-size: 11px;
4709
+ }
4710
+
4711
+ .repl-quick-composer textarea {
4712
+ box-sizing: border-box;
4713
+ min-height: 72px;
4714
+ max-height: 260px;
4715
+ margin: 0;
4716
+ resize: vertical;
4717
+ }
4718
+
4719
+ .repl-quick-composer textarea:focus-visible {
4720
+ border-color: color-mix(in srgb, var(--accent) 65%, var(--control-border));
4721
+ outline: 2px solid color-mix(in srgb, var(--accent) 28%, transparent);
4722
+ outline-offset: 1px;
4723
+ }
4724
+
4725
+ .repl-quick-actions {
4726
+ align-items: flex-end;
4727
+ }
4728
+
4729
+ .repl-quick-actions > span {
4730
+ line-height: 1.35;
4731
+ }
4732
+
4733
+ .repl-quick-send-btn {
4734
+ border-color: color-mix(in srgb, var(--accent) 58%, var(--control-border));
4735
+ background: color-mix(in srgb, var(--accent) 14%, var(--panel));
4736
+ color: var(--text);
4737
+ }
4738
+
4582
4739
  .repl-journal,
4583
4740
  .repl-mirror {
4584
4741
  border: 1px solid var(--panel-border);
@@ -5726,6 +5883,20 @@
5726
5883
  .pane-resize-handle {
5727
5884
  display: none;
5728
5885
  }
5886
+
5887
+ .repl-quick-header,
5888
+ .repl-quick-actions {
5889
+ align-items: stretch;
5890
+ flex-direction: column;
5891
+ }
5892
+
5893
+ .repl-quick-target {
5894
+ max-width: 66vw;
5895
+ }
5896
+
5897
+ .repl-quick-actions > div {
5898
+ align-self: flex-end;
5899
+ }
5729
5900
  }
5730
5901
 
5731
5902
  /* Default Studio layout. The legacy classic layout remains available only via ?uiRefresh=0. */
package/index.ts CHANGED
@@ -11530,10 +11530,11 @@ function stripStudioReplSubmissionEcho(output: string): string {
11530
11530
  let value = String(output || "").replace(/^\s+/, "");
11531
11531
  // The raw tmux mirror should stay raw, but Studio/tool result output should not
11532
11532
  // expose the temp-file wrapper used to submit multiline snippets safely. The
11533
- // The root fragment catches both legacy long Studio paths and compact private
11534
- // control paths when IPython wraps them across continuation prompt lines.
11533
+ // root fragment catches both legacy long Studio paths and compact private
11534
+ // control paths. Match the Python wrapper by its final double close rather
11535
+ // than the word `globals`, which IPython may split across continuation lines.
11535
11536
  const submissionEchoPatterns = [
11536
- /^.*exec\(open\([\s\S]*?(?:pi-studio-re|pi-rc-)[\s\S]*?globals\(\)\)\s*$/gm,
11537
+ /^.*exec\(open\([\s\S]*?(?:pi-studio-re|pi-rc-)[\s\S]*?\)\)\s*$/gm,
11537
11538
  /^.*include\([\s\S]*?(?:pi-studio-re|pi-rc-)[\s\S]*?\.jl"\)\s*$/gm,
11538
11539
  /^.*source\([\s\S]*?(?:pi-studio-re|pi-rc-)[\s\S]*?local\s*=\s*\.GlobalEnv\)\s*$/gm,
11539
11540
  /^.*:script\s+[\s\S]*?(?:pi-studio-re|pi-rc-)[\s\S]*?\.ghci"?\s*$/gm,
@@ -12508,6 +12509,15 @@ ${cssVarsBlock}
12508
12509
  <option value="off">Line numbers: Off</option>
12509
12510
  <option value="on" selected>Line numbers: On</option>
12510
12511
  </select>
12512
+ <select id="studioPaneLayoutSelect" class="studio-flat-select" aria-label="Studio pane layout" title="Choose whether the two main panes sit side by side or in a vertical stack.">
12513
+ <option value="side-by-side">Layout: Side by side</option>
12514
+ <option value="editor-top">Layout: Editor above</option>
12515
+ <option value="response-top">Layout: Response above</option>
12516
+ </select>
12517
+ <select id="activityTrackingSelect" class="studio-flat-select" aria-label="Follow main Pi activity" title="Optionally follow main Pi activity from Working to the response view; off by default.">
12518
+ <option value="off">Follow activity: Off</option>
12519
+ <option value="on">Follow activity: On</option>
12520
+ </select>
12511
12521
  <select id="editorFontSizeSelect" class="studio-flat-select" aria-label="Editor text size" title="Adjust raw editor text size.">
12512
12522
  <option value="10">Editor text: 10px</option>
12513
12523
  <option value="11">Editor text: 11px</option>
@@ -12607,7 +12617,7 @@ ${cssVarsBlock}
12607
12617
  <div id="rightSectionHeader" class="section-header">
12608
12618
  <div class="section-header-main">
12609
12619
  <span id="rightViewSelectWrap" class="studio-header-select-wrap">
12610
- <select id="rightViewSelect" aria-label="Response view mode" title="Right pane view mode. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+1–8 switches directly between all right-pane views. Cmd/Ctrl+Alt+P/E/W/F/Q keep mnemonic shortcuts for Preview, Editor Preview, Working, Files, and Side questions.">
12620
+ <select id="rightViewSelect" aria-label="Response view mode" title="Right pane view mode. F7 cycles when the right pane is active; Cmd/Ctrl+Alt+1–8 switches directly between all right-pane views. Cmd/Ctrl+Alt+P/E/W/F/R/Q keep mnemonic shortcuts for Preview, Editor Preview, Working, Files, REPL, and Side questions.">
12611
12621
  <option value="markdown">Response (Raw)</option>
12612
12622
  <option value="preview" selected>Response (Preview)</option>
12613
12623
  <option value="editor-preview">Editor (Preview)</option>
@@ -12725,6 +12735,7 @@ ${cssVarsBlock}
12725
12735
  <div><dt>Cmd/Ctrl+Alt+E</dt><dd>Switch the right pane directly to Editor Preview</dd></div>
12726
12736
  <div><dt>Cmd/Ctrl+Alt+W</dt><dd>Switch the right pane directly to Working</dd></div>
12727
12737
  <div><dt>Cmd/Ctrl+Alt+F</dt><dd>Switch the right pane directly to Files</dd></div>
12738
+ <div><dt>Cmd/Ctrl+Alt+R</dt><dd>Switch the right pane directly to REPL and focus Quick send when a session is selected</dd></div>
12728
12739
  <div><dt>Cmd/Ctrl+Alt+Q</dt><dd>Switch the right pane directly to Side questions</dd></div>
12729
12740
  <div><dt>F8</dt><dd>Focus editor text</dd></div>
12730
12741
  <div><dt>Shift+F8</dt><dd>Focus right-pane content</dd></div>
@@ -12740,7 +12751,7 @@ ${cssVarsBlock}
12740
12751
  <div><dt>Alt/Option+=</dt><dd>Increase the active pane's text size when not editing text</dd></div>
12741
12752
  <div><dt>Alt/Option+-</dt><dd>Decrease the active pane's text size when not editing text</dd></div>
12742
12753
  <div><dt>Alt/Option+0</dt><dd>Reset the active pane's text size when not editing text</dd></div>
12743
- <div><dt>Cmd/Ctrl+Alt+R</dt><dd>Refresh the focused or visible PDF preview from disk</dd></div>
12754
+ <div><dt>Cmd/Ctrl+Alt+Shift+R</dt><dd>Refresh the focused or visible PDF preview from disk</dd></div>
12744
12755
  </dl>
12745
12756
  </section>
12746
12757
  <section class="shortcuts-group">
@@ -12772,6 +12783,7 @@ ${cssVarsBlock}
12772
12783
  <section class="shortcuts-group">
12773
12784
  <h3>REPL</h3>
12774
12785
  <dl>
12786
+ <div><dt>Cmd/Ctrl+Enter</dt><dd>Send exact Quick send text while its REPL composer is focused; Enter adds a new line</dd></div>
12775
12787
  <div><dt>Cmd/Ctrl+Shift+Enter</dt><dd>Send selection, chunks, or editor text to the active REPL when the right pane is REPL</dd></div>
12776
12788
  </dl>
12777
12789
  </section>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-studio",
3
- "version": "0.9.57",
3
+ "version": "0.9.58",
4
4
  "description": "Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, active quiz, prompt/response history, live previews, and tmux-backed REPL/literate REPL workflows",
5
5
  "type": "module",
6
6
  "license": "MIT",