235 lines
8.8 KiB
Markdown

# SDT — Stan's Dev Tools
> **Status: v0.1 — active development**
> Phosphor-green TUI build orchestrator. Currently embedded in Project Journal; long-term goal is a standalone universal dev tool.
---
## What It Is
SDT is a terminal UI (TUI) application for managing builds, toolchains, and multi-project workspaces. It reads a `devtool.json` from your project root and presents a menu-driven interface so you never have to remember which script to run, in what order, with what flags.
```
____ ____ _____
/ ___|| _ \|_ _|
\___ \| | | | | |
___) | |_| | | |
|____/|____/ |_|
─────────── Project Journal v0.1.0 ─────────────
root: E:\stansshit\csharp\journal-master\journal
What would you like to do?
BUILD
> Publish Sidecar Build Journal.Sidecar as self-contained exe
Build Web UI Build SvelteKit bundle
Publish WebGateway Publish ASP.NET host with embedded web UI
Build Tauri Desktop App Build desktop exe (no installer)
Full Release Build ✦ Sidecar → Web → WebGateway → Tauri, in order
...
SYSTEM
⬡ Toolchain management python / node
⚙ Edit environment variables
✗ Quit
```
---
## Current Features (v0.1)
### Build Target Runner
- Menu driven by `devtool.json` — add/remove targets without touching SDT code
- **Dependency resolution**: targets declare `dependsOn`; SDT topologically sorts them and runs each step exactly once. Select `webgateway` and `web` runs first automatically. Select `all` and everything runs in the right order.
- **Live output streaming**: stdout in phosphor green, stderr in amber — you see the build as it happens
- Each step reports exit code and elapsed time
### Environment Variable Editor
- All configurable env vars declared in `devtool.json`
- Dropdown selection for known options (e.g. `none`/`python-sidecar` for AI provider)
- Free-text input for path overrides
- Changes apply to SDT's process environment for the current session
### Toolchain Management
Python:
- Detect system Python and venv status in one health-check table
- Create / recreate venv (`python -m venv`)
- Install requirements profile — select cpu / gpu / nlp, handles `--extra-index-url` automatically
- Upgrade pip
- Cross-platform venv path resolution (`Scripts/` on Windows, `bin/` on Linux/Mac)
Node / npm:
- Detect Node.js and npm versions
- Check `node_modules` status
- Run `npm install` (or `pnpm`/`yarn` — configurable per project)
### Multi-Project Workspace Switcher
- Place `sdt-workspace.json` in any parent directory listing your projects
- SDT detects it automatically on startup
- **Switch Project** appears in SYSTEM menu when workspace is loaded with more than one project
- Selecting a different project hot-reloads config in-process — no restart needed
- Project table shows current (`►`), path, and whether `devtool.json` exists
---
## Running SDT
From the project root (where `devtool.json` lives):
```powershell
dotnet run --project Journal.DevTool/Journal.DevTool.csproj
```
Or via `just`:
```powershell
just sdt
```
SDT walks up the directory tree from wherever you launch it to find `devtool.json`. You don't need to be in any specific directory.
---
## Config Files
### `devtool.json` (per project)
```json
{
"name": "My Project",
"version": "1.0.0",
"toolchains": {
"python": {
"executable": "python3",
"venvDir": ".venv",
"profiles": [
{ "id": "default", "label": "Default", "requirementsFile": "requirements.txt" }
]
},
"node": { "packageManager": "npm", "workingDir": "frontend" }
},
"targets": [
{
"id": "build",
"label": "Build",
"description": "Build everything",
"group": "Build",
"command": "dotnet",
"args": ["build"],
"workingDir": ".",
"dependsOn": []
}
],
"env": [
{
"key": "MY_VAR",
"description": "Controls something",
"default": "value",
"options": ["value", "other"]
}
]
}
```
**Target fields:**
| Field | Description |
|-------|-------------|
| `id` | Unique identifier, referenced by `dependsOn` |
| `label` | Display name in the menu |
| `description` | Short hint shown in the menu |
| `group` | Menu category (BUILD / DEV / TEST / etc.) |
| `command` | Executable to run (`dotnet`, `pwsh`, `npm`, etc.) — `null` for virtual aggregator |
| `args` | Argument array passed to the executable |
| `workingDir` | Working directory relative to project root |
| `dependsOn` | List of target IDs that must run first |
### `sdt-workspace.json` (per workspace, any parent directory)
```json
{
"name": "My Dev Workspace",
"projects": [
{ "name": "Project A", "description": "Does X", "path": "project-a" },
{ "name": "Project B", "description": "Does Y", "path": "../other-repo/project-b" }
]
}
```
Paths are relative to the `sdt-workspace.json` file. Absolute paths also work.
---
## Project Structure
```
Journal.DevTool/
├── Journal.DevTool.csproj net10.0 exe, outputs as 'sdt'
├── Program.cs Entry point — discovers workspace + project, run loop
├── Config/
│ ├── DevToolConfig.cs devtool.json models (BuildTarget, EnvVarDef, ToolchainConfig)
│ ├── ConfigLoader.cs Walks up dirs to find and parse devtool.json
│ ├── WorkspaceConfig.cs sdt-workspace.json model
│ └── WorkspaceLoader.cs Finds and parses sdt-workspace.json
├── Runner/
│ ├── ProcessRunner.cs Runs a process with live stdout/stderr streaming
│ └── TargetRunner.cs Topological dependency resolver
└── Tui/
├── Theme.cs Phosphor green palette (#00FF41 + amber + red)
├── App.cs Main TUI loop — banner, menu, target runner, env editor
├── ToolchainScreen.cs Python venv/pip + Node/npm management
└── WorkspaceScreen.cs Project switcher
```
---
## Roadmap
### v0.2 — Usability & Polish
- [ ] `--target <id>` flag for non-interactive single-target run (CI use)
- [ ] `--list` flag to print targets and exit
- [ ] Config validation with clear error messages on startup
- [ ] Build history — last run result + timestamp per target (persisted to `.sdt-state.json`)
- [ ] Parallel target execution for independent steps (opt-in per target)
### v0.3 — Package Manager Depth
- [ ] Full pip environment health: list installed packages, outdated check
- [ ] npm/pnpm/yarn: show scripts from `package.json`, run arbitrary script
- [ ] Python version manager integration (pyenv, py launcher on Windows)
- [ ] Virtual environment activation hint for the current shell
### v0.4 — Multi-Project & Workspace
- [ ] Workspace-level targets that span multiple projects (e.g. build all repos in order)
- [ ] Project dependency graph across workspace (project A's publish feeds project B's build)
- [ ] Workspace health dashboard — all projects' last-build status in one table
### v0.5 — Env & Secrets
- [ ] `.env` file load/save support (per project and per workspace)
- [ ] Secret redaction in log output (already in Journal's LogRedactor — port to SDT)
- [ ] Environment profiles: save/load named env var sets (e.g. "dev", "staging")
### v1.0 — Standalone Universal Tool
- [ ] Extract from Journal repo into its own standalone repository
- [ ] Publish as a `dotnet tool` (`dotnet tool install sdt`)
- [ ] Plugin system: projects can register custom SDT commands via `IsdtPlugin`
- [ ] GUI mode (Avalonia or web UI) as an optional launch mode — default CLI, `--gui` for graphical
- [ ] Linux and macOS first-class support (already mostly there — mainly path/exe resolution)
- [ ] JSON schema for `devtool.json` with IDE autocompletion
### Long-term Vision
SDT's goal is to be **the single tool you open when you sit down at a project** — regardless of language, framework, or OS. Instead of remembering 15 different CLI commands across `dotnet`, `npm`, `pip`, `cargo`, `just`, and `pwsh`, you open SDT and it knows your project's shape from `devtool.json`.
The workspace layer means you can manage a portfolio of projects — switching between them, running cross-project builds, and keeping a consistent interface across everything you work on.
---
## Dependencies
- [`Spectre.Console`](https://spectreconsole.net/) `0.49.1` — TUI rendering, selection prompts, tables, progress
No dependency on `Journal.Core` — SDT is intentionally standalone so it can be extracted cleanly.
---
## Notes
- SDT does **not** set background colour — it renders on whatever your terminal's background is. A dark terminal is strongly recommended for the phosphor look.
- Environment variable changes made in SDT apply to SDT's own process environment for the session. They are **not** written to your system or shell permanently — by design.
- When a build step fails, SDT stops the plan and does not run subsequent steps.