codex-ringside 0.3.0 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1 (2026-11-03)
4
+
5
+ - Bundle a wallpaper and background preset for fresh installations (cover, 134% zoom, top-left alignment, zero transparency and blur). Preserve existing images, edits and disabled backgrounds on upgrades, reinstalls and Codex Plus migrations.
6
+ - Verify preset inclusion in npm packages and standalone bundles, real image preparation, settings preservation and failed-install rollback.
7
+
3
8
  ## 0.3.0 (2026-11-03)
4
9
 
5
10
  - Replace the native sidebar usage icon with Ringside meters in place, preserving its usage menu, management actions and keyboard controls. Restore the native icon when the add-on is removed.
package/README.md CHANGED
@@ -104,6 +104,8 @@ Reinstalling preserves observe mode; `--observe` explicitly disables startup han
104
104
 
105
105
  ## Background controls
106
106
 
107
+ A fresh installation automatically applies the bundled wallpaper: image source, cover layout, 134% zoom, top-left alignment, zero transparency and blur, 100% brightness/contrast/saturation, and no crop. The image is stored inside the add-on's directory; no separate download or file selection is needed. Upgrades, reinstalls and Codex Plus migrations preserve existing images and settings, including leaving backgrounds off for users who never enabled them. You can change the image, adjust the controls or turn the background off at any time. Framing varies with window proportions; the client's light/dark appearance setting is preserved.
108
+
107
109
  Click a ring, or press Enter or Space while focused, to open background settings. The hover details' background settings button, right-click and Shift+F10 also work. Open the native usage menu through the separate button in the hover details or ArrowDown while the ring is focused; this entry is hidden on clients without a compatible native usage button. Panel changes apply immediately; CLI changes apply within five seconds.
108
110
 
109
111
  | Source | Behavior |
package/README.zh-CN.md CHANGED
@@ -113,6 +113,8 @@ npx codex-ringside@latest install
113
113
 
114
114
  ## 自定义背景
115
115
 
116
+ 首次安装会自动应用安装包内置的壁纸:图片来源、铺满布局、缩放 134%、左上对齐、透明度和模糊均为 0,亮度、对比度和饱和度均为 100%,不裁剪。图片保存在插件自己的目录内,无需另行下载或选择。升级、重装和从 Codex Plus 迁移都会保留已有图片和设置;之前未启用背景的用户也会继续保持关闭。可随时在面板中换图、调整参数或选择“关闭”。窗口比例不同会影响取景,客户端的浅色/深色模式保持用户自己的选择。
117
+
116
118
  直接点击侧栏圆环打开原有背景设置面板,聚焦后按 Enter 或空格也可以打开。悬停面板中的“背景设置”、右键和 Shift+F10 仍可使用。官方用量菜单通过悬停面板中的“用量菜单”打开,也可以聚焦圆环后按向下键;没有兼容的官方按钮时,这个菜单入口隐藏。先选来源,再用效果调外观,所有调节都立即生效。
117
119
 
118
120
  面板顶部还能切换 Codex 的**外观模式**:跟随系统、浅色、深色。它和设置页的“模式”是同一个设置,改动会保存,并在两边同步。这里用的是 Codex 内部的设置函数,找不到时控件自动隐藏。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-ringside",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Usage rings and customizable backgrounds for the Codex desktop app. Unofficial macOS add-on.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -49,6 +49,8 @@
49
49
  "bin/*.cjs",
50
50
  "src/**/*.cjs",
51
51
  "src/**/*.js",
52
+ "src/presets/default-background.json",
53
+ "src/presets/wallpaper.png",
52
54
  "native/bridge.swift",
53
55
  "README*.md",
54
56
  "LICENSE",
package/src/install.cjs CHANGED
@@ -6,6 +6,7 @@ const { execFileSync } = require('node:child_process');
6
6
  const launchd = require('./launchd.cjs');
7
7
  const { DEFAULT_APP, isExecutable, resolveCodexBin, resolveNode } = require('./resolve.cjs');
8
8
  const { inspectBundle, copyBundle } = require('./standalone.cjs');
