cabletidy 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,90 @@
1
+ param(
2
+ [ValidateSet('version', 'models')][string]$Query,
3
+ [ValidateRange(1, 2147483647)][int]$DaemonPid
4
+ )
5
+ $ErrorActionPreference = 'Stop'
6
+ if (-not (Get-Command codex -CommandType Application -ErrorAction SilentlyContinue)) {
7
+ [Console]::Error.WriteLine('Cannot find codex in PATH')
8
+ exit 127
9
+ }
10
+
11
+ # A Job Object also owns descendants whose launcher has already exited.
12
+ # Keep its non-inheritable handle open until this supervisor exits or is killed.
13
+ Add-Type -TypeDefinition @'
14
+ using System;
15
+ using System.ComponentModel;
16
+ using System.Diagnostics;
17
+ using System.Runtime.InteropServices;
18
+ using System.Threading.Tasks;
19
+
20
+ public static class CableTidyCodexJob {
21
+ [StructLayout(LayoutKind.Sequential)]
22
+ struct BasicLimits {
23
+ public long ProcessTime, JobTime;
24
+ public uint Flags;
25
+ public UIntPtr MinWorkingSet, MaxWorkingSet;
26
+ public uint ActiveProcesses;
27
+ public UIntPtr Affinity;
28
+ public uint Priority, Scheduling;
29
+ }
30
+ [StructLayout(LayoutKind.Sequential)]
31
+ struct IoCounters {
32
+ public ulong ReadOperations, WriteOperations, OtherOperations;
33
+ public ulong ReadBytes, WriteBytes, OtherBytes;
34
+ }
35
+ [StructLayout(LayoutKind.Sequential)]
36
+ struct ExtendedLimits {
37
+ public BasicLimits Basic;
38
+ public IoCounters Io;
39
+ public UIntPtr ProcessMemory, JobMemory, PeakProcessMemory, PeakJobMemory;
40
+ }
41
+ [DllImport("kernel32.dll", SetLastError = true)]
42
+ static extern IntPtr CreateJobObject(IntPtr attributes, string name);
43
+ [DllImport("kernel32.dll", SetLastError = true)]
44
+ static extern bool SetInformationJobObject(IntPtr job, int type, ref ExtendedLimits limits, uint size);
45
+ [DllImport("kernel32.dll", SetLastError = true)]
46
+ static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
47
+ [DllImport("kernel32.dll")]
48
+ static extern bool SetConsoleCtrlHandler(IntPtr handler, bool ignore);
49
+ static IntPtr job;
50
+
51
+ public static int Run(string command, int daemonPid) {
52
+ job = CreateJobObject(IntPtr.Zero, null);
53
+ if (job == IntPtr.Zero) throw new Win32Exception();
54
+ var limits = new ExtendedLimits();
55
+ limits.Basic.Flags = 0x2000; // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
56
+ if (!SetInformationJobObject(job, 9, ref limits, (uint)Marshal.SizeOf(limits)) ||
57
+ !AssignProcessToJobObject(job, Process.GetCurrentProcess().Handle)) {
58
+ throw new Win32Exception();
59
+ }
60
+ // The daemon controls Ctrl+C draining. This flag is inherited by children.
61
+ SetConsoleCtrlHandler(IntPtr.Zero, true);
62
+ // Hold a process handle so PID reuse cannot disguise daemon termination.
63
+ var daemon = Process.GetProcessById(daemonPid);
64
+ if (daemon.Handle == IntPtr.Zero) throw new Win32Exception();
65
+ Task.Run(() => {
66
+ daemon.WaitForExit();
67
+ Environment.Exit(130);
68
+ });
69
+ // Only fixed arguments reach cmd.exe; it resolves native binaries and npm .cmd shims.
70
+ var start = new ProcessStartInfo(Environment.GetEnvironmentVariable("ComSpec"),
71
+ "/d /s /c \"codex " + command + "\"");
72
+ start.UseShellExecute = false;
73
+ start.CreateNoWindow = true;
74
+ start.RedirectStandardOutput = true;
75
+ start.RedirectStandardError = true;
76
+ using (var child = Process.Start(start)) {
77
+ var stdout = child.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput());
78
+ var stderr = child.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError());
79
+ child.WaitForExit();
80
+ // Drain successful output, including pipes still held by descendants.
81
+ // On failure, exiting this supervisor closes the job immediately.
82
+ if (child.ExitCode == 0) Task.WaitAll(stdout, stderr);
83
+ return child.ExitCode;
84
+ }
85
+ }
86
+ }
87
+ '@
88
+
89
+ $command = if ($Query -eq 'version') { '--version' } else { 'debug models --bundled' }
90
+ exit [CableTidyCodexJob]::Run($command, $DaemonPid)