openclacky 1.0.0.beta.1 → 1.0.0.beta.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0938f51d788566d1c708a0054a3b45565f0f3b2ea7cd68f9e18897247c745cd
4
- data.tar.gz: 96bef1e4b6333fcee57e26fb330f12d7d5b9f79f470a34f35483ab5f51571e64
3
+ metadata.gz: a6a51d00de51f04f142d6be7e3e726561384752ca02f44a6971eeaad9c2cdb28
4
+ data.tar.gz: 185e635750793082206332377649095313b62297a2bd2f9f0b825a523a499afb
5
5
  SHA512:
6
- metadata.gz: 59ba5927fef6187d4d862f210282190b589838e4950b0a5bf0e37731e6cd772bba0d4bfd483d6ff14f979eabf7a4dc09abacb2c60f98df7762af6b4191dc67cf
7
- data.tar.gz: 52063a91b64281d4dcf3e6bd8e3f4d87cc63cfed70169c87cfacf55e4f6c1cb16f2d938a9f554f564829e879755573d3eb8fb3988260285d11087dfa0058473d
6
+ metadata.gz: 66e14242f2d4b0e049fd45283c77c71919614d5f2ef8558b8635318f443afd41ab3ebf941a3b10a22c987805569082f699683af5eae23f5ef54e6dbd993e4931
7
+ data.tar.gz: 4734d321c296e168f505185e67bddf8967687fd4889871a9a148f8bc003a7bb866774eb4f8c15ab4aba8b27384ae28e1c436477b3dd65e898c90743b393dbfb9
@@ -3,7 +3,9 @@
3
3
  name: gem-release
4
4
  description: >-
5
5
  Automates the complete process of releasing a new version of the openclacky Ruby
6
- gem
6
+ gem. Supports both stable releases (auto-increment) and pre-release versions
7
+ (user-specified, e.g., 1.0.0.beta.1). Handles version bumping, testing, building,
8
+ RubyGems publishing, GitHub Releases, and OSS CDN mirroring.
7
9
  disable-model-invocation: false
8
10
  user-invocable: true
9
11
  ---
@@ -21,6 +23,7 @@ This skill handles the entire gem release workflow from version bumping to publi
21
23
  To use this skill, simply say:
22
24
  - "Release a new version"
23
25
  - "Publish a new gem version"
26
+ - "Release version 1.0.0.beta.1" (pre-release with explicit version)
24
27
  - Use the command: `/gem-release`
25
28
 
26
29
  ## Process Steps
@@ -31,10 +34,30 @@ To use this skill, simply say:
31
34
  - Ensure the repository is in a clean state
32
35
 
33
36
  ### 2. Version Management
37
+
38
+ **Stable releases (default):**
34
39
  - Read current version from `lib/clacky/version.rb`
35
40
  - Increment version number (typically patch version: x.y.z → x.y.z+1)
36
41
  - Update the VERSION constant in the version file
37
42
 
43
+ **Pre-release versions (when user specifies a version like `1.0.0.beta.1`):**
44
+ - Accept the user-provided version string directly — do NOT auto-increment
45
+ - The version must follow semver pre-release format: `X.Y.Z-<identifier>` or `X.Y.Z.<identifier>` (e.g., `1.0.0.beta.1`, `2.0.0-alpha`, `1.5.0-rc1`)
46
+ - Before proceeding, warn the user about pre-release caveats (see Pre-Release Caveats below)
47
+
48
+ ### 2a. Pre-Release Caveats
49
+
50
+ When releasing a pre-release version, inform the user of these known behaviors in the Clacky ecosystem:
51
+
52
+ | Concern | Behavior | Impact |
53
+ |---------|----------|--------|
54
+ | **Version check notification** | RubyGems API returns the highest version number, including prereleases. `Gem::Version("0.9.38") < Gem::Version("1.0.0.beta.1")` → `true`. | ✅ The upgrade dot WILL appear in the Web UI for most users. |
55
+ | **`gem update` (official source)** | `gem update openclacky --no-document` does NOT install prereleases without `--pre`. | ❌ Users on official RubyGems source who click "Upgrade" will see the notification but the upgrade will silently do nothing. |
56
+ | **OSS CDN upgrade (mirror users)** | `upgrade_via_oss_cdn` downloads the exact `.gem` from `latest.txt` on OSS. | ⚠️ If you update `latest.txt` to point to the prerelease, mirror users WILL get the beta. |
57
+ | **OSS `latest.txt`** | Stable users fetching `latest.txt` for fresh installs would get the beta. | ⚠️ By default, do NOT update `latest.txt` for pre-releases. Only update if this is intentional (e.g., a release candidate for broad testing). |
58
+
59
+ **Action**: Ask the user whether to update `latest.txt` on OSS before proceeding. For internal testing, the answer is usually "no".
60
+
38
61
  ### 3. Quality Assurance
