@gotcos/glasses-server 6.15.2 → 6.15.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 6.15.3
2
+
3
+ - Make `COS_WORKDIR` the authoritative Claude, Codex, and Cursor workspace.
4
+ Legacy provider-specific and `COS_SCRIPTS_DIR` paths remain compatibility
5
+ fallbacks, so pipeline scripts can stay separate from the agent workspace.
6
+ - Add workspace-precedence coverage for migrated LaunchAgent environments.
7
+
1
8
  ## 6.15.2
2
9
 
3
10
  - Validate the inherited Kokoro Python runtime before skipping bootstrap, so a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotcos/glasses-server",
3
- "version": "6.15.2",
3
+ "version": "6.15.3",
4
4
  "description": "COS Glasses — self-hosted AI heads-up-display server for Even G2 smart glasses, powered by your local Claude Code or Codex CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,7 +11,7 @@ import { writeFileSync, readFileSync, unlinkSync, existsSync } from 'node:fs'
11
11
  import { appendFileSync } from 'node:fs'
12
12
  import { COS_SCRIPTS_DIR } from './python-bridge.js'
13
13
  import { cleanupModelImageInputs, type ModelImageInput } from './model-image-input.js'
14
- import { cosBrainDir } from './launch-dir.js'
14
+ import { resolveProviderWorkDir } from './launch-dir.js'
15
15
  import { logTokenAudit } from './token-audit.js'
16
16
  import { buildSystemPrompt, buildLightweightSystemPrompt, buildPrewarmSystemPrompt, getCachedContextInstant } from './context-builder.js'
17
17
  import { getHistory, addExchange, setExchangeAttachments, removeExchange, formatHistoryForPrompt, getOrCreateSession, isNewSession, markSessionNotified, getSessionModel, getSessionRaw, replaceLastExchangeWithSummary, type ModelPreference, type PromptReference } from './conversation.js'
@@ -225,7 +225,7 @@ export async function preWarmCLI(): Promise<void> {
225
225
  ], {
226
226
  stdio: ['pipe', 'pipe', 'pipe'],
227
227
  env,
228
- cwd: COS_SCRIPTS_DIR ?? cosBrainDir() ?? process.cwd(),
228
+ cwd: resolveProviderWorkDir({ scriptsDir: COS_SCRIPTS_DIR }),
229
229
  })
230
230
 
231
231
  let buffer = ''
@@ -528,7 +528,7 @@ export async function callClaudeStreaming(
528
528
  const env = { ...process.env }
529
529
  delete env.CLAUDECODE
530
530
  if (outputImagePublisher) Object.assign(env, outputImagePublisher.env)
531
- const cliCwd = COS_SCRIPTS_DIR ?? cosBrainDir() ?? process.cwd()
531
+ const cliCwd = resolveProviderWorkDir({ scriptsDir: COS_SCRIPTS_DIR })
532
532
  const inactivityMs = INACTIVITY_BY_MODEL[resolvedModel]
533
533
  const defaultWallMax = WALL_MAX_BY_MODEL[resolvedModel]
534
534
  const effortWallMax = resolvedEffort === 'max' || resolvedEffort === 'ultracode'
@@ -2,7 +2,7 @@ import crypto from 'node:crypto'
2
2
  import { appendFileSync, chmodSync, existsSync, mkdirSync, readFileSync } from 'node:fs'
3
3
  import { dirname, resolve } from 'node:path'
4
4
  import { COS_SCRIPTS_DIR } from './python-bridge.js'
5
- import { cosBrainDir } from './launch-dir.js'
5
+ import { resolveProviderWorkDir } from './launch-dir.js'
6
6
  import { CODEX_ENGINE_SESSION_TTL_MS, type CodexTrustMode } from './codex-engine-sessions.js'
7
7
  import {
8
8
  CODEX_FRONTIER_MODEL,
@@ -84,16 +84,10 @@ export function areCodexContentPreviewsEnabled(): boolean {
84
84
  }
85
85
 
86
86
  export function getCodexExecutionCwd(): string {
87
- const configured = process.env.CODEX_GLASSES_WORKDIR?.trim()
88
- if (configured) return resolve(configured)
89
- if (COS_SCRIPTS_DIR) return resolve(COS_SCRIPTS_DIR, '..', '..')
90
- // A Starter-Kit COS in the directory the user launched npx from — Codex
91
- // loads its AGENTS.md brain natively when run there.
92
- const brain = cosBrainDir()
93
- if (brain) return brain
94
- // Last resort when neither CODEX_GLASSES_WORKDIR nor COS_SCRIPTS_DIR is set:
95
- // the server's own working dir (codex glasses is an optional, env-configured feature).
96
- return process.cwd()
87
+ return resolveProviderWorkDir({
88
+ legacyProviderDir: process.env.CODEX_GLASSES_WORKDIR,
89
+ scriptsDir: COS_SCRIPTS_DIR,
90
+ })
97
91
  }
98
92
 
99
93
  export function getCodexTrustMode(): CodexTrustMode {
@@ -7,8 +7,9 @@
7
7
  // spawns of claude/codex use IT as their working directory — so the CLIs load
8
8
  // the user's brain exactly as they would in a terminal session in that folder.
9
9
  //
10
- // Precedence stays: COS_SCRIPTS_DIR (full COS pipeline) > detected brain dir >
11
- // process.cwd(). Explicit config always wins.
10
+ // Provider precedence is: selected COS_WORKDIR > legacy provider override >
11
+ // COS_SCRIPTS_DIR repository root > process.cwd(). Pipeline data still uses
12
+ // COS_SCRIPTS_DIR independently.
12
13
  import { existsSync } from 'node:fs'
13
14
  import { join, resolve } from 'node:path'
14
15
 
@@ -33,3 +34,28 @@ export function cosBrainDir(): string | null {
33
34
  cached = resolveCosBrainDir(process.env.COS_WORKDIR ?? process.env.COS_LAUNCH_DIR)
34
35
  return cached
35
36
  }
37
+
38
+ /**
39
+ * Resolve the provider working directory from one authoritative contract.
40
+ * COS_WORKDIR (via cosBrainDir) is the user-selected agent workspace and must
41
+ * outrank legacy provider-specific and pipeline locations. COS_SCRIPTS_DIR is
42
+ * still used by the Python pipeline; it is only a cwd fallback here.
43
+ */
44
+ export function resolveProviderWorkDir(options: {
45
+ legacyProviderDir?: string | null
46
+ scriptsDir?: string | null
47
+ fallback?: string
48
+ } = {}): string {
49
+ const brain = cosBrainDir()
50
+ if (brain) return brain
51
+ const legacy = options.legacyProviderDir?.trim()
52
+ if (legacy) return resolve(legacy)
53
+ const scripts = options.scriptsDir?.trim()
54
+ if (scripts) return resolve(scripts, '..', '..')
55
+ return resolve(options.fallback ?? process.cwd())
56
+ }
57
+
58
+ /** Test-only cache reset for environment-precedence coverage. */
59
+ export function resetCosBrainDirCacheForTests(): void {
60
+ cached = undefined
61
+ }