journal/Journal.DevTool/Config/DevToolConfig.cs
stan44 5b383858ae feat(sdt): add Journal.DevTool TUI, devtool.json, and justfile
- Journal.DevTool: C# TUI dev tool (SDT) using Spectre.Console
  - Phosphor green (#00FF41) terminal aesthetic with amber/red accents
  - Grouped build target menu driven by devtool.json config
  - Topological dependency resolver for DependsOn chains
  - Live stdout/stderr streaming per target step
  - Interactive environment variable editor (dropdown + free-text)
  - Toolchain management screen: Python venv create/install/upgrade, Node npm install
  - Workspace switcher: reads sdt-workspace.json, hot-switches between projects
  - Outputs as 'sdt' executable (net10.0)

- devtool.json: project config for SDT
  - All build targets: sidecar, web, webgateway, tauri, tauri-nsis, all (virtual)
  - Dev targets: run-gateway
  - Test targets: test (smoke), gate (migration)
  - Cache targets: nuget-export, nuget-import
  - Toolchains: Python 3.14 (cpu/gpu/nlp profiles) + Node/npm (Journal.App)
  - Env vars: AI provider, log level, NLP backend, path overrides

- justfile: just command runner recipes wrapping existing scripts
  - Correct dependency ordering (sidecar before tauri, web before webgateway)
  - OS-aware runtime detection (win-x64 / linux-x64)
  - Recipes: sidecar, web, webgateway, tauri, tauri-nsis, all, run, dev-app, test, gate, build, nuget-export/import, sdt

- Journal.slnx: added Journal.DevTool project
2026-02-27 13:12:36 -06:00

87 lines
3.0 KiB
C#

namespace Sdt.Config;
public sealed class DevToolConfig
{
public string Name { get; init; } = "SDT Project";
public string Version { get; init; } = "0.1.0";
public List<BuildTarget> Targets { get; init; } = [];
public List<EnvVarDef> Env { get; init; } = [];
public ToolchainConfig? Toolchains { get; init; }
}
public sealed class BuildTarget
{
public string Id { get; init; } = "";
public string Label { get; init; } = "";
public string Description { get; init; } = "";
public string Group { get; init; } = "General";
/// <summary>Executable name. Null = virtual aggregator (runs DependsOn only).</summary>
public string? Command { get; init; }
public List<string> Args { get; init; } = [];
/// <summary>Working directory relative to project root.</summary>
public string WorkingDir { get; init; } = ".";
public List<string> DependsOn { get; init; } = [];
}
public sealed class EnvVarDef
{
public string Key { get; init; } = "";
public string Description { get; init; } = "";
[System.Text.Json.Serialization.JsonPropertyName("default")]
public string DefaultValue { get; init; } = "";
/// <summary>If non-empty, shown as a dropdown. Otherwise free-text input.</summary>
public List<string> Options { get; init; } = [];
}
// ── Toolchain config ──────────────────────────────────────────────────────────
public sealed class ToolchainConfig
{
public PythonToolchain? Python { get; init; }
public NodeToolchain? Node { get; init; }
}
public sealed class PythonToolchain
{
/// <summary>Python executable (e.g. "python3.14", "python").</summary>
public string Executable { get; init; } = "python";
/// <summary>Windows-specific override (e.g. "py" when using the launcher).</summary>
public string? WindowsExecutable { get; init; }
/// <summary>Optional version flag to pass (e.g. "-3.14" for py launcher).</summary>
public string? LauncherVersion { get; init; }
/// <summary>Venv directory relative to project root.</summary>
public string VenvDir { get; init; } = ".venv";
public List<PythonProfile> Profiles { get; init; } = [];
/// <summary>Optional path to a pip wrapper script (relative to project root).</summary>
public string? PipScript { get; init; }
}
public sealed class PythonProfile
{
public string Id { get; init; } = "";
public string Label { get; init; } = "";
public string RequirementsFile { get; init; } = "";
public string? ExtraIndexUrl { get; init; }
public List<string> PostInstallCommands { get; init; } = [];
}
public sealed class NodeToolchain
{
/// <summary>Package manager: "npm", "pnpm", or "yarn".</summary>
public string PackageManager { get; init; } = "npm";
/// <summary>Working directory for the frontend (relative to project root).</summary>
public string WorkingDir { get; init; } = ".";
}