39
62
  - Run the full test suite with `bundle exec rspec`
40
63
  - Ensure all 167+ tests pass
@@ -93,15 +116,26 @@ To use this skill, simply say:
93
116
 
94
117
  4. **Create GitHub Release and Upload gem**
95
118
 
96
- Extract the release notes for this version from CHANGELOG.md, then create a GitHub Release with the .gem file attached:
119
+ Extract the release notes for this version from CHANGELOG.md, then create a GitHub Release with the .gem file attached.
120
+
121
+ **For stable releases:**
97
122
  ```bash
98
123
  gh release create v{version} \
99
124
  --title "v{version}" \
100
- --notes-file /tmp/release_notes.md \
125
+ --notes-file /tmp/release_notes_{version}.md \
101
126
  --latest \
102
127
  openclacky-{version}.gem
103
128
  ```
104
129
 
130
+ **For pre-release versions (e.g., `1.0.0.beta.1`):** use `--prerelease` instead of `--latest`:
131
+ ```bash
132
+ gh release create v{version} \
133
+ --title "v{version}" \
134
+ --notes-file /tmp/release_notes_{version}.md \
135
+ --prerelease \
136
+ openclacky-{version}.gem
137
+ ```
138
+
105
139
  Steps:
106
140
  - Parse the CHANGELOG.md section for `[{version}]`
107
141
  - Write it to a temp file (e.g., `/tmp/release_notes_{version}.md`) to avoid shell escaping issues
@@ -112,22 +146,28 @@ To use this skill, simply say:
112
146
 
113
147
  5. **Sync to Tencent Cloud OSS (CN mirror)**
114
148
 
115
- After GitHub Release is created, upload the .gem file and update `latest.txt` on OSS so Chinese users can install without hitting GitHub directly:
149
+ After GitHub Release is created, upload the .gem file to OSS so Chinese users can install without hitting GitHub directly.
116
150
 
117
151
  ```bash
118
- # Upload .gem file
152
+ # Upload .gem file (always do this for any release)
119
153
  coscli cp openclacky-{version}.gem cos://clackyai-1258723534/openclacky/openclacky-{version}.gem
154
+ ```
120
155
 
121
- # Update latest.txt
156
+ **For stable releases only** — update `latest.txt` so fresh installs and mirror users pick up the new version:
157
+ ```bash
122
158
  echo "{version}" > /tmp/latest.txt
123
159
  coscli cp /tmp/latest.txt cos://clackyai-1258723534/openclacky/latest.txt
124
160
 
125
161
  # Verify
126
162
  curl -fsSL https://oss.1024code.com/openclacky/latest.txt
127
163
  ```
128
-
129
164
  Expected output of verify: `{version}`
130
165
 
166
+ **For pre-release versions** — do NOT update `latest.txt` unless the user explicitly requested it. Updating `latest.txt` to a prerelease would cause:
167
+ - Mirror users clicking "Upgrade" to get the beta via `upgrade_via_oss_cdn`
168
+ - Fresh installs via the install script to get the beta
169
+ - Only skip this if the user explicitly wants broad beta distribution
170
+
131
171
  > **Prerequisite**: `coscli` installed at `/usr/local/bin/coscli` and configured at `~/.cos.yaml`
132
172
 
133
173
  6. **Sync scripts/ to OSS**
@@ -325,22 +365,34 @@ git tag vX.Y.Z
325
365
  git push origin main
326
366
  git push origin --tags
327
367
 
328
- # Create GitHub Release with .gem asset (requires gh CLI)
329
- # 1. Extract release notes from CHANGELOG.md for this version
330
- # 2. Write to temp file to avoid shell escaping issues
331
- # 3. Create the release and attach .gem file
368
+ # ── GitHub Release ──────────────────────────────────────────────────────
369
+
370
+ # Stable release:
332
371
  gh release create vX.Y.Z \
333
372
  --title "vX.Y.Z" \
334
373
  --notes-file /tmp/release_notes_X.Y.Z.md \
335
374
  --latest \
336
375
  openclacky-X.Y.Z.gem