9
+ const { normalizeBackground } = require('./background.cjs');
9
10
 
10
11
  const SWIFTC = '/usr/bin/swiftc';
11
12
  const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
@@ -116,7 +117,8 @@ function copyUserData(source, stage, destination) {
116
117
  if (typeof config?.image === 'string') {
117
118
  const relative = path.relative(source, config.image);
118
119
  if (relative && !relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative)) {
119
- const name = path.join('user-images', `imported${path.extname(config.image)}`);
120
+ const name = relative.startsWith(`user-images${path.sep}`)
121
+ ? relative : path.join('user-images', `imported${path.extname(config.image)}`);
120
122
  copyIfPresent(config.image, path.join(stage, name));
121
123
  config.image = path.join(destination, name);
122
124
  writeJson(file, config);
@@ -124,6 +126,16 @@ function copyUserData(source, stage, destination) {
124
126
  }
125
127
  }
126
128
 
129
+ function seedBackground(stage, destination) {
130
+ const presets = path.join(stage, 'src/presets');
131
+ const preset = readJson(path.join(presets, 'default-background.json'));
132
+ if (preset?.source !== 'image' || preset.image !== 'wallpaper.png') throw new Error('安装包缺少有效的默认背景预设');
133
+ const image = path.join('user-images', 'default-background.png');
134
+ fs.mkdirSync(path.join(stage, 'user-images'), { recursive: true, mode: 0o700 });
135
+ fs.copyFileSync(path.join(presets, preset.image), path.join(stage, image));
136
+ writeJson(path.join(stage, 'background.json'), normalizeBackground({ ...preset, image: path.join(destination, image) }));
137
+ }
138
+
127
139
  async function install(options = {}) {
128
140
  const { current, legacy, backupRoot, repoRoot, services } = { ...defaults, ...options };
129
141
  return withLock(current, async () => {
@@ -146,6 +158,9 @@ async function install(options = {}) {
146
158
  for (const name of ['package.json', 'LICENSE', 'NOTICE']) fs.copyFileSync(path.join(repoRoot, name), path.join(stage, name));
147
159
  if (checked.bundle) copyBundle(repoRoot, stage);
148
160
  else await (options.compile ?? compile)(repoRoot, stage);
161
+ // Older installations may have no background.json because they never enabled a background.
162
+ // Only a genuinely new install gets the preset; upgrading must retain that implicit opt-out.
163
+ if (!locations.some(location => fs.existsSync(location.installDir))) seedBackground(stage, current.installDir);
149
164
  options.beforeInstall?.();
150
165
  fs.mkdirSync(backupRoot, { recursive: true, mode: 0o700 });
151
166
  backup = fs.mkdtempSync(path.join(backupRoot, 'install-'));
@@ -156,7 +171,8 @@ async function install(options = {}) {
156
171
  for (const location of locations) await services.bootout(location.label);
157
172
 
158
173
  // Copy after stopping writers. Existing Ringside data takes precedence over legacy data.
159
- const dataRoot = fs.existsSync(path.join(current.installDir, 'settings.json')) ? current.installDir : legacy.installDir;
174
+ const hasCurrentData = ['settings.json', 'background.json'].some(name => fs.existsSync(path.join(current.installDir, name)));
175
+ const dataRoot = hasCurrentData ? current.installDir : legacy.installDir;
160
176
  copyUserData(dataRoot, stage, current.installDir);
161
177
  const cooldown = Math.max(...locations.map(location => {
162
178
  const value = readJson(path.join(location.installDir, 'state.json'))?.lastAttemptAt;
@@ -0,0 +1,14 @@
1
+ {
2
+ "source": "image",
3
+ "image": "wallpaper.png",
4
+ "transparency": 0,
5
+ "blur": 0,
6
+ "zoom": 134,
7
+ "x": 0,
8
+ "y": 0,
9
+ "brightness": 100,
10
+ "contrast": 100,
11
+ "saturation": 100,
12
+ "layout": "cover",
13
+ "crop": null
14
+ }
Binary file