claude-dev-env 8.30.0 → 8.30.1

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.
@@ -39,6 +39,7 @@ prove the task by the artifact it changes.
39
39
  - `LastTaskResult: 0` from a run that took the idle branch says nothing about the branch that acts.
40
40
  - A `#Requires -RunAsAdministrator` line pasted at a prompt checks nothing. It applies only to a script file.
41
41
  - An elevated window opens in `C:\WINDOWS\system32`. A prompt in the user's home folder is usually unelevated.
42
+ - An Interactive task that starts `pwsh.exe -WindowStyle Hidden` still flashes a console window on the signed-in desktop. Windows draws the console before PowerShell reads the flag. `conhost.exe --headless` in front of the executable starts it with no window.
42
43
 
43
44
  ## When this applies
44
45
 
@@ -49,7 +50,7 @@ module. Register the task in an elevated shell when the task must run while the
49
50
 
50
51
  1. Resolve every executable in the action with `Get-Command <name>` and read `.Source`.
51
52
  2. Read `files[]` in `~/.claude/.claude-dev-env-manifest.json` and pick a directory that list omits.
52
- 3. Build the action with the absolute executable path and `-WindowStyle Hidden` inside the argument string.
53
+ 3. Build the action with `conhost.exe --headless` as the executable, followed by the absolute path of the program it starts.
53
54
  4. Build a `-Once` trigger with a repetition interval and no duration, then clear the duration on the trigger object.
54
55
  5. Build the settings set.
55
56
  6. Register with an S4U principal, catch the registration failure, and register with an Interactive principal.
@@ -83,18 +84,21 @@ try {
83
84
  ```
84
85
 
85
86
  S4U runs the task with no window whether or not the user is signed in, and its registration needs an
86
- elevated shell. The Interactive principal with `-WindowStyle Hidden` in the action runs windowless
87
- while the user is signed in. Report `$PrincipalKind` so the operator knows which one the task holds.
87
+ elevated shell. The Interactive principal runs the task on the signed-in desktop, so its action goes
88
+ through `conhost.exe --headless` to stay windowless. Report `$PrincipalKind` so the operator knows
89
+ which one the task holds.
88
90
 
89
91
  ## Absolute paths in the action
90
92
 
91
93
  ```powershell
94
+ $ConhostPath = Join-Path -Path $env:SystemRoot -ChildPath 'System32\conhost.exe'
92
95
  $PwshPath = (Get-Command pwsh).Source
93
- $Action = New-ScheduledTaskAction -Execute $PwshPath -Argument "-NoProfile -WindowStyle Hidden -File ""$ScriptPath"""
96
+ $Action = New-ScheduledTaskAction -Execute $ConhostPath -Argument "--headless ""$PwshPath"" -NoProfile -File ""$ScriptPath"""
94
97
  ```
95
98
 
96
99
  Resolve each executable at registration time and store the absolute path in the action. Give the
97
- script an absolute path too.
100
+ script an absolute path too. The same `--headless` front works for any console program, such as
101
+ `python.exe` or `cmd.exe`.
98
102
 
99
103
  ## Settings
100
104
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.30.0",
3
+ "version": "8.30.1",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -99,7 +99,8 @@ if (-not $?) {
99
99
  $Target = (Resolve-Path $Target).Path
100
100
  $Target = [System.IO.Path]::TrimEndingDirectorySeparator($Target)
101
101
 
102
- $Action = New-ScheduledTaskAction -Execute $PythonPath -Argument """$ScriptPath"" --once --age $AgeSeconds ""$Target"""
102
+ $ConhostPath = Join-Path -Path $env:SystemRoot -ChildPath 'System32\conhost.exe'
103
+ $Action = New-ScheduledTaskAction -Execute $ConhostPath -Argument "--headless ""$PythonPath"" ""$ScriptPath"" --once --age $AgeSeconds ""$Target"""
103
104
  $Trigger = New-ScheduledTaskTrigger -Once -At $StartAt -RepetitionInterval (New-TimeSpan -Minutes $IntervalMinutes) -RepetitionDuration (New-TimeSpan -Days 31)
104
105
  $Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
105
106
 
@@ -0,0 +1,42 @@
1
+ """Specifications for the scheduled task Install-SweepEmptyDirs.ps1 registers.
2
+
3
+ A task that starts a console program straight from Task Scheduler draws a
4
+ console window on the signed-in desktop at every run. The registered action
5
+ starts the program through conhost.exe --headless so no window appears.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import re
11
+ from pathlib import Path
12
+
13
+ _INSTALLER_PATH = Path(__file__).resolve().parents[1] / "Install-SweepEmptyDirs.ps1"
14
+ _UTF8_ENCODING = "utf-8"
15
+ _ACTION_PATTERN = re.compile(
16
+ r"^\$Action = New-ScheduledTaskAction -Execute (\$\w+) -Argument (.+)$",
17
+ re.MULTILINE,
18
+ )
19
+ _CONHOST_ASSIGNMENT = (
20
+ "$ConhostPath = Join-Path -Path $env:SystemRoot -ChildPath 'System32\\conhost.exe'"
21
+ )
22
+
23
+
24
+ def _registered_action() -> tuple[str, str]:
25
+ installer_text = _INSTALLER_PATH.read_text(encoding=_UTF8_ENCODING)
26
+ all_actions = _ACTION_PATTERN.findall(installer_text)
27
+ assert len(all_actions) == 1, all_actions
28
+ return all_actions[0]
29
+
30
+
31
+ def test_should_start_the_task_through_conhost() -> None:
32
+ installer_text = _INSTALLER_PATH.read_text(encoding=_UTF8_ENCODING)
33
+ executable_variable, _ = _registered_action()
34
+
35
+ assert executable_variable == "$ConhostPath"
36
+ assert _CONHOST_ASSIGNMENT in installer_text
37
+
38
+
39
+ def test_should_pass_headless_before_the_python_program() -> None:
40
+ _, argument_text = _registered_action()
41
+
42
+ assert argument_text.startswith('"--headless ""$PythonPath"" ""$ScriptPath""')