337
376
 
338
- # Sync to Tencent Cloud OSS (CN mirror)
377
+ # Pre-release (use --prerelease instead of --latest):
378
+ gh release create vX.Y.Z-beta.1 \
379
+ --title "vX.Y.Z-beta.1" \
380
+ --notes-file /tmp/release_notes_X.Y.Z-beta.1.md \
381
+ --prerelease \
382
+ openclacky-X.Y.Z.beta.1.gem
383
+
384
+ # ── OSS CDN (CN mirror) ─────────────────────────────────────────────────
385
+
386
+ # Always upload the .gem file:
339
387
  coscli cp openclacky-X.Y.Z.gem cos://clackyai-1258723534/openclacky/openclacky-X.Y.Z.gem
388
+
389
+ # Stable releases ONLY — update latest.txt:
340
390
  echo "X.Y.Z" > /tmp/latest.txt
341
391
  coscli cp /tmp/latest.txt cos://clackyai-1258723534/openclacky/latest.txt
342
392
  curl -fsSL https://oss.1024code.com/openclacky/latest.txt # verify
343
393
 
394
+ # Pre-releases — skip latest.txt update unless user explicitly requests it
395
+
344
396
  # Sync scripts/ to OSS (build from templates first)
345
397
  bash scripts/build/build.sh
