@ailuntz/minilink 0.9.5 → 0.9.6

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/README.md CHANGED
@@ -37,7 +37,7 @@ npm 11 默认可能跳过全局包的安装脚本;上面的单次许可让 Min
37
37
 
38
38
  通过 `minilink link` 保存选择后,完全退出并重开 Desktop。
39
39
 
40
- macOS 上 `off` 会让后续启动直接使用 Desktop 自带的 Codex;`on` 会重新接入 MiniLink。已打开的 Desktop 需要完全退出并重开,才会切换启动方式。MiniLink 会在每次启动时重新查找 Desktop 自带的 Codex,兼容旧版 `Resources/codex` 和新版 `Resources/codex-cli/bin/codex` 布局。
40
+ macOS 上 `off` 会让后续启动直接使用 Desktop 自带的 Codex;`on` 会重新接入 MiniLink。已打开的 Desktop 需要完全退出并重开,才会切换启动方式。MiniLink 使用 ChatGPT 当前内置的 `Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex`。
41
41
 
42
42
  ## 配置
43
43
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ailuntz/minilink",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Use your Codex profiles in the Desktop model menu.",
5
5
  "type": "module",
6
6
  "license": "MIT AND Apache-2.0",
package/src/config.mjs CHANGED
@@ -63,22 +63,12 @@ export function discoverProfiles(home = codexHome()) {
63
63
  return routes;
64
64
  }
65
65
 
66
- export const bundledCodexPaths = [
67
- 'codex-cli/bin/codex',
68
- 'codex-cli/CodexCLI.app/Contents/MacOS/codex',
69
- 'codex'
70
- ];
71
-
72
- export function bundledCodex(app) {
73
- for (const relative of bundledCodexPaths) {
74
- const candidate = join(app, 'Contents/Resources', relative);
75
- try { accessSync(candidate, constants.X_OK); return candidate; } catch {}
76
- }
77
- return null;
78
- }
66
+ export const bundledCodexRelativePath = 'Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex';
67
+ export const bundledCodex = app => join(app, bundledCodexRelativePath);
79
68
 
80
69
  export function findApp() {
81
- return [process.env.CODEX_DESKTOP_APP, '/Applications/ChatGPT.app', '/Applications/Codex.app', join(homedir(), 'Applications/ChatGPT.app'), join(homedir(), 'Applications/Codex.app')].filter(Boolean).find(p => bundledCodex(p));
70
+ const app = process.env.CODEX_DESKTOP_APP || '/Applications/ChatGPT.app';
71
+ try { accessSync(bundledCodex(app), constants.X_OK); return app; } catch { return null; }
82
72
  }
83
73
 
84
74
  export function resolveRealCodex(selfPath) {
package/src/install.mjs CHANGED
@@ -5,7 +5,7 @@ import { execFileSync } from 'node:child_process';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { activeRuns } from './runtime.mjs';
7
7
  import { legacyInstallation } from './legacy.mjs';
8
- import { atomicJSON, configPath, codexHome, resolveRealCodex, readConfig, bundledCodexPaths } from './config.mjs';
8
+ import { atomicJSON, configPath, codexHome, readConfig, bundledCodexRelativePath } from './config.mjs';
9
9
 
10
10
  const label = 'com.ailuntz.minilink';
11
11
  export const installRoot = () => join(homedir(), '.local/share/minilink');
@@ -42,7 +42,7 @@ function atomicFile(path, text, mode) {
42
42
 
43
43
  // Each installation has its own files: active Desktop processes keep their
44
44
  // original modules and picker assets while the next launch uses the new copy.
45
- export function install({ root = installRoot(), plist = defaultPlist(), source = sourceRoot, home = codexHome(), config = configPath(), node = process.execPath, npm = process.env.npm_execpath, prefix = process.env.npm_config_prefix, run = launchctl, legacy = root === installRoot() ? legacyInstallation() : null, realCodex = resolveRealCodex(join(source, 'bin/minilink.mjs')) } = {}) {
45
+ export function install({ root = installRoot(), plist = defaultPlist(), source = sourceRoot, home = codexHome(), config = configPath(), node = process.execPath, npm = process.env.npm_execpath, prefix = process.env.npm_config_prefix, run = launchctl, legacy = root === installRoot() ? legacyInstallation() : null } = {}) {
46
46
  if (process.platform !== 'darwin') throw new Error('Desktop 接入目前仅支持 macOS。');
47
47
  const previous = installation(root), wrapper = join(root, 'minilink');
48
48
  if (existsSync(plist) && !previous) throw new Error('同名 LaunchAgent 已存在且不属于本次安装。');
@@ -76,10 +76,8 @@ export function install({ root = installRoot(), plist = defaultPlist(), source =
76
76
  if (JSON.parse(readFileSync(join(dependency, 'package.json'), 'utf8')).name !== 'smol-toml') throw new Error('smol-toml 依赖路径无效。');
77
77
  cpSync(dependency, join(runtime, 'node_modules/smol-toml'), { recursive: true });
78
78
  const state = { version: 2, source, runtime, wrapper, node, npm: npm || previous?.npm, prefix: prefix || previous?.prefix, codexHome: home, configPath: config, previousEnv: previous?.previousEnv || legacy?.state.previousEnv || null, installedAt: new Date().toISOString() };
79
- // The small fallback also serves Desktop instances that inherited the old
80
- // launch environment before npm uninstall removed the integration.
81
- const fallbackApps = ['/Applications/ChatGPT.app', '/Applications/Codex.app', join(homedir(), 'Applications/ChatGPT.app'), join(homedir(), 'Applications/Codex.app')];
82
- const fallback = `if [ ! -f ${shellQuote(stateFile)} ]; then\n if [ -n "$MINILINK_REAL_CODEX" ] && [ -x "$MINILINK_REAL_CODEX" ]; then exec "$MINILINK_REAL_CODEX" "$@"; fi\n for app in "$CODEX_DESKTOP_APP" ${fallbackApps.map(shellQuote).join(' ')}; do\n [ -n "$app" ] || continue\n for rel in ${bundledCodexPaths.map(shellQuote).join(' ')}; do\n candidate="$app/Contents/Resources/$rel"\n if [ -x "$candidate" ]; then exec "$candidate" "$@"; fi\n done\n done\n exec ${shellQuote(realCodex)} "$@"\nfi`;
79
+ // A Desktop process can retain this launcher after npm removes the state.
80
+ const fallback = `if [ ! -f ${shellQuote(stateFile)} ]; then\n exec "\${CODEX_DESKTOP_APP:-/Applications/ChatGPT.app}/${bundledCodexRelativePath}" "$@"\nfi`;
83
81
  atomicFile(wrapper, `#!/bin/sh\n${fallback}\nexport CODEX_HOME=${shellQuote(home)}\nexport MINILINK_CONFIG=${shellQuote(config)}\nexec ${shellQuote(node)} ${shellQuote(join(runtime, 'bin/minilink.mjs'))} "$@"\n`, 0o755);
84
82
  atomicFile(activate, `#!/bin/sh\nexec ${shellQuote(node)} ${shellQuote(join(runtime, 'src/lifecycle.mjs'))}\n`, 0o700);
85
83
  mkdirSync(dirname(plist), { recursive: true });