claude-dev-env 8.30.0 → 8.31.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.
@@ -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
 
@@ -16,10 +16,15 @@ WORKING_STYLE_PROMPT = (
16
16
  "Keep disclaimers and caveats short while giving "
17
17
  "the main answer most of the response. Give a high-level explanation by default "
18
18
  "and provide depth when the request calls for it. "
19
- "Before your first tool call, state your next action in one sentence. While "
20
- "working, give brief updates when you find important information or change "
21
- "direction. Finish with the outcome in the first sentence, then provide "
22
- "supporting detail for readers who want it. "
19
+ "On a typed request, state your next action in one sentence before the first "
20
+ "tool call. "
21
+ "Finish with the outcome in the first sentence. "
22
+ "Send the user only what they must act on or need to know. When a background "
23
+ "event, such as a task notification, an agent message, or a scheduled wake, "
24
+ "starts a turn and nothing in it needs the user, end the turn with no text. A "
25
+ "report that a fix is done carries three lines: the fix acknowledged, what "
26
+ "changed, and the proof that it works. Put the rest of the detail in the pull "
27
+ "request or a linked file. "
23
28
  "Match written-document length to the task. Cover the substance and keep every "
24
29
  "section, summary, and phrase useful. "
25
30
  "Deliver the requested work at its intended scope. Make routine judgment calls "
@@ -34,7 +39,7 @@ WORKING_STYLE_PROMPT = (
34
39
  "when the ambiguity changes the outcome, scope, audience, format, or risk. Use a "
35
40
  "clearly stated low-risk assumption when the intended result remains stable. "
36
41
  "Pause for the user's choice before making a high-impact decision. "
37
- "Use current, immediately relevant context. Name each action, fact, reason, "
38
- "and outcome. Use full terms and specific names for repository work. Keep all "
42
+ "Use current, immediately relevant context. "
43
+ "Use full terms and specific names for repository work. Keep all "
39
44
  "text concise, clear, direct, and useful."
40
45
  )
@@ -50,11 +50,26 @@ class TestWorkingStylePrompt:
50
50
  assert "update-in-place continuity, and sharing" in prompt_text
51
51
  assert "Apply ~/.claude/rules/asd-ste100-language.md for user-facing word choice" in prompt_text
52
52
  assert "Use current, immediately relevant context." in prompt_text
53
- assert "Name each action, fact, reason, and outcome." in prompt_text
54
53
  assert "Use full terms and specific names for repository work." in prompt_text
55
54
  assert "When a request has multiple reasonable interpretations" in prompt_text
56
55
  assert "Ask one focused clarification question" in prompt_text
57
56
  assert "Pause for the user's choice before making a high-impact decision." in prompt_text
58
57
 
58
+ def test_prompt_limits_replies_to_what_the_user_must_act_on_or_know(self) -> None:
59
+ assert "Send the user only what they must act on or need to know." in WORKING_STYLE_PROMPT
60
+ assert "starts a turn and nothing in it needs the user, end the turn with no text." in WORKING_STYLE_PROMPT
61
+ assert "On a typed request, state your next action in one sentence" in WORKING_STYLE_PROMPT
62
+ assert "Before your first tool call, state your next action" not in WORKING_STYLE_PROMPT
63
+ assert (
64
+ "A report that a fix is done carries three lines: the fix acknowledged, "
65
+ "what changed, and the proof that it works."
66
+ ) in WORKING_STYLE_PROMPT
67
+ assert "Put the rest of the detail in the pull request or a linked file." in WORKING_STYLE_PROMPT
68
+
69
+ def test_prompt_drops_the_clauses_that_invite_surplus_detail(self) -> None:
70
+ assert "supporting detail for readers who want it" not in WORKING_STYLE_PROMPT
71
+ assert "give brief updates when you find important information" not in WORKING_STYLE_PROMPT
72
+ assert "Name each action, fact, reason, and outcome." not in WORKING_STYLE_PROMPT
73
+
59
74
  def test_build_session_directive_returns_the_shared_constant(self) -> None:
60
75
  assert starter.build_session_directive() == WORKING_STYLE_PROMPT
@@ -4,8 +4,9 @@
4
4
  At session start this hook emits an ``additionalContext`` block carrying a fixed
5
5
  working-style prompt: use ELI5 for the beginner presentation envelope, follow
6
6
  ``~/.claude/rules/asd-ste100-language.md`` for sentence prose, keep a running
7
- ledger, narrate before the first tool call, lead with the outcome, and stay at
8
- the asked scope.
7
+ ledger, narrate before the first tool call on a typed request, lead with the
8
+ outcome, send only what the user must act on or know, stay silent on a
9
+ background-event turn that needs nothing, and stay at the asked scope.
9
10
  The hook writes nothing and runs no tools itself.
10
11
  """
11
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.30.0",
3
+ "version": "8.31.0",
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""')