As an HPC facilitator I assist researchers with troubleshooting or optimizing their code. To keep my work organized I created this tooling that generates a directory structure to support my work for any new request I receive, plus helper scripts and Claude Code assets for diagnosing common build/environment problems.
Git needs to be installed. Helper scripts under bin/ use LMOD module commands (BU SCC). Add bin/ to your PATH for the common tools (new_request.sh, triage_build_log.sh) — e.g. in ~/.bashrc:
export PATH="/path/to/new_request/bin:$PATH"Per-language tools live in bin/<lang>/ and are activated per request via the workspace's module_load.sh (see Usage), so they aren't all on your PATH at once.
Syntax: new_request.sh CLIENT TICKET [DIR] [--lang LANGS]
Arguments:
CLIENT A client identifier (e.g. username).
TICKET Request identifier (e.g. ticket number).
DIR Location to create directory hierarchy (if blank defaults to pwd).
--lang Comma-separated language toolset(s) to activate, e.g. --lang r
or --lang r,python . Puts bin/<lang> on PATH when the workspace's
module_load.sh is sourced.new_request.sh lives in this repo's bin/; with bin/ on your PATH you can run it from anywhere. It creates a new request directory using CLIENT and TICKET as unique identifiers and initializes it as a git repository. For example:
new_request.sh bob 123456 --lang r
Initialized empty Git repository in /projectnb/dvm-rcs/client/bob/123456/.git/Scripts are organized by language and maintained once (not copied into each workspace):
- Common (top-level
bin/):new_request.sh— scaffold a request workspace.triage_build_log.sh [LOG|WORKSPACE]— analyze any build/compile/install log: strips warning noise, finds the real error, detects the ecosystem, and classifies it (SUCCESS / COMPILE-ERROR / LINK-ERROR / OOM-KILL / MISSING-DEPENDENCY / CONFIGURE-ERROR / ENV-NOT-ACTIVATED / UNKNOWN). Backs thetriage-build-logClaude skill.
- R (
bin/r/):r_env.sh [R_MODULE] [WORKSPACE]— one-time setup: loads the R module, makes a per-module package library in the workspace, installs the packages VSCode needs, and records the R env in the workspace'smodule_load.sh+.gitignore. Run it (don't source); activate afterwards withsource <workspace>/module_load.sh.r_snapshot.sh [WORKSPACE]— records the workspace's R library intoenv_setup/renv.lock(a manifest). Uses renv only to document the library, not change it.r_install.sh <pkg> [WORKSPACE]— reproduce a researcher's R package install in the workspace and report a classified outcome (viatriage_build_log.sh).
bin/python/— placeholder for future Python tools.
Reproduce the researcher's R environment inside the request's isolated library and capture a manifest; step 3 (the copy) is manual:
- Set up the R environment (one-time; run by path — it needs nothing on PATH and writes the R block into
module_load.sh):/path/to/new_request/bin/r/r_env.sh R/4.5.2 /path/to/request - Activate (now and every future session — loads R, sets
R_LIBS_USER, and puts the commonbin/+ the R toolset on PATH):source /path/to/request/module_load.sh - Copy the researcher's R library into
$R_LIBS_USER— done manually withscp(it requires logging in as the researcher). Byte-for-byte copy, valid only on the same cluster / same R version. - Record the manifest:
r_snapshot.sh /path/to/request
To switch R versions later, just re-run step 1 with a different R/X.Y; r_env.sh replaces the R block in module_load.sh (re-source to pick it up).
renv.lock is committed (the record of what was reproduced); the reproduced R/<version>/ library is not. You do not need the researcher to have used renv.
- For a failing R package install, ask Claude Code to use the
r-install-debuggersubagent (or runr_install.sh <pkg>yourself): it reproduces the install in the workspace and returns a classified verdict. - For any build log (R, Python, C/C++, Fortran), run
triage_build_log.sh <log>or invoke the/triage-styletriage-build-logskill in Claude Code. It declares the ecosystems it supports and reports back if a log's language is outside that set, instead of guessing.
The scaffolder creates:
- data — relevant data used by the client's scripts.
- env_setup — holds
renv.lock(the reproduced-package manifest, tracked) and.renv-tools/(gitignored). The helper scripts live centrally in this repo'sbin/<lang>/, not here. - scripts — the client's scripts.
- output — output generated by the client's scripts (e.g.
*_install.log). - context — request context:
problem.mdandlinks.mdfor you to fill in;/init-requestalso writesSUMMARY.md. Drop researcher-provided build/job logs incontext/logs/(gitignored; the folder is kept via.gitkeep) —/init-requestsamples each log's head + tail and triages build logs rather than reading them whole. - CLAUDE.md — per-workspace map of the layout + conventions, so Claude Code has context.
- module_load.sh — sourced to activate the workspace: loads modules, puts the request's
bin/<lang>toolset(s) on PATH, and exportsXDG_*,RENV_PATHS_ROOT, andR_ENVIRON_USER/R_PROFILE_USER/R_HISTFILEinto the request directory so caches/config/data/history stay in the workspace, not your home (~/.cache, ...). Best-effort — scripts that hardcode~or absolute home paths can still escape; use a container or throwaway user for hard isolation.
Each request workspace gives Claude Code the context it needs:
- Describe the issue in
context/problem.mdand add relevant URLs/tickets tocontext/links.md. - Run the
/init-requestslash command in the workspace — it readsCLAUDE.md,context/,scripts/, and the environment, writescontext/SUMMARY.md, and reports.
Each workspace's .claude/ is a symlink to this repo's own .claude/, so every Claude command/skill/agent lives in one place: add or edit one here (.claude/commands/, .claude/skills/, .claude/agents/) and every workspace — existing and new — picks it up, no re-scaffolding. (The workspace .claude symlink is gitignored.)