pc:setup
Set PartCAD up so pc and partcad become runnable, and so the editor this
session is running in — if it is running in one — can browse and view what they
build.
Named
setuprather thaninstallbecausepc installis a different thing entirely. That command is PartCAD'snpm install: it fetches a package's imports into the local cache, and it needs PartCAD to already be here. This skill is what puts PartCAD here.
Two parts, in order:
- The command line tools, always. The argument selects how. It is in
$ARGUMENTS; if empty or unrecognized, default toexecutableand say so. - The editor extension, only when this session is running inside Visual Studio Code or VSCodium. Everywhere else there is nothing to do.
| Argument | Installs | Afterward it runs as |
|---|---|---|
executable |
Standalone PyInstaller bundle from the latest GitHub release (no Python needed) | pc / partcad on PATH |
python-module |
The partcad wheel into the active Python environment |
python -m partcad_cli.click.command |
Which version
The plugin these skills ship in is released by PartCAD's own release, under
PartCAD's own version: the version in the plugin's .claude-plugin/plugin.json
names the release they were written against. Installing the newest release is
the default and is normally right — the skills use documented commands, which do
not disappear. Install that exact one when a newer PartCAD turns out to behave
differently from what a skill describes, and say why. How to pin depends on the
mode, and the two do not share a knob:
| Mode | Pin the plugin's version with |
|---|---|
executable |
... | sh -s -- --version <version>, or PARTCAD_VERSION=<version> |
python-module |
"${PY}" -m pip install -U "partcad==<version>" |
--version and PARTCAD_VERSION are install.sh options and do nothing in
python-module mode, where the version is part of the requirement pip is
given.
0. Skip if already installed
Check whether PartCAD is already available, using the same resolution /pc:init
uses; if so, report it and go on to The editor extension below — do not
reinstall unless the user asked for it.
Resolve the interpreter first and keep it as PY, because /pc:init tries
python and python3 and this has to agree with it. A machine can have
either name, both, or a python that is Python 2; a check that only ever runs
python misses an installed partcad_cli on any machine where python3 is
the only one — which is most Linux distributions and every current macOS — and
then reinstalls PartCAD over a working installation:
PY=""
for candidate in python python3; do
if "${candidate}" -c "import sys; sys.exit(0 if sys.version_info[0] == 3 else 1)" >/dev/null 2>&1; then
PY="${candidate}"; break
fi
done
if command -v pc >/dev/null 2>&1 || command -v partcad >/dev/null 2>&1 ||
{ [ -n "${PY}" ] && "${PY}" -c "import partcad_cli" >/dev/null 2>&1; }; then
echo "already installed"
fi
PY empty means no Python 3 at all, which rules python-module out entirely
and leaves executable — which needs none.
executable — standalone build from GitHub releases
Defer to PartCAD's official POSIX installer, which finds the latest release,
downloads the bundle for this OS/arch, verifies the checksum, and links pc /
partcad into ~/.local/bin:
curl -fsSL https://raw.githubusercontent.com/partcad/partcad/main/install.sh | sh
Options pass through the pipe with sh -s -- (for example
... | sh -s -- --version 0.7.135); the same knobs exist as environment
variables (PARTCAD_VERSION, PARTCAD_REPOSITORY, PARTCAD_BIN_DIR, …).
Every release publishes bundles for Linux (x86_64, arm64), macOS (Apple silicon
and Intel) and Windows, along with a platforms.json manifest the installer
reads to pick the right one for this machine. The download is around 57MB on
Linux x86_64 and about half that on macOS and Linux arm64.
Should the installer fail, report what it said and stop. Do not fall back to another install method and do not hand-roll one. The two failures worth recognizing:
error: download failed.
There may be no build of <version> for <platform>.
— no bundle for this platform in the release that was asked for. --platform
names one explicitly; --version picks a different release.
error: could not determine the latest release
— the release list could not be reached at all, which is a network or rate-limit problem rather than a missing build.
python-module — into the active Python environment
Only when the user explicitly asks for this mode. Install the partcad wheel
with the pip of PY, the interpreter resolved in step 0 — never a bare
python, for the reason given there. It carries the CLI, the JSON-RPC service
and the viewer client, so this one install is everything:
"${PY}" -m pip install -U partcad
If pip refuses on a permissions or externally-managed-environment error, retry
with --user, or use pipx install partcad or a virtualenv. Verify and
report the result:
"${PY}" -m partcad_cli.click.command --version
The editor extension
Do this after the command line tools are in place, whichever mode installed
them. The PartCAD extension puts a package's parts, assemblies and sketches in
the sidebar and hosts the PartCAD Viewer; it is a JSON-RPC client of the
partcad-json-rpc those tools just provided, so it is worth having wherever
this session is running in an editor that can host it.
Outside such an editor there is nothing to install and nothing to report. Do not go looking for an editor elsewhere on the machine, and do not offer to install one.
1. Which editor, if any
Visual Studio Code, VSCodium and the PartCAD IDE all set TERM_PROGRAM=vscode
in their integrated terminals, and each one puts its own command line tool on
the PATH of those terminals. That pair is what tells them apart:
EDITOR_CLI=""
if [ "${TERM_PROGRAM:-}" = "vscode" ]; then
# The built-in Git extension names the executable of the window this terminal
# belongs to. Matched case-folded and with spaces and hyphens removed, because
# the same application spells itself differently per platform: the PartCAD IDE
# is "partcad-ide" on Linux and Windows, where its executable is renamed, and
# "PartCAD IDE.app" on macOS, where nothing inside the bundle is renamed and
# only the bundle directory carries the name. Complete by construction after
# that: anything in this family that is neither the IDE nor VSCodium is Visual
# Studio Code, so there is no list of VS Code paths to keep up to date.
marker="$(printf '%s' "${VSCODE_GIT_ASKPASS_NODE:-}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')"
case "${marker}" in
"") EDITOR_CLI="" ;;
*partcadide*) EDITOR_CLI="partcad-ide" ;;
*odium*) EDITOR_CLI="codium" ;;
*insiders*) EDITOR_CLI="code-insiders" ;;
*) EDITOR_CLI="code" ;;
esac
# Unset (the Git extension can be disabled), or naming a build whose command
# line tool is not installed: take the first of these on `PATH`, left to
# right. The integrated terminal puts the running application's own `bin`
# directory at the front, so the leftmost match is that application -- which
# is why the order of `PATH` decides and not the order of this list. A fixed
# candidate order answers with whichever editor is listed first rather than
# whichever one is running, on any machine that has two of them.
if [ -z "${EDITOR_CLI}" ] || ! command -v "${EDITOR_CLI}" >/dev/null 2>&1; then
EDITOR_CLI=""
IFS=:
for dir in ${PATH}; do
for candidate in partcad-ide codium codium-insiders code code-insiders; do
if [ -x "${dir}/${candidate}" ]; then EDITOR_CLI="${candidate}"; break 2; fi
done
done
unset IFS
fi
fi
echo "EDITOR_CLI=${EDITOR_CLI:-<none>}"
An empty EDITOR_CLI means a plain terminal, or an editor whose command line
tool is not on PATH (on macOS, "Shell Command: Install 'code' command in PATH"
from the command palette adds it). Say nothing about extensions and stop.
2. Stop if there is nothing to do
partcad-ide is the PartCAD IDE, which already ships this extension inside
the application and versions it with the IDE — a new one arrives with a new IDE,
not from here. There is nothing to install and nothing to check: report that and
stop. Installing anyway would not even land in the same place, since the IDE
keeps its extensions in the application and its state in ~/.partcad-ide,
sharing neither with a Visual Studio Code or VSCodium on the machine.
Otherwise, check whether it is installed already, by its extension id:
"${EDITOR_CLI}" --list-extensions | grep -qix "partcad.partcad-official" && echo "already installed"
openvmp.partcad in that list is not it. That is the identity the extension
was published under before it moved, and it is now a stub whose only content is
a dependency on PartCAD.partcad-official — so an installation holding it has
either pulled the real extension in already or will on its next update.
Installing PartCAD.partcad-official is what the stub is for, done now instead
of whenever that update arrives, so treat the extension as missing unless
partcad.partcad-official itself is listed.
3. Install it
The extension's id is PartCAD.partcad-official, and each editor resolves it
against its own gallery: Visual Studio Code against the Visual Studio
Marketplace, VSCodium against Open VSX, where PartCAD
publishes it for exactly that reason — the Marketplace's terms restrict its use
to Microsoft's own products, so a VSCodium pointed at that one would be in the
wrong. Which gallery answers is therefore the editor's business and not this
skill's, and the command is the same either way:
"${EDITOR_CLI}" --install-extension PartCAD.partcad-official
Use ${EDITOR_CLI} rather than a literal name: it is what distinguishes an
Insiders build from a stable one, and installing into the wrong one leaves the
window the user is looking at without the extension.
Should the gallery be unreachable, or should the user want a particular version, every release carries the same package — one build for every platform, the extension being a JSON-RPC client with no Python and nothing compiled in it:
version="$(curl -fsSL https://api.github.com/repos/partcad/partcad/releases/latest |
sed -n 's/.*"tag_name" *: *"\([^"]*\)".*/\1/p' | head -n 1)"
if [ -z "${version}" ]; then
echo "error: could not determine the latest release" >&2
else
vsix="$(mktemp -d)/partcad-${version}.vsix"
curl -fsSL -o "${vsix}" \
"https://github.com/partcad/partcad/releases/download/${version}/partcad-${version}.vsix" &&
"${EDITOR_CLI}" --install-extension "${vsix}"
fi
partcad-<version>.vsix is the extension. The partcad-shim-<version>.vsix
beside it is the old OpenVMP.partcad entry, which is nothing but a dependency
on the real one — installing that here would send the editor back to the gallery
this route exists to do without.
Name a release in place of ${version} to pin one, the same way --version
pins the tools above. If either step fails, report what it said and stop: these
are the same two failures install.sh names, a release that cannot be resolved
and an asset that cannot be downloaded.
4. Report
The extension loads on the next window reload, so say so: "Developer: Reload Window" from the command palette, or reopen the folder.
It then finds the tools by itself — an existing standalone installation, or a
partcad-json-rpc on PATH — and only asks when it finds neither. Two cases
where it will find neither, worth mentioning when they apply:
python-moduleinto a virtual environment. ThePATHthe extension searches is the one the editor was started with, which does not include a virtualenv unless the editor was launched from it. Pointpartcad.servicePathat the environment'spartcad-json-rpc, or use "Find installed PartCAD", which fills that setting in.executablein a session whosePATHthe editor never saw. Reloading the window is enough if~/.local/binis on the editor'sPATH; otherwise the same setting is the answer.
Finally
Whatever was set up, close by suggesting the task the user was actually after —
/pc:init to start a package, /pc:gen to make something — rather than leaving
them at a bare installation.