346
398
  for script in scripts/*; do
@@ -365,8 +417,10 @@ curl -fsSL https://oss.1024code.com/clacky-ai/openclacky/main/scripts/install.sh
365
417
  - Git repository updated with version tag
366
418
  - CHANGELOG.md updated with release notes
367
419
  - GitHub Release created with .gem file attached at https://github.com/clacky-ai/openclacky/releases
420
+ - Use `--latest` for stable releases, `--prerelease` for pre-releases
368
421
  - .gem file uploaded to OSS: https://oss.1024code.com/openclacky/openclacky-{version}.gem
369
- - latest.txt updated on OSS: https://oss.1024code.com/openclacky/latest.txt returns the new version
422
+ - For stable releases: `latest.txt` updated on OSS: https://oss.1024code.com/openclacky/latest.txt returns the new version
423
+ - For pre-releases: `latest.txt` NOT updated (unless user explicitly opts in)
370
424
  - No build or deployment errors
371
425
  - User-facing release summary presented at the end
372
426
 
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.0.beta.2] - 2026-04-27
11
+
12
+ ### Added
13
+ - **New session creation supports model & working-directory options.** The Web UI "new session" dialog now lets you pick the model and starting directory up front, instead of having to adjust them after the session opens.
14
+
15
+ ### Fixed
16
+ - **System prompt now refreshes when you switch models.** Previously the system prompt captured at session start stuck around even after `/model` or `/provider` switches, which could leave model-specific instructions out of sync. The agent now re-injects the correct system prompt on every model change.
17
+ - **Port 7070 properly released when the terminal tool exits.** A lingering listener on port 7070 could block subsequent runs; the terminal tool now cleans it up on shutdown.
18
+ - **Windows installer uses `[IO.Path]::GetTempPath()` for the temp directory** (#58) — more reliable than `$env:TEMP` on systems where the env var is unset or points to a non-ASCII path.
19
+
10
20
  ## [1.0.0.beta.1] - 2026-04-26
11
21
 
12
22
  ### Added
data/lib/clacky/agent.rb CHANGED
@@ -1371,7 +1371,19 @@ module Clacky
1371
1371
  # Core method to inject session context (date, model, OS, paths).
1372
1372
  # Called by inject_session_context_if_needed (with date check)
1373
1373
  # and by switch_model (without date check, to force update).
1374
+ #
1375
+ # IMPORTANT: Skip injection when the system prompt hasn't been built yet.
1376
+ # Otherwise, appending a user message to an empty history makes
1377
+ # @history.empty? false, which causes run() to skip building the
1378
+ # system prompt entirely (see run()'s "first run" guard).
1379
+ # The injection will happen naturally in run() via
1380
+ # inject_session_context_if_needed after the system prompt is in place.
1374
1381
  private def inject_session_context
1382
+ # Don't inject context before system prompt exists — defer to
1383
+ # inject_session_context_if_needed which runs inside run()
1384
+ # after the system prompt has been built.
1385
+ return unless @history.has_system_prompt?
1386
+
1375
1387
  today = Time.now.strftime("%Y-%m-%d")
1376
1388
  os = Clacky::Utils::EnvironmentDetector.os_type
1377
1389
  desktop = Clacky::Utils::EnvironmentDetector.desktop_path
@@ -100,6 +100,14 @@ module Clacky
100
100
  # Business queries
101
101
  # ─────────────────────────────────────────────
102
102
 
103
+ # True when a system prompt message is present in the history.
104
+ # Used by inject_session_context to avoid injecting context messages
105
+ # before the system prompt has been built (which would cause the
106
+ # guard in run() to skip building it altogether).
107
+ def has_system_prompt?
108
+ @messages.any? { |m| m[:role] == "system" }
109
+ end
110
+
103
111
  # True when the last assistant message has tool_calls but no
104
112
  # tool_result has been appended yet (would cause a 400 from the API).
105
113
  def pending_tool_calls?
@@ -501,15 +501,25 @@ module Clacky
501
501
  raw_dir = body["working_dir"].to_s.strip
502
502
  working_dir = raw_dir.empty? ? default_working_dir : File.expand_path(raw_dir)
503
503
 
504
- # Optional model override
505
- model_override = body["model"].to_s.strip
506
- model_override = nil if model_override.empty?
504
+ # Optional model override — passed as a stable model id (matches the
505
+ # id returned by GET /api/config). Name-based override was removed:
506
+ # a bare model name can't disambiguate between entries from different
507
+ # providers (e.g. "deepseek-v4-pro" on DeepSeek direct vs its dsk-*
508
+ # alias on OpenClacky/Bedrock), and mutating current_model["model"]
509
+ # kept the wrong api_key / base_url / api format, producing
510
+ # "unknown model" errors at the provider.
511
+ model_id_override = body["model_id"].to_s.strip
512
+ model_id_override = nil if model_id_override.empty?
513
+
514
+ if model_id_override && !@agent_config.models.any? { |m| m["id"] == model_id_override }
515
+ return json_response(res, 400, { error: "Model not found in configuration" })
516
+ end
507
517
 
508
518
  # Create working directory if it doesn't exist
509
519
  # Allow multiple sessions in the same directory
510
520
  FileUtils.mkdir_p(working_dir)
511
521
 
512
- session_id = build_session(name: name, working_dir: working_dir, profile: profile, source: source, model_override: model_override)
522
+ session_id = build_session(name: name, working_dir: working_dir, profile: profile, source: source, model_id: model_id_override)
513
523
  broadcast_session_update(session_id)
514
524
  json_response(res, 201, { session: @registry.session_summary(session_id) })
515
525
  end
@@ -2662,19 +2672,38 @@ module Clacky
2662
2672
  # @param working_dir [String] working directory for the agent
2663
2673
  # @param permission_mode [Symbol] :confirm_all (default, human present) or
2664
2674
  # :auto_approve (unattended — suppresses request_user_feedback waits)
2665
- def build_session(name:, working_dir:, permission_mode: :confirm_all, profile: "general", source: :manual, model_override: nil)
2675
+ def build_session(name:, working_dir:, permission_mode: :confirm_all, profile: "general", source: :manual, model_id: nil)
2666
2676
  session_id = Clacky::SessionManager.generate_id
2667
2677
  @registry.create(session_id: session_id)
2668
2678
 
2669
- client = @client_factory.call
2670
2679
  config = @agent_config.deep_copy
2671
2680
  config.permission_mode = permission_mode
2672
-
2673
- # Apply model override if provided
2674
- if model_override && config.current_model
2675
- config.current_model["model"] = model_override
2676
- end
2677
-
2681
+
2682
+ # Apply model override BEFORE creating the client — otherwise the
2683
+ # client is built from the default model entry and may route through
2684
+ # the wrong provider (e.g. sending a deepseek-v4-pro request to the
2685
+ # Bedrock-format OpenClacky endpoint, which replies "unknown model").
2686
+ #
2687
+ # We use switch_model_by_id (not a name-based rewrite of
2688
+ # current_model["model"]) because:
2689
+ # 1. Ids uniquely identify an entry across providers; names can
2690
+ # collide between entries (deepseek vs dsk-deepseek aliases).
2691
+ # 2. switch_model_by_id only flips per-session @current_model_id
2692
+ # in the dup'd config — it never mutates the shared @models
2693
+ # array (see AgentConfig#deep_copy's shared-ref contract).
2694
+ # A name rewrite would have leaked into every live session
2695
+ # AND corrupted the on-disk config at next save.
2696
+ config.switch_model_by_id(model_id) if model_id
2697
+
2698
+ # Build client from the (possibly overridden) config so api format
2699
+ # detection (Bedrock vs OpenAI vs Anthropic) uses the correct model.
2700
+ client = Clacky::Client.new(
2701
+ config.api_key,
2702
+ base_url: config.base_url,
2703
+ model: config.model_name,
2704
+ anthropic_format: config.anthropic_format?
2705
+ )
2706
+
2678
2707
  broadcaster = method(:broadcast)
2679
2708
  ui = WebUIController.new(session_id, broadcaster)
2680
2709
  agent = Clacky::Agent.new(client, config, working_dir: working_dir, ui: ui, profile: profile,
@@ -621,12 +621,39 @@ module Clacky
621
621
  log_file = SessionManager.allocate_log_file
622
622
  log_io = File.open(log_file, "wb")
623
623
 
624
+ # Prevent the child process from inheriting the server's
625
+ # listening socket (port 7070) which would block hot_restart.
626
+ # PTY.spawn does not support close_others, so we temporarily
627
+ # set close_on_exec on the inherited fd — the kernel closes
628
+ # it in the child after exec while the parent keeps it open.
629
+ inherited_fd = ENV["CLACKY_INHERIT_FD"].to_i
630
+ if inherited_fd > 0
631
+ begin
632
+ inherited_io = IO.for_fd(inherited_fd)
633
+ inherited_io.autoclose = false
634
+ was_cloexec = inherited_io.close_on_exec?
635
+ inherited_io.close_on_exec = true
636
+ rescue StandardError
637
+ inherited_fd = 0
638
+ end
639
+ end
640
+
624
641
  reader, writer, pid = PTY.spawn(
625
642
  spawn_env, *args, chdir_args(cwd)
626
643
  )
627
644
  reader.sync = true
628
645
  writer.sync = true
629
646
 
647
+ # Restore original close_on_exec flag on the parent's fd so the
648
+ # server can continue accepting connections after hot_restart.
649
+ if inherited_fd > 0
650
+ begin
651
+ inherited_io.close_on_exec = was_cloexec
652
+ rescue StandardError
653
+ # best-effort
654
+ end
655
+ end
656
+
630
657
  begin
631
658
  writer.winsize = [40, 120]
632
659
  rescue StandardError
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clacky
4
- VERSION = "1.0.0.beta.1"
4
+ VERSION = "1.0.0.beta.2"
5
5
  end
@@ -2153,7 +2153,13 @@ const Sessions = (() => {
2153
2153
 
2154
2154
  const agentProfile = agentSelect ? agentSelect.value : "general";
2155
2155
  const customName = nameInput ? nameInput.value.trim() : "";
2156
- const selectedModel = modelSelect ? modelSelect.value : "";
2156
+ // The dropdown's value is the model's stable runtime id (see
2157
+ // _populateModelDropdown). Using the id — not the model *name* — lets
2158
+ // the backend switch to the right full model entry (api_key, base_url,
2159
+ // anthropic_format) instead of mutating the current default entry's
2160
+ // name in place, which caused "unknown model <name>" errors when the
2161
+ // chosen model belonged to a different provider than the default.
2162
+ const selectedModelId = modelSelect ? modelSelect.value : "";
2157
2163
  const workingDir = dirInput ? dirInput.value.trim() : "";
2158
2164
  const initProject = initCheckbox ? initCheckbox.checked : false;
2159
2165
 
@@ -2178,7 +2184,7 @@ const Sessions = (() => {
2178
2184
 
2179
2185
  // Add optional fields
2180
2186
  if (workingDir) payload.working_dir = workingDir;
2181
- if (selectedModel) payload.model = selectedModel;
2187
+ if (selectedModelId) payload.model_id = selectedModelId;
2182
2188
 
2183
2189
  const res = await fetch("/api/sessions", {
2184
2190
  method: "POST",
@@ -2244,16 +2250,20 @@ const Sessions = (() => {
2244
2250
  return;
2245
2251
  }
2246
2252
 
2247
- // Add each configured model (CLI-style format)
2253
+ // Add each configured model (CLI-style format).
2254
+ // The option's value is the model's stable runtime id — not the bare
2255
+ // model name — so the backend can switch to the exact model entry
2256
+ // (with matching api_key / base_url / anthropic_format) when the user
2257
+ // chooses a non-default model. See createFromModal + build_session.
2248
2258
  models.forEach(m => {
2249
2259
  const opt = document.createElement("option");
2250
- opt.value = m.model || "";
2251
-
2260
+ opt.value = m.id || "";
2261
+
2252
2262
  // Format: [default] abs-claude-sonnet-4-5 (clacky...8825)
2253
2263
  const typeBadge = m.type === "default" ? "[default] " : "";
2254
2264
  const label = `${typeBadge}${m.model} (${m.api_key_masked})`;
2255
2265
  opt.textContent = label;
2256
-
2266
+
2257
2267
  // Pre-select default model
2258
2268
  if (m.type === "default") opt.selected = true;
2259
2269
  modelSelect.appendChild(opt);
data/scripts/install.ps1 CHANGED
@@ -57,6 +57,16 @@ function Test-IsAdmin {
57
57
  [Security.Principal.WindowsBuiltInRole]::Administrator)
58
58
  }
59
59
 
60
+ function Get-SafeTempDir {
61
+ # Use [IO.Path]::GetTempPath() instead of $env:TEMP.
62
+ # $env:TEMP can return a short (8.3) path (e.g. C:\Users\USERNA~1\AppData\Local\Temp)
63
+ # on systems where the user profile path contains spaces or non-ASCII characters,
64
+ # which can break tools that don't handle 8.3 names correctly.
65
+ # [IO.Path]::GetTempPath() always returns the full long path.
66
+ $tempDir = [IO.Path]::GetTempPath().TrimEnd("\", "/")
67
+ return $tempDir
68
+ }
69
+
60
70
  # Robust file download: try curl first (shows progress), fall back to
61
71
  # Invoke-WebRequest. Returns $true on success, $false on failure.
62
72
  function Invoke-Download {
@@ -79,7 +89,8 @@ function Invoke-Download {
79
89
  # Returns $true on match, or if the checksum file cannot be fetched (non-fatal).
80
90
  function Test-Sha256 {
81
91
  param([string]$FilePath, [string]$Sha256Url)
82
- $sha256File = "$env:TEMP\download.sha256"
92
+ $safeTemp = Get-SafeTempDir
93
+ $sha256File = "$safeTemp\download.sha256"
83
94
  try {
84
95
  if (-not (Invoke-Download -Url $Sha256Url -OutFile $sha256File)) {
85
96
  Write-Warn "Could not download checksum file — skipping verification."
@@ -178,7 +189,8 @@ function Install-UbuntuRootfs {
178
189
  $sha256Url = $UBUNTU_WSL_AMD64_SHA256_URL
179
190
  }
180
191
 
181
- $tarPath = "$env:TEMP\ubuntu-wsl-$cpuArch.tar.gz"
192
+ $safeTemp = Get-SafeTempDir
193
+ $tarPath = "$safeTemp\ubuntu-wsl-$cpuArch.tar.gz"
182
194
  $installDir = $UBUNTU_WSL_DIR
183
195
 
184
196
  # Disk space check (~2 GB needed: 350 MB download + ~1.5 GB imported)
@@ -324,8 +336,10 @@ function Test-VirtualisationSupported {
324
336
  # Probe WSL2 with a minimal tar (512 zero bytes = valid tar EOF block)
325
337
  # Called only after WSL feature is confirmed enabled (Main already checked).
326
338
  Write-Info "Probing WSL2 availability..."
327
- $probeTar = "$env:TEMP\wsl_probe.tar"
328
- $probeDir = "$env:TEMP\wsl_probe"
339
+
340
+ $safeTemp = Get-SafeTempDir
341
+ $probeTar = "$safeTemp\wsl_probe.tar"
342
+ $probeDir = "$safeTemp\wsl_probe"
329
343
  $ok = $false
330
344
  try {
331
345
  $bytes = New-Object byte[] 512
@@ -369,7 +383,8 @@ function Install-WslKernel {
369
383
  $url = $WSL_UPDATE_URL_X64
370
384
  }
371
385
 
372
- $msiPath = "$env:TEMP\wsl_update.msi"
386
+ $safeTemp = Get-SafeTempDir
387
+ $msiPath = "$safeTemp\wsl_update.msi"
373
388
  Write-Step "Downloading WSL kernel update ($cpuArch)..."
374
389
  if (-not (Invoke-Download -Url $url -OutFile $msiPath)) {
375
390
  Write-Fail "Failed to download WSL kernel update. Check your network and try again."
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openclacky
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta.1
4
+ version: 1.0.0.beta.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - windy