v0.2.0: shadowing-proof package helpers, Pkg REPL console input, Create New Package command - #37
Merged
Merged
Conversation
The package-pane helper script was included directly into Main, so every unqualified Base name it used resolved through the user's namespace. A variable like `values = [3, 7, 2]` shadowed Base.values and made the background _positron_list_packages() hook fail repeatedly with a "Julia package command failed" toast. Define the whole script inside a `_PositronPackages` module so Base names always resolve to Base, qualify the generated stdout-capture wrapper and the include call with `Base.`, and add a regression test that shadows `values` in a scratch Main. Closes #32 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Typing `]` in the console did nothing: the input parses as invalid Julia, and IJulia maps a bare `]` to an empty Pkg command that produces no output, so users assumed Pkg mode was broken. - Treat single-line REPL special modes (`] add X`, `?foo`, `;ls`) as complete input in check_code_complete so the console executes them. - Print guidance for a bare `]` (a modal pkg> prompt cannot exist in a Jupyter-based console) pointing to the supported one-line form, which IJulia already executes via Pkg.REPLMode. - Extract the help-mode reply machinery into execute_positron_action and reuse it for the Pkg-mode guidance path. Closes #35 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Scaffolds a new package from the command palette: prompts for a name, parent folder, and template options (git repository, MIT license, GitHub Actions CI, Documenter docs; tests and README always included), then runs PkgTemplates in a Julia subprocess. PkgTemplates lives in a dedicated helper environment under the extension's global storage so user projects are never touched, and the command falls back to Pkg.generate when PkgTemplates cannot be installed (e.g. offline). A GitHub username is requested only when a selected option needs one, preferring `git config github.user`. Closes #31 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR prepares the extension for the v0.2.0 release by hardening the Julia package helper integration against user-global shadowing, improving console handling of Julia REPL “special modes” (Pkg/help/shell), and adding a new command to scaffold packages via PkgTemplates.
Changes:
- Wrap
scripts/packages/packages.jlhelpers in_PositronPackagesand update TypeScript to call helpers via the qualified module name; also Base-qualify generated wrapper calls to avoidMainshadowing. - Treat REPL special-mode one-liners (
],?,;) as “complete” input and provide guidance output for bare]in the Jupyter-based console. - Add
julia.createNewPackagecommand to scaffold a new package using a dedicated helper environment andscripts/packages/create_package.jl, with fallback toPkg.generate.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/runtime-manager.ts | Adds a “preferred installation” selector for auxiliary tooling. |
| src/packages.ts | Qualifies helper calls via _PositronPackages, Base-qualifies wrapper functions to avoid Main shadowing. |
| src/create-package.ts | Implements the “Create New Package” command flow and subprocess runner. |
| src/commands.ts | Registers the julia.createNewPackage command. |
| scripts/packages/packages.jl | Moves package helper definitions into _PositronPackages module to prevent shadowing. |
| scripts/packages/create_package.jl | Adds Julia-side scaffold script using PkgTemplates with Pkg.generate fallback. |
| julia/Positron/src/kernel.jl | Adds REPL magic-line completeness handling and execute routing for Pkg/help behavior. |
| julia/Positron/test/test_kernel.jl | Adds tests for REPL special modes and Pkg command extraction. |
| julia/Positron/test/test_package_helpers.jl | Adds regression test for “shadowed Main” package helper behavior. |
| README.md | Documents one-line Pkg commands support and the new create-package command. |
| package.json | Bumps version to 0.2.0 and contributes/activates the new command. |
| package-lock.json | Updates lockfile version metadata to 0.2.0. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
761
to
+763
| `finally\n` + | ||
| `close(__positron_io)\n` + | ||
| `flush(__positron_err)\n` + | ||
| `Base.close(__positron_io)\n` + | ||
| `Base.flush(__positron_err)\n` + |
Rework the #35 fix per review: a bare `]` now actually enters Pkg REPL mode, forked from julia-vscode's REPL integration (VSCodeServer binds the `]` key in a LineEdit keymap to transition the terminal REPL into Pkg.REPLMode). A Jupyter-based console never sees raw keystrokes, so the transition happens on submission instead: - Submitting `]` switches the console into Pkg REPL mode; Positron's prompt_state UI event changes the prompt to the environment-aware `(@v1.12) pkg>` / `(MyProject) pkg>`. - Every subsequent submission runs through Pkg.REPLMode (via IJulia's version-aware bridge) until `back`/`exit`/`quit` returns to julia>; the Backspace/Ctrl-C keystrokes that leave the mode in a terminal cannot reach the kernel, so typed commands replace them. - Silent executions and the extension's package-pane calls bypass the mode, and a fresh kernel resets the prompt when the UI comm opens so a restart never leaves a stale pkg> prompt behind. - One-shot `] add Foo` commands still work unchanged. Refs #35 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…xists The kernel startup script activates the bundled julia/Positron package first (to load Positron.jl's own dependencies), then only re-activates the user's project if POSITRON_USER_PROJECT points to a directory with a Project.toml/JuliaProject.toml. When neither is true - no workspace folder open, or the folder has no project file - the kernel was left permanently activated on the extension's own internal package, so `] status`, `Pkg.add`, etc. silently targeted the extension's bundled dev environment instead of the user's default global one. This is what the Pkg REPL mode prompt surfaced as `(Positron) pkg>` instead of `(@v1.12) pkg>`. Pkg.activate() with no arguments clears the explicit override and lets Julia resolve the project the normal way (nearest Project.toml, else the default global environment), exactly as if `--project` had never been passed. Add that as the missing else branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes three issues for the 0.2.0 release: #32, #35, and #31.
valuesshadowing crash in the package hooks (closes #32)The package-pane helper script was included directly into
Main, so every unqualified Base name it used resolved through the user's namespace —values = [3, 7, 2]shadowedBase.valuesand made the background_positron_list_packages()hook fail with a repeating "Julia package command failed" toast.scripts/packages/packages.jlnow defines everything inside a_PositronPackagesmodule, so Base names always resolve to Base regardless of what the user defines inMain. This fixes the whole class of shadowing bugs (values,keys,filter, ...), not just the reported one.includecall insrc/packages.tsareBase.-qualified for the same reason (open,redirect_stdout,close,flushwere equally shadowable).Mainwithvalues = [3, 7, 2, 5, 4]and runs the list hook through it.Pkg REPL mode in the console (closes #35)
VSCodeServer binds the
]key in a LineEdit keymap that transitions the terminal REPL intoPkg.REPLMode. Positron's console is Jupyter-based and never sees raw keystrokes, so the transition happens on submission instead:]enters Pkg REPL mode. The console prompt changes to the environment-aware(@v1.12) pkg>/(MyProject) pkg>via Positron'sprompt_stateUI event (the same mechanism ark uses for R'sbrowser()prompts).Pkg.REPLMode(IJulia's version-aware bridge), with output in the console:status,add DataFrames,?, etc.back,exit, orquitreturns to thejulia>prompt — the Backspace/Ctrl-C keystrokes that leave the mode in a terminal can't reach a Jupyter kernel, so typed commands replace them (the entry message says so).pkg>prompt.] add DataFrames) still work from thejulia>prompt, andcheck_code_completenow reports REPL special-mode lines (]...,?foo,;ls) as complete so the console executes them instead of treating them as invalid."Julia: Create New Package" command (closes #31)
New
julia.createNewPackagecommand scaffolds a package with PkgTemplates.jl: prompts for a name (validated), a parent folder, and template options — git repository, MIT license, GitHub Actions CI, Documenter docs; tests and README are always included.Pkg.generate(with a distinct success message) when PkgTemplates cannot be installed, e.g. offline.git config github.user. The git option is pre-selected only when a git identity is configured.Testing
Pkg.test("Positron"): 1001/1001 pass, including new tests for the shadowed-Mainscenario, Pkg REPL mode enter/exit + completeness, the extension-internal bypass, andextract_pkg_repl_command.statusoutput throughPkg.REPLMode→ exit.tscand esbuild bundle are clean.create_package.jlexercised end-to-end for all three paths: full options (git+license+ci+docs → complete scaffold with initial commits), license-only without a username, and the offlinePkg.generatefallback.🤖 Generated with Claude Code