| ... | @@ -114,6 +114,9 @@ it.layer(NodeServices.layer)("CodexHomeLayout", (it) => { | ... | @@ -114,6 +114,9 @@ it.layer(NodeServices.layer)("CodexHomeLayout", (it) => { |
| 114 | | 114 | |
| 115 | const sessionsTarget = yield* fileSystem.readLink(path.join(shadowHome, "sessions")); | 115 | const sessionsTarget = yield* fileSystem.readLink(path.join(shadowHome, "sessions")); |
| 116 | const configTarget = yield* fileSystem.readLink(path.join(shadowHome, "config.toml")); | 116 | const configTarget = yield* fileSystem.readLink(path.join(shadowHome, "config.toml")); |
| | 117 | const mcpOauthLocksTarget = yield* fileSystem.readLink( |
| | 118 | path.join(shadowHome, "mcp-oauth-locks"), |
| | 119 | ); |
| 117 | const modelsCacheExists = yield* fileSystem.exists( | 120 | const modelsCacheExists = yield* fileSystem.exists( |
| 118 | path.join(shadowHome, "models_cache.json"), | 121 | path.join(shadowHome, "models_cache.json"), |
| 119 | ); | 122 | ); |
| ... | @@ -124,12 +127,45 @@ it.layer(NodeServices.layer)("CodexHomeLayout", (it) => { | ... | @@ -124,12 +127,45 @@ it.layer(NodeServices.layer)("CodexHomeLayout", (it) => { |
| 124 | | 127 | |
| 125 | expect(sessionsTarget).toBe(path.join(sharedHome, "sessions")); | 128 | expect(sessionsTarget).toBe(path.join(sharedHome, "sessions")); |
| 126 | expect(configTarget).toBe(path.join(sharedHome, "config.toml")); | 129 | expect(configTarget).toBe(path.join(sharedHome, "config.toml")); |
| | 130 | expect(mcpOauthLocksTarget).toBe(path.join(sharedHome, "mcp-oauth-locks")); |
| 127 | expect(modelsCacheExists).toBe(false); | 131 | expect(modelsCacheExists).toBe(false); |
| 128 | expect(authLinkResult._tag).toBe("Failure"); | 132 | expect(authLinkResult._tag).toBe("Failure"); |
| 129 | expect(authContents).toContain("shadow"); | 133 | expect(authContents).toContain("shadow"); |
| 130 | }), | 134 | }), |
| 131 | ); | 135 | ); |
| 132 | | 136 | |
| | 137 | it.effect("replaces Codex-created local MCP OAuth locks with the shared lock directory", () => |
| | 138 | Effect.gen(function* () { |
| | 139 | const fileSystem = yield* FileSystem.FileSystem; |
| | 140 | const path = yield* Path.Path; |
| | 141 | const sharedHome = yield* makeTempDir("t3code-codex-shared-"); |
| | 142 | const shadowRoot = yield* makeTempDir("t3code-codex-shadow-root-"); |
| | 143 | const shadowHome = path.join(shadowRoot, "shadow"); |
| | 144 | const sharedLocks = path.join(sharedHome, "mcp-oauth-locks"); |
| | 145 | const shadowLocks = path.join(shadowHome, "mcp-oauth-locks"); |
| | 146 | |
| | 147 | yield* writeTextFile(path.join(sharedLocks, "file-store.lock"), ""); |
| | 148 | yield* writeTextFile(path.join(shadowLocks, "file-store.lock"), ""); |
| | 149 | |
| | 150 | const layout = yield* resolveCodexHomeLayout( |
| | 151 | decodeCodexSettings({ |
| | 152 | homePath: sharedHome, |
| | 153 | shadowHomePath: shadowHome, |
| | 154 | }), |
| | 155 | ); |
| | 156 | |
| | 157 | yield* materializeCodexShadowHome(layout); |
| | 158 | |
| | 159 | const locksTarget = yield* fileSystem.readLink(shadowLocks); |
| | 160 | const sharedLockExists = yield* fileSystem.exists( |
| | 161 | path.join(sharedLocks, "file-store.lock"), |
| | 162 | ); |
| | 163 | |
| | 164 | expect(locksTarget).toBe(sharedLocks); |
| | 165 | expect(sharedLockExists).toBe(true); |
| | 166 | }), |
| | 167 | ); |
| | 168 | |
| 133 | it.effect("accepts Codex-created shadow-local runtime directories", () => | 169 | it.effect("accepts Codex-created shadow-local runtime directories", () => |
| 134 | Effect.gen(function* () { | 170 | Effect.gen(function* () { |
| 135 | const fileSystem = yield* FileSystem.FileSystem; | 171 | const fileSystem = yield* FileSystem.FileSystem; |