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 +4 -4
- data/.clacky/skills/gem-release/SKILL.md +67 -13
- data/CHANGELOG.md +10 -0
- data/lib/clacky/agent.rb +12 -0
- data/lib/clacky/message_history.rb +8 -0
- data/lib/clacky/server/http_server.rb +41 -12
- data/lib/clacky/tools/terminal.rb +27 -0
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/sessions.js +16 -6
- data/scripts/install.ps1 +20 -5
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a6a51d00de51f04f142d6be7e3e726561384752ca02f44a6971eeaad9c2cdb28
|
|
4
|
+
data.tar.gz: 185e635750793082206332377649095313b62297a2bd2f9f0b825a523a499afb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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/
|
|
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
|
|
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
|
-
|
|
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
|
-
#
|
|
329
|
-
|
|
330
|
-
#
|
|
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
|
-
#
|
|
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
|
-
|
|
506
|
-
|
|
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,
|
|
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,
|
|
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
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
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
|
data/lib/clacky/version.rb
CHANGED
data/lib/clacky/web/sessions.js
CHANGED
|
@@ -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
|
-
|
|
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 (
|
|
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.
|
|
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
|
-
$
|
|
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
|
-
$
|
|
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
|
-
|
|
328
|
-
$
|
|
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
|
-
$
|
|
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."
|