@supen-ai/cli 1.3.2 → 1.3.3

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.
@@ -1615,6 +1615,16 @@ function coerceSingleQueryParam(value) {
1615
1615
  return value[0] || null;
1616
1616
  return value || null;
1617
1617
  }
1618
+ function codexThreadsListRoute(pathname) {
1619
+ return /^\/api\/computers\/\{computer_id\}\/agents\/[^/]+\/codex\/threads$/.test(pathname);
1620
+ }
1621
+ function codexThreadActionRoute(pathname, action) {
1622
+ const suffix = action === 'messages' ? 'messages' : action;
1623
+ return pathname.match(new RegExp(`^/api/computers/\\{computer_id\\}/agents/[^/]+/codex/threads/([^/]+)/${suffix}$`));
1624
+ }
1625
+ function codexProjectsOpenRoute(pathname) {
1626
+ return /^\/api\/computers\/\{computer_id\}\/agents\/[^/]+\/codex\/projects\/open$/.test(pathname);
1627
+ }
1618
1628
  function collectSpaceLogEntries(filters = {}) {
1619
1629
  const spaceId = currentSpaceId();
1620
1630
  const limit = Math.max(1, Math.min(filters.limit || SPACE_LOG_EVENT_LIMIT, 500));
@@ -1764,6 +1774,15 @@ const MANAGED_CODING_CLI_INSTALL_COMMANDS = {
1764
1774
  codex: CODING_CLI_INSTALL_COMMANDS.codex,
1765
1775
  gemini: CODING_CLI_INSTALL_COMMANDS.gemini,
1766
1776
  };
1777
+ function resolveManagedCodingCliInstallCommand(cli, current) {
1778
+ if (cli === 'codex' && current.install_source === 'homebrew') {
1779
+ return {
1780
+ command: 'sh',
1781
+ args: ['-lc', 'brew upgrade codex || brew upgrade --cask codex || brew reinstall --cask codex'],
1782
+ };
1783
+ }
1784
+ return MANAGED_CODING_CLI_INSTALL_COMMANDS[cli];
1785
+ }
1767
1786
  const CODING_CLI_NAMES = ['codex', 'gemini', 'claude'];
1768
1787
  const DETECTABLE_SPACE_APPS = [
1769
1788
  { id: 'libreoffice', command: 'libreoffice', managed: false },
@@ -1971,7 +1990,7 @@ function inferCliInstallSource(name, executablePath, resolvedPath) {
1971
1990
  return { install_source: 'pnpm', update_supported: false };
1972
1991
  }
1973
1992
  if (normalized.includes('/homebrew/') || normalized.includes('/opt/homebrew/') || normalized.includes('/cellar/')) {
1974
- return { install_source: 'homebrew', update_supported: false };
1993
+ return { install_source: 'homebrew', update_supported: name === 'codex' };
1975
1994
  }
1976
1995
  if (name === 'codex') {
1977
1996
  const npmRoot = detectGlobalNpmRoot();
@@ -2763,31 +2782,6 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
2763
2782
  writeJson(res, 200, await readCodexAgentStatusPayload());
2764
2783
  return true;
2765
2784
  }
2766
- if (pathname === '/api/computers/{computer_id}/runtime-models' && method === 'GET') {
2767
- writeJson(res, 200, readRuntimeModelStatusPayload());
2768
- return true;
2769
- }
2770
- if (pathname === '/api/computers/{computer_id}/runtime-models/default' && method === 'PUT') {
2771
- try {
2772
- const parsed = await readJsonBody(req);
2773
- const model = typeof parsed === 'object' && parsed && typeof parsed.model === 'string'
2774
- ? String(parsed.model).trim()
2775
- : '';
2776
- if (!model) {
2777
- writeProtocolError(res, 400, 'validation_error', 'missing_model', 'Request body must include a non-empty "model" string.');
2778
- return true;
2779
- }
2780
- writeCodexDefaultModel(model);
2781
- writeJson(res, 200, {
2782
- ok: true,
2783
- status: readRuntimeModelStatusPayload(),
2784
- });
2785
- }
2786
- catch (err) {
2787
- writeProtocolError(res, 500, 'config_error', 'codex_model_default_failed', err?.message || 'Failed to set Codex default model');
2788
- }
2789
- return true;
2790
- }
2791
2785
  const codexTransportDefaultMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/agents\/codex\/transports\/([^/]+)\/default$/);
2792
2786
  if (codexTransportDefaultMatch && method === 'PUT') {
2793
2787
  try {
@@ -2822,7 +2816,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
2822
2816
  }
2823
2817
  return true;
2824
2818
  }
2825
- if (pathname === '/api/computers/{computer_id}/agents/codex/install' && method === 'POST') {
2819
+ if (pathname === '/api/computers/{computer_id}/agents/codex/update' && method === 'POST') {
2826
2820
  try {
2827
2821
  const cli = 'codex';
2828
2822
  const current = detectCliInstalled(cli);
@@ -2830,7 +2824,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
2830
2824
  writeProtocolError(res, 400, 'validation_error', 'coding_cli_update_not_supported', `${cli} is installed via ${current.install_source || current.resolved_path || current.path || 'an unknown source'}; update it with that installer on this computer.`);
2831
2825
  return true;
2832
2826
  }
2833
- const installSpec = MANAGED_CODING_CLI_INSTALL_COMMANDS.codex;
2827
+ const installSpec = resolveManagedCodingCliInstallCommand(cli, current);
2834
2828
  const result = spawnSync(installSpec.command, installSpec.args, {
2835
2829
  encoding: 'utf8',
2836
2830
  timeout: 120_000,
@@ -2946,15 +2940,15 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
2946
2940
  writeJson(res, 200, buildHubSnapshotForSpace(spaceId));
2947
2941
  return true;
2948
2942
  }
2949
- if (pathname === '/api/computers/{computer_id}/usage' && method === 'GET') {
2943
+ if (pathname === '/api/computers/{computer_id}/agents/codex/usage' && method === 'GET') {
2950
2944
  writeJson(res, 200, getGlobalUsage());
2951
2945
  return true;
2952
2946
  }
2953
- if (pathname === '/api/computers/{computer_id}/usage/daily' && method === 'GET') {
2947
+ if (pathname === '/api/computers/{computer_id}/agents/codex/usage/daily' && method === 'GET') {
2954
2948
  writeJson(res, 200, { daily: getDailyUsage() });
2955
2949
  return true;
2956
2950
  }
2957
- if (pathname === '/api/computers/{computer_id}/codex/threads' && method === 'GET') {
2951
+ if (codexThreadsListRoute(pathname) && method === 'GET') {
2958
2952
  const limitRaw = coerceSingleQueryParam(url.searchParams.get('limit'));
2959
2953
  const limit = limitRaw ? Number.parseInt(limitRaw, 10) : MIRRORED_THREAD_LIMIT;
2960
2954
  writeJson(res, 200, readMirroredTaskProjects(Number.isFinite(limit) ? limit : MIRRORED_THREAD_LIMIT));
@@ -2974,7 +2968,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
2974
2968
  serveRemoteFile(req, res, filePath);
2975
2969
  return true;
2976
2970
  }
2977
- const mirroredThreadArchiveMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/codex\/threads\/([^/]+)\/archive$/);
2971
+ const mirroredThreadArchiveMatch = codexThreadActionRoute(pathname, 'archive');
2978
2972
  if (mirroredThreadArchiveMatch && method === 'POST') {
2979
2973
  const threadId = decodeURIComponent(mirroredThreadArchiveMatch[1] || '').trim();
2980
2974
  if (!threadId) {
@@ -2988,7 +2982,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
2988
2982
  writeJson(res, 200, { ok: true, archived: true });
2989
2983
  return true;
2990
2984
  }
2991
- const mirroredThreadStreamMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/codex\/threads\/([^/]+)\/stream$/);
2985
+ const mirroredThreadStreamMatch = codexThreadActionRoute(pathname, 'stream');
2992
2986
  if (mirroredThreadStreamMatch && method === 'GET') {
2993
2987
  const threadId = decodeURIComponent(mirroredThreadStreamMatch[1] || '').trim();
2994
2988
  if (!threadId) {
@@ -3031,7 +3025,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
3031
3025
  res.flush?.();
3032
3026
  return true;
3033
3027
  }
3034
- const mirroredThreadHistoryMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/codex\/threads\/([^/]+)\/messages$/);
3028
+ const mirroredThreadHistoryMatch = codexThreadActionRoute(pathname, 'messages');
3035
3029
  if (mirroredThreadHistoryMatch && method === 'GET') {
3036
3030
  const threadId = decodeURIComponent(mirroredThreadHistoryMatch[1] || '').trim();
3037
3031
  const limitRaw = coerceSingleQueryParam(url.searchParams.get('limit'));
@@ -3046,7 +3040,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
3046
3040
  writeJson(res, 200, history);
3047
3041
  return true;
3048
3042
  }
3049
- const mirroredThreadAdoptMatch = pathname.match(/^\/api\/computers\/\{computer_id\}\/codex\/threads\/([^/]+)\/adopt$/);
3043
+ const mirroredThreadAdoptMatch = codexThreadActionRoute(pathname, 'adopt');
3050
3044
  if (mirroredThreadAdoptMatch && method === 'POST') {
3051
3045
  const threadId = decodeURIComponent(mirroredThreadAdoptMatch[1] || '').trim();
3052
3046
  const parsed = await readJsonBody(req);
@@ -3063,7 +3057,7 @@ export async function handleSystemRoutes(req, res, url, pathname, method) {
3063
3057
  writeJson(res, 200, { thread: serializeAdoptedMirroredThread(session) });
3064
3058
  return true;
3065
3059
  }
3066
- if (pathname === '/api/computers/{computer_id}/codex/projects/open' && method === 'POST') {
3060
+ if (codexProjectsOpenRoute(pathname) && method === 'POST') {
3067
3061
  try {
3068
3062
  const parsed = await readJsonBody(req);
3069
3063
  const projectPath = parsed && typeof parsed === 'object' && typeof parsed.path === 'string'