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
|
|
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
|
|
87
|
-
|
|
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 $
|
|
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
|
@@ -99,7 +99,8 @@ if (-not $?) {
|
|
|
99
99
|
$Target = (Resolve-Path $Target).Path
|
|
100
100
|
$Target = [System.IO.Path]::TrimEndingDirectorySeparator($Target)
|
|
101
101
|
|
|
102
|
-
$
|
|
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""')
|