d55887bd29e5

add branded PS1 prompt and exit instruction to nina try and develop

time
2026-06-08 18:29 UTC · 4 months ago
machine
koh2
agent
claude-sonnet-4-6
session
nina try + develop branded PS1 prompt
parent
0e5a095f8dcc
4 files VERSION+1 −1src/commands.zig+3 −2src/exec.zig+48 −0src/output.zig+5 −1
VERSION+1 −1
@@ -1 +1 @@1-3.0.221+3.0.23

view file

src/commands.zig+3 −2
@@ -514,7 +514,7 @@514514     else515515         null;516516     output.developStart(&.{});517-    _ = try exec.nixDevelop(ctx.io, &ctx.machine, ctx.gpa, run_cmd);517+    _ = try exec.nixDevelopPs1(ctx.io, &ctx.machine, ctx.gpa, run_cmd, ctx.environ);518518     output.developDone();519519 }520520 @@ -696,7 +696,8 @@696696 fn tryPkg(ctx: Ctx, npkg: types.NixPackage) !void {697697     output.tryStart(npkg.pname);698698     output.printSubstep("nix shell nixpkgs#{s}", .{npkg.attr});699-    _ = try exec.nixShell(ctx.io, &ctx.machine, ctx.gpa, npkg.attr);699+    output.tryExitHint();700+    _ = try exec.nixShellPs1(ctx.io, &ctx.machine, ctx.gpa, npkg.attr, ctx.environ);700701     output.tryDone();701702 }702703 

view file

src/exec.zig+48 −0
@@ -65,6 +65,38 @@6565     };6666 }6767 68+// Stream a process with an overridden PS1 in the child environment.69+fn streamEnv(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, cmd: []const []const u8, base_env: *const std.process.Environ.Map, ps1: []const u8) !u8 {70+    output.flush();71+    const argv = try buildArgv(gpa, machine, cmd);72+    defer if (!machine.local) gpa.free(argv);73+74+    var env = try base_env.clone(gpa);75+    defer env.deinit();76+    try env.put("PS1", ps1);77+78+    var child = std.process.spawn(io, .{79+        .argv = argv,80+        .stdin = .inherit,81+        .stdout = .inherit,82+        .stderr = .inherit,83+        .environ_map = &env,84+    }) catch |e| {85+        errors.error_info.setMessage("failed to spawn: {s}", .{cmd[0]});86+        return e;87+    };88+89+    const term = child.wait(io) catch |e| {90+        errors.error_info.setMessage("process wait failed", .{});91+        return e;92+    };93+94+    return switch (term) {95+        .exited => |c| c,96+        else => 1,97+    };98+}99+68100 // Stream a local process with inherited stdio (no SSH routing — for nix commands).69101 pub fn streamLocal(io: std.Io, cmd: []const []const u8) !u8 {70102     output.flush();@@ -721,12 +753,28 @@721753     return stream(io, machine, gpa, &.{ "nix", "shell", ref });722754 }723755 756+pub fn nixShellPs1(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, pkg: []const u8, base_env: *const std.process.Environ.Map) !u8 {757+    const ref = try std.fmt.allocPrint(gpa, "nixpkgs#{s}", .{pkg});758+    defer gpa.free(ref);759+    const ps1 = try std.fmt.allocPrint(gpa, "(nina: {s}) -> ", .{pkg});760+    defer gpa.free(ps1);761+    return streamEnv(io, machine, gpa, &.{ "nix", "shell", ref }, base_env, ps1);762+}763+724764 pub fn nixDevelop(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, run_cmd: ?[]const u8) !u8 {725765     if (run_cmd) |cmd| {726766         // sh -c so a multi-word command isn't treated as a single executable name.727767         return stream(io, machine, gpa, &.{ "nix", "develop", "--command", "sh", "-c", cmd });728768     }729769     return stream(io, machine, gpa, &.{ "nix", "develop" });770+}771+772+pub fn nixDevelopPs1(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, run_cmd: ?[]const u8, base_env: *const std.process.Environ.Map) !u8 {773+    if (run_cmd) |cmd| {774+        // sh -c so a multi-word command isn't treated as a single executable name.775+        return stream(io, machine, gpa, &.{ "nix", "develop", "--command", "sh", "-c", cmd });776+    }777+    return streamEnv(io, machine, gpa, &.{ "nix", "develop" }, base_env, "(nina: dev) -> ");730778 }731779 732780 pub fn nixRepl(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {

view file

src/output.zig+5 −1
@@ -409,7 +409,7 @@409409         if (i > 0) p("  ", .{});410410         p("{s}", .{pkg});411411     }412-    p("\n\n   {s}exit to return{s}\n\n", .{ c(DIM), c(RESET) });412+    p("\n\n   {s}-> type 'exit' to return{s}\n\n", .{ c(DIM), c(RESET) });413413 }414414 415415 pub fn developDone() void {@@ -583,6 +583,10 @@583583 584584 pub fn tryStart(pkg: []const u8) void {585585     p("{s}trying {s}{s}{s}  exit when done\n", .{ hdr(), c(PINK), pkg, c(RESET) });586+}587+588+pub fn tryExitHint() void {589+    p("   {s}-> type 'exit' to return{s}\n", .{ c(DIM), c(RESET) });586590 }587591 588592 pub fn tryDone() void {

view file