@tickernelz/paperclip-pro-adapter-codex-local 2026.925.0

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.
Files changed (268) hide show
  1. package/LICENSE +22 -0
  2. package/dist/cli/format-event.d.ts +2 -0
  3. package/dist/cli/format-event.d.ts.map +1 -0
  4. package/dist/cli/format-event.js +218 -0
  5. package/dist/cli/format-event.js.map +1 -0
  6. package/dist/cli/index.d.ts +2 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +2 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/cli/quota-probe.d.ts +3 -0
  11. package/dist/cli/quota-probe.d.ts.map +1 -0
  12. package/dist/cli/quota-probe.js +104 -0
  13. package/dist/cli/quota-probe.js.map +1 -0
  14. package/dist/index.d.ts +21 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +155 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/index.test.d.ts +2 -0
  19. package/dist/index.test.d.ts.map +1 -0
  20. package/dist/index.test.js +58 -0
  21. package/dist/index.test.js.map +1 -0
  22. package/dist/server/acp.d.ts +30 -0
  23. package/dist/server/acp.d.ts.map +1 -0
  24. package/dist/server/acp.js +532 -0
  25. package/dist/server/acp.js.map +1 -0
  26. package/dist/server/acp.test.d.ts +2 -0
  27. package/dist/server/acp.test.d.ts.map +1 -0
  28. package/dist/server/acp.test.js +1087 -0
  29. package/dist/server/acp.test.js.map +1 -0
  30. package/dist/server/adapter-auth-promotion.d.ts +102 -0
  31. package/dist/server/adapter-auth-promotion.d.ts.map +1 -0
  32. package/dist/server/adapter-auth-promotion.js +210 -0
  33. package/dist/server/adapter-auth-promotion.js.map +1 -0
  34. package/dist/server/adapter-auth-promotion.test.d.ts +2 -0
  35. package/dist/server/adapter-auth-promotion.test.d.ts.map +1 -0
  36. package/dist/server/adapter-auth-promotion.test.js +658 -0
  37. package/dist/server/adapter-auth-promotion.test.js.map +1 -0
  38. package/dist/server/auth-check.d.ts +8 -0
  39. package/dist/server/auth-check.d.ts.map +1 -0
  40. package/dist/server/auth-check.js +8 -0
  41. package/dist/server/auth-check.js.map +1 -0
  42. package/dist/server/auth-precedence.d.ts +16 -0
  43. package/dist/server/auth-precedence.d.ts.map +1 -0
  44. package/dist/server/auth-precedence.js +20 -0
  45. package/dist/server/auth-precedence.js.map +1 -0
  46. package/dist/server/auth-precedence.test.d.ts +2 -0
  47. package/dist/server/auth-precedence.test.d.ts.map +1 -0
  48. package/dist/server/auth-precedence.test.js +100 -0
  49. package/dist/server/auth-precedence.test.js.map +1 -0
  50. package/dist/server/codex-args.d.ts +13 -0
  51. package/dist/server/codex-args.d.ts.map +1 -0
  52. package/dist/server/codex-args.js +76 -0
  53. package/dist/server/codex-args.js.map +1 -0
  54. package/dist/server/codex-args.test.d.ts +2 -0
  55. package/dist/server/codex-args.test.d.ts.map +1 -0
  56. package/dist/server/codex-args.test.js +243 -0
  57. package/dist/server/codex-args.test.js.map +1 -0
  58. package/dist/server/codex-auth-cache.d.ts +206 -0
  59. package/dist/server/codex-auth-cache.d.ts.map +1 -0
  60. package/dist/server/codex-auth-cache.js +501 -0
  61. package/dist/server/codex-auth-cache.js.map +1 -0
  62. package/dist/server/codex-auth-cache.test.d.ts +2 -0
  63. package/dist/server/codex-auth-cache.test.d.ts.map +1 -0
  64. package/dist/server/codex-auth-cache.test.js +497 -0
  65. package/dist/server/codex-auth-cache.test.js.map +1 -0
  66. package/dist/server/codex-auth-copyback.d.ts +53 -0
  67. package/dist/server/codex-auth-copyback.d.ts.map +1 -0
  68. package/dist/server/codex-auth-copyback.js +123 -0
  69. package/dist/server/codex-auth-copyback.js.map +1 -0
  70. package/dist/server/codex-auth-copyback.test.d.ts +2 -0
  71. package/dist/server/codex-auth-copyback.test.d.ts.map +1 -0
  72. package/dist/server/codex-auth-copyback.test.js +507 -0
  73. package/dist/server/codex-auth-copyback.test.js.map +1 -0
  74. package/dist/server/codex-auth-merge-decision.cjs +170 -0
  75. package/dist/server/codex-auth-merge-decision.d.ts +22 -0
  76. package/dist/server/codex-auth-merge-decision.d.ts.map +1 -0
  77. package/dist/server/codex-auth-merge-decision.js +58 -0
  78. package/dist/server/codex-auth-merge-decision.js.map +1 -0
  79. package/dist/server/codex-auth-merge-decision.test.d.ts +2 -0
  80. package/dist/server/codex-auth-merge-decision.test.d.ts.map +1 -0
  81. package/dist/server/codex-auth-merge-decision.test.js +230 -0
  82. package/dist/server/codex-auth-merge-decision.test.js.map +1 -0
  83. package/dist/server/codex-auth-merge-extract.sh +73 -0
  84. package/dist/server/codex-auth-merge-scripts.d.ts +21 -0
  85. package/dist/server/codex-auth-merge-scripts.d.ts.map +1 -0
  86. package/dist/server/codex-auth-merge-scripts.js +40 -0
  87. package/dist/server/codex-auth-merge-scripts.js.map +1 -0
  88. package/dist/server/codex-auth-merge.test.d.ts +2 -0
  89. package/dist/server/codex-auth-merge.test.d.ts.map +1 -0
  90. package/dist/server/codex-auth-merge.test.js +714 -0
  91. package/dist/server/codex-auth-merge.test.js.map +1 -0
  92. package/dist/server/codex-auth-seed-write.d.ts +30 -0
  93. package/dist/server/codex-auth-seed-write.d.ts.map +1 -0
  94. package/dist/server/codex-auth-seed-write.js +41 -0
  95. package/dist/server/codex-auth-seed-write.js.map +1 -0
  96. package/dist/server/codex-home.d.ts +162 -0
  97. package/dist/server/codex-home.d.ts.map +1 -0
  98. package/dist/server/codex-home.js +771 -0
  99. package/dist/server/codex-home.js.map +1 -0
  100. package/dist/server/codex-home.test.d.ts +2 -0
  101. package/dist/server/codex-home.test.d.ts.map +1 -0
  102. package/dist/server/codex-home.test.js +1183 -0
  103. package/dist/server/codex-home.test.js.map +1 -0
  104. package/dist/server/config-schema.d.ts +3 -0
  105. package/dist/server/config-schema.d.ts.map +1 -0
  106. package/dist/server/config-schema.js +67 -0
  107. package/dist/server/config-schema.js.map +1 -0
  108. package/dist/server/device-login-export.d.ts +56 -0
  109. package/dist/server/device-login-export.d.ts.map +1 -0
  110. package/dist/server/device-login-export.js +230 -0
  111. package/dist/server/device-login-export.js.map +1 -0
  112. package/dist/server/device-login-export.test.d.ts +2 -0
  113. package/dist/server/device-login-export.test.d.ts.map +1 -0
  114. package/dist/server/device-login-export.test.js +245 -0
  115. package/dist/server/device-login-export.test.js.map +1 -0
  116. package/dist/server/device-login-parse.d.ts +20 -0
  117. package/dist/server/device-login-parse.d.ts.map +1 -0
  118. package/dist/server/device-login-parse.js +155 -0
  119. package/dist/server/device-login-parse.js.map +1 -0
  120. package/dist/server/device-login-parse.test.d.ts +2 -0
  121. package/dist/server/device-login-parse.test.d.ts.map +1 -0
  122. package/dist/server/device-login-parse.test.js +269 -0
  123. package/dist/server/device-login-parse.test.js.map +1 -0
  124. package/dist/server/device-login-runner.d.ts +69 -0
  125. package/dist/server/device-login-runner.d.ts.map +1 -0
  126. package/dist/server/device-login-runner.js +109 -0
  127. package/dist/server/device-login-runner.js.map +1 -0
  128. package/dist/server/device-login-runner.test.d.ts +2 -0
  129. package/dist/server/device-login-runner.test.d.ts.map +1 -0
  130. package/dist/server/device-login-runner.test.js +201 -0
  131. package/dist/server/device-login-runner.test.js.map +1 -0
  132. package/dist/server/engine-availability.test.d.ts +2 -0
  133. package/dist/server/engine-availability.test.d.ts.map +1 -0
  134. package/dist/server/engine-availability.test.js +41 -0
  135. package/dist/server/engine-availability.test.js.map +1 -0
  136. package/dist/server/execute.acp-fallback.test.d.ts +2 -0
  137. package/dist/server/execute.acp-fallback.test.d.ts.map +1 -0
  138. package/dist/server/execute.acp-fallback.test.js +123 -0
  139. package/dist/server/execute.acp-fallback.test.js.map +1 -0
  140. package/dist/server/execute.auth-precedence.test.d.ts +2 -0
  141. package/dist/server/execute.auth-precedence.test.d.ts.map +1 -0
  142. package/dist/server/execute.auth-precedence.test.js +137 -0
  143. package/dist/server/execute.auth-precedence.test.js.map +1 -0
  144. package/dist/server/execute.auth.test.d.ts +2 -0
  145. package/dist/server/execute.auth.test.d.ts.map +1 -0
  146. package/dist/server/execute.auth.test.js +197 -0
  147. package/dist/server/execute.auth.test.js.map +1 -0
  148. package/dist/server/execute.d.ts +40 -0
  149. package/dist/server/execute.d.ts.map +1 -0
  150. package/dist/server/execute.js +1290 -0
  151. package/dist/server/execute.js.map +1 -0
  152. package/dist/server/execute.remote.test.d.ts +2 -0
  153. package/dist/server/execute.remote.test.d.ts.map +1 -0
  154. package/dist/server/execute.remote.test.js +556 -0
  155. package/dist/server/execute.remote.test.js.map +1 -0
  156. package/dist/server/execute.stderr-error.test.d.ts +2 -0
  157. package/dist/server/execute.stderr-error.test.d.ts.map +1 -0
  158. package/dist/server/execute.stderr-error.test.js +142 -0
  159. package/dist/server/execute.stderr-error.test.js.map +1 -0
  160. package/dist/server/execute.test.d.ts +2 -0
  161. package/dist/server/execute.test.d.ts.map +1 -0
  162. package/dist/server/execute.test.js +240 -0
  163. package/dist/server/execute.test.js.map +1 -0
  164. package/dist/server/index.d.ts +18 -0
  165. package/dist/server/index.d.ts.map +1 -0
  166. package/dist/server/index.js +71 -0
  167. package/dist/server/index.js.map +1 -0
  168. package/dist/server/output-inactivity-monitor.d.ts +62 -0
  169. package/dist/server/output-inactivity-monitor.d.ts.map +1 -0
  170. package/dist/server/output-inactivity-monitor.integration.test.d.ts +2 -0
  171. package/dist/server/output-inactivity-monitor.integration.test.d.ts.map +1 -0
  172. package/dist/server/output-inactivity-monitor.integration.test.js +136 -0
  173. package/dist/server/output-inactivity-monitor.integration.test.js.map +1 -0
  174. package/dist/server/output-inactivity-monitor.js +112 -0
  175. package/dist/server/output-inactivity-monitor.js.map +1 -0
  176. package/dist/server/output-inactivity-monitor.test.d.ts +2 -0
  177. package/dist/server/output-inactivity-monitor.test.d.ts.map +1 -0
  178. package/dist/server/output-inactivity-monitor.test.js +284 -0
  179. package/dist/server/output-inactivity-monitor.test.js.map +1 -0
  180. package/dist/server/parse.d.ts +51 -0
  181. package/dist/server/parse.d.ts.map +1 -0
  182. package/dist/server/parse.js +261 -0
  183. package/dist/server/parse.js.map +1 -0
  184. package/dist/server/parse.test.d.ts +2 -0
  185. package/dist/server/parse.test.d.ts.map +1 -0
  186. package/dist/server/parse.test.js +186 -0
  187. package/dist/server/parse.test.js.map +1 -0
  188. package/dist/server/process-activity-monitor.d.ts +21 -0
  189. package/dist/server/process-activity-monitor.d.ts.map +1 -0
  190. package/dist/server/process-activity-monitor.js +103 -0
  191. package/dist/server/process-activity-monitor.js.map +1 -0
  192. package/dist/server/process-activity-monitor.test.d.ts +2 -0
  193. package/dist/server/process-activity-monitor.test.d.ts.map +1 -0
  194. package/dist/server/process-activity-monitor.test.js +82 -0
  195. package/dist/server/process-activity-monitor.test.js.map +1 -0
  196. package/dist/server/quota-spawn-error.test.d.ts +2 -0
  197. package/dist/server/quota-spawn-error.test.d.ts.map +1 -0
  198. package/dist/server/quota-spawn-error.test.js +174 -0
  199. package/dist/server/quota-spawn-error.test.js.map +1 -0
  200. package/dist/server/quota.d.ts +66 -0
  201. package/dist/server/quota.d.ts.map +1 -0
  202. package/dist/server/quota.js +511 -0
  203. package/dist/server/quota.js.map +1 -0
  204. package/dist/server/runtime-config.d.ts +11 -0
  205. package/dist/server/runtime-config.d.ts.map +1 -0
  206. package/dist/server/runtime-config.js +380 -0
  207. package/dist/server/runtime-config.js.map +1 -0
  208. package/dist/server/runtime-config.test.d.ts +2 -0
  209. package/dist/server/runtime-config.test.d.ts.map +1 -0
  210. package/dist/server/runtime-config.test.js +367 -0
  211. package/dist/server/runtime-config.test.js.map +1 -0
  212. package/dist/server/skills.d.ts +8 -0
  213. package/dist/server/skills.d.ts.map +1 -0
  214. package/dist/server/skills.js +26 -0
  215. package/dist/server/skills.js.map +1 -0
  216. package/dist/server/test.d.ts +3 -0
  217. package/dist/server/test.d.ts.map +1 -0
  218. package/dist/server/test.js +458 -0
  219. package/dist/server/test.js.map +1 -0
  220. package/dist/server/test.remote.test.d.ts +2 -0
  221. package/dist/server/test.remote.test.d.ts.map +1 -0
  222. package/dist/server/test.remote.test.js +396 -0
  223. package/dist/server/test.remote.test.js.map +1 -0
  224. package/dist/ui/build-config.d.ts +5 -0
  225. package/dist/ui/build-config.d.ts.map +1 -0
  226. package/dist/ui/build-config.js +229 -0
  227. package/dist/ui/build-config.js.map +1 -0
  228. package/dist/ui/build-config.test.d.ts +2 -0
  229. package/dist/ui/build-config.test.d.ts.map +1 -0
  230. package/dist/ui/build-config.test.js +272 -0
  231. package/dist/ui/build-config.test.js.map +1 -0
  232. package/dist/ui/index.d.ts +4 -0
  233. package/dist/ui/index.d.ts.map +1 -0
  234. package/dist/ui/index.js +8 -0
  235. package/dist/ui/index.js.map +1 -0
  236. package/dist/ui/parse-stdout.d.ts +3 -0
  237. package/dist/ui/parse-stdout.d.ts.map +1 -0
  238. package/dist/ui/parse-stdout.js +265 -0
  239. package/dist/ui/parse-stdout.js.map +1 -0
  240. package/dist/ui/parse-stdout.test.d.ts +2 -0
  241. package/dist/ui/parse-stdout.test.d.ts.map +1 -0
  242. package/dist/ui/parse-stdout.test.js +77 -0
  243. package/dist/ui/parse-stdout.test.js.map +1 -0
  244. package/package.json +61 -0
  245. package/skills/agentmail/SKILL.md +70 -0
  246. package/skills/paperclip/SKILL.md +712 -0
  247. package/skills/paperclip/references/api-reference.md +1675 -0
  248. package/skills/paperclip/references/artifacts.md +158 -0
  249. package/skills/paperclip/references/cases.md +295 -0
  250. package/skills/paperclip/references/company-skills.md +266 -0
  251. package/skills/paperclip/references/issue-workspaces.md +80 -0
  252. package/skills/paperclip/references/routines.md +231 -0
  253. package/skills/paperclip/references/workflows.md +141 -0
  254. package/skills/paperclip/scripts/paperclip-upload-artifact.sh +592 -0
  255. package/skills/paperclip-board/SKILL.md +619 -0
  256. package/skills/paperclip-converting-plans-to-tasks/SKILL.md +60 -0
  257. package/skills/paperclip-create-agent/SKILL.md +179 -0
  258. package/skills/paperclip-create-agent/references/agent-instruction-templates.md +123 -0
  259. package/skills/paperclip-create-agent/references/agents/coder.md +64 -0
  260. package/skills/paperclip-create-agent/references/agents/qa.md +88 -0
  261. package/skills/paperclip-create-agent/references/agents/securityengineer.md +135 -0
  262. package/skills/paperclip-create-agent/references/agents/uxdesigner.md +115 -0
  263. package/skills/paperclip-create-agent/references/api-reference.md +110 -0
  264. package/skills/paperclip-create-agent/references/baseline-role-guide.md +168 -0
  265. package/skills/paperclip-create-agent/references/draft-review-checklist.md +95 -0
  266. package/skills/para-memory-files/SKILL.md +100 -0
  267. package/skills/para-memory-files/references/schemas.md +35 -0
  268. package/skills/slack/SKILL.md +65 -0
@@ -0,0 +1,497 @@
1
+ import { chmod, lstat, mkdir, mkdtemp, readdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { assertAccountHomeCacheDirStillValid, clearCodexAuthCache, clearCodexAuthCacheEntry, ensureCodexAuthCacheEntryDir, isCodexAuthCacheEnabled, isCodexAuthCachePath, resolveCodexAuthCacheDir, resolveCodexAuthCacheEntryPath, selectVendCredential, toCacheKey, withAccountHomeSecretMutationLock, withCodexAccountHomePromotionLock, } from "./codex-auth-cache.js";
6
+ import { resolveSharedCodexHomeDir } from "./codex-home.js";
7
+ // This suite proves the per-identity host credential cache store. The cache is a
8
+ // separate directory outside the shared Codex home and outside the symlink
9
+ // allowlist. It keys one usable subscription credential per identity
10
+ // (`account_id`). The suite drives the real path resolver, the real directory
11
+ // guards, and the real decision predicate (`codex-auth-merge-decision.cjs`)
12
+ // against a real host tmp filesystem.
13
+ describe("codex auth cache store", () => {
14
+ const cleanupDirs = [];
15
+ afterEach(async () => {
16
+ while (cleanupDirs.length > 0) {
17
+ const dir = cleanupDirs.pop();
18
+ if (!dir)
19
+ continue;
20
+ await chmod(dir, 0o700).catch(() => undefined);
21
+ await rm(dir, { recursive: true, force: true }).catch(() => undefined);
22
+ }
23
+ });
24
+ async function makeInstanceRoot() {
25
+ const dir = await mkdtemp(path.join(os.tmpdir(), "paperclip-codex-cache-"));
26
+ cleanupDirs.push(dir);
27
+ return dir;
28
+ }
29
+ function envFor(instanceHome, extra = {}) {
30
+ return {
31
+ PAPERCLIP_HOME: instanceHome,
32
+ PAPERCLIP_INSTANCE_ID: "default",
33
+ ...extra,
34
+ };
35
+ }
36
+ function subscriptionAuth(input) {
37
+ const suffix = input.marker ?? input.accountId;
38
+ return JSON.stringify({
39
+ tokens: {
40
+ id_token: `id-token-${suffix}`,
41
+ access_token: `access-token-${suffix}`,
42
+ refresh_token: `refresh-token-${suffix}`,
43
+ account_id: input.accountId,
44
+ },
45
+ ...(input.lastRefresh ? { last_refresh: input.lastRefresh } : {}),
46
+ });
47
+ }
48
+ const NEWER = "2026-07-09T02:00:00Z";
49
+ const OLDER = "2026-07-09T01:00:00Z";
50
+ describe("Phase 1: cache store location and path scheme", () => {
51
+ it("resolveCodexAuthCacheDir returns a path outside resolveSharedCodexHomeDir", async () => {
52
+ const home = await makeInstanceRoot();
53
+ const env = envFor(home, { CODEX_HOME: path.join(home, "shared-codex") });
54
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
55
+ const sharedHome = resolveSharedCodexHomeDir(env);
56
+ expect(cacheDir.startsWith(sharedHome + path.sep)).toBe(false);
57
+ expect(cacheDir).not.toBe(sharedHome);
58
+ });
59
+ it("resolveCodexAuthCacheDir returns a company-scoped path under the instance companies directory when companyId is set", async () => {
60
+ const home = await makeInstanceRoot();
61
+ const env = envFor(home);
62
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
63
+ expect(cacheDir).toBe(path.resolve(home, "instances", "default", "companies", "company-a", "codex-auth-cache"));
64
+ });
65
+ it("isCodexAuthCachePath recognizes store entries for any company and rejects everything else", async () => {
66
+ const home = await makeInstanceRoot();
67
+ const env = envFor(home);
68
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
69
+ expect(isCodexAuthCachePath(env, cacheDir)).toBe(true);
70
+ expect(isCodexAuthCachePath(env, path.join(cacheDir, "acct-1"))).toBe(true);
71
+ expect(isCodexAuthCachePath(env, resolveCodexAuthCacheDir(env, "company-b"))).toBe(true);
72
+ // The company Codex home and a per-agent home are managed homes, not
73
+ // store entries — the seeding pass owns them.
74
+ expect(isCodexAuthCachePath(env, path.join(home, "instances", "default", "companies", "company-a", "codex-home"))).toBe(false);
75
+ expect(isCodexAuthCachePath(env, path.join(home, "instances", "default", "companies", "company-a", "agents", "agent-1", "codex-home"))).toBe(false);
76
+ // A sibling directory whose name merely STARTS with the store name
77
+ // stays out, as does anything outside the instance tree.
78
+ expect(isCodexAuthCachePath(env, path.join(home, "instances", "default", "companies", "company-a", "codex-auth-cache-extra"))).toBe(false);
79
+ expect(isCodexAuthCachePath(env, "/tmp/codex-auth-cache/acct-1")).toBe(false);
80
+ });
81
+ it("resolveCodexAuthCacheEntryPath keys the entry by a sanitized account_id and ends with auth.json", async () => {
82
+ const home = await makeInstanceRoot();
83
+ const env = envFor(home);
84
+ const entryPath = resolveCodexAuthCacheEntryPath(env, "acct-42", "company-a");
85
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
86
+ expect(entryPath).toBe(path.join(cacheDir, "acct-42", "auth.json"));
87
+ });
88
+ it("toCacheKey rejects an empty account_id, a path separator, and ..", () => {
89
+ expect(() => toCacheKey("")).toThrow();
90
+ expect(() => toCacheKey(" ")).toThrow();
91
+ expect(() => toCacheKey("..")).toThrow();
92
+ expect(() => toCacheKey(".")).toThrow();
93
+ expect(() => toCacheKey("a/b")).toThrow();
94
+ expect(() => toCacheKey("a\\b")).toThrow();
95
+ expect(() => toCacheKey("../escape")).toThrow();
96
+ expect(() => toCacheKey("a\0b")).toThrow();
97
+ expect(toCacheKey("acct-42")).toBe("acct-42");
98
+ });
99
+ it("resolveCodexAuthCacheDir rejects a traversal companyId before it builds the path", async () => {
100
+ const home = await makeInstanceRoot();
101
+ const env = envFor(home);
102
+ // A traversal companyId must never make the cache root escape the
103
+ // companies/ directory. Sanitization runs before path construction, so a
104
+ // relative segment, a path separator, an absolute path, and a NUL byte all
105
+ // fail loud.
106
+ expect(() => resolveCodexAuthCacheDir(env, "")).toThrow();
107
+ expect(() => resolveCodexAuthCacheDir(env, " ")).toThrow();
108
+ expect(() => resolveCodexAuthCacheDir(env, "..")).toThrow();
109
+ expect(() => resolveCodexAuthCacheDir(env, ".")).toThrow();
110
+ expect(() => resolveCodexAuthCacheDir(env, "../../etc")).toThrow();
111
+ expect(() => resolveCodexAuthCacheDir(env, "/etc")).toThrow();
112
+ expect(() => resolveCodexAuthCacheDir(env, "a/b")).toThrow();
113
+ expect(() => resolveCodexAuthCacheDir(env, "a\\b")).toThrow();
114
+ expect(() => resolveCodexAuthCacheDir(env, "a\0b")).toThrow();
115
+ // The clear path inherits the same guard, so a traversal companyId can
116
+ // never reach rm() on an escaped root.
117
+ await expect(clearCodexAuthCache(env, "../../etc")).rejects.toThrow();
118
+ const safeDir = resolveCodexAuthCacheDir(env, "company-a");
119
+ expect(safeDir).toBe(path.resolve(home, "instances", "default", "companies", "company-a", "codex-auth-cache"));
120
+ });
121
+ it("resolveCodexAuthCacheEntryPath rejects an identifier that toAccountHandle rejects", async () => {
122
+ const home = await makeInstanceRoot();
123
+ const env = envFor(home);
124
+ // A space, a plus sign, and a leading hyphen all fail the stricter
125
+ // account-handle allowlist, even though the older denylist alone would
126
+ // accept some of them.
127
+ expect(() => resolveCodexAuthCacheEntryPath(env, "acct 42", "company-a")).toThrow();
128
+ expect(() => resolveCodexAuthCacheEntryPath(env, "acct+42", "company-a")).toThrow();
129
+ expect(() => resolveCodexAuthCacheEntryPath(env, "-rf", "company-a")).toThrow();
130
+ });
131
+ it("resolveCodexAuthCacheEntryPath verifies the resolved path stays under the cache root", async () => {
132
+ const home = await makeInstanceRoot();
133
+ const env = envFor(home);
134
+ // A traversal account_id is rejected by toCacheKey, so the resolved entry
135
+ // path can never escape the cache root.
136
+ expect(() => resolveCodexAuthCacheEntryPath(env, "../../etc", "company-a")).toThrow();
137
+ const entryPath = resolveCodexAuthCacheEntryPath(env, "acct-ok", "company-a");
138
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
139
+ expect(entryPath.startsWith(cacheDir + path.sep)).toBe(true);
140
+ expect(entryPath.endsWith(path.join("acct-ok", "auth.json"))).toBe(true);
141
+ });
142
+ it("ensureCodexAuthCacheEntryDir creates the cache root and the entry directory private (0700)", async () => {
143
+ const home = await makeInstanceRoot();
144
+ const env = envFor(home);
145
+ const entryPath = await ensureCodexAuthCacheEntryDir(env, "acct-priv", "company-a");
146
+ const entryDir = path.dirname(entryPath);
147
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
148
+ expect((await lstat(entryDir)).mode & 0o777).toBe(0o700);
149
+ expect((await lstat(cacheDir)).mode & 0o777).toBe(0o700);
150
+ });
151
+ it("the cache root fails closed (lstat) when it is a symlink or a non-directory", async () => {
152
+ const home = await makeInstanceRoot();
153
+ const env = envFor(home);
154
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
155
+ // Make the cache root a symlink to another directory. lstat (not stat)
156
+ // must catch it and fail closed.
157
+ await mkdir(path.dirname(cacheDir), { recursive: true });
158
+ const target = path.join(home, "elsewhere");
159
+ await mkdir(target, { recursive: true });
160
+ await symlink(target, cacheDir);
161
+ await expect(ensureCodexAuthCacheEntryDir(env, "acct-x", "company-a")).rejects.toThrow();
162
+ });
163
+ it("the entry directory fails closed (lstat) when it is a symlink or a non-directory", async () => {
164
+ const home = await makeInstanceRoot();
165
+ const env = envFor(home);
166
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
167
+ await mkdir(cacheDir, { recursive: true, mode: 0o700 });
168
+ // Put a regular file where the entry directory must be.
169
+ await writeFile(path.join(cacheDir, "acct-file"), "not a dir", { mode: 0o600 });
170
+ await expect(ensureCodexAuthCacheEntryDir(env, "acct-file", "company-a")).rejects.toThrow();
171
+ });
172
+ });
173
+ describe("Phase 4: identity-anchored vend", () => {
174
+ async function stageHostAndCache(input) {
175
+ const home = await makeInstanceRoot();
176
+ const env = envFor(home, { CODEX_HOME: path.join(home, "shared-codex") });
177
+ const sharedHome = resolveSharedCodexHomeDir(env);
178
+ await mkdir(sharedHome, { recursive: true });
179
+ const sharedHomeAuthPath = path.join(sharedHome, "auth.json");
180
+ if (input.hostAuth !== undefined) {
181
+ await writeFile(sharedHomeAuthPath, input.hostAuth, { mode: 0o600 });
182
+ }
183
+ for (const [accountId, auth] of Object.entries(input.cacheAuthByAccount ?? {})) {
184
+ const entryPath = await ensureCodexAuthCacheEntryDir(env, accountId, "company-a");
185
+ await writeFile(entryPath, auth, { mode: 0o600 });
186
+ }
187
+ return { env, sharedHomeAuthPath };
188
+ }
189
+ const resolveEntry = (env) => (accountId) => resolveCodexAuthCacheEntryPath(env, accountId, "company-a");
190
+ it("vend refreshes the host identity when the cached copy is strictly newer for the same identity", async () => {
191
+ const { env, sharedHomeAuthPath } = await stageHostAndCache({
192
+ hostAuth: subscriptionAuth({ accountId: "acct-x", lastRefresh: OLDER, marker: "host" }),
193
+ cacheAuthByAccount: {
194
+ "acct-x": subscriptionAuth({ accountId: "acct-x", lastRefresh: NEWER, marker: "cache" }),
195
+ },
196
+ });
197
+ const outcome = await selectVendCredential(sharedHomeAuthPath, resolveEntry(env), () => undefined, env);
198
+ expect(outcome).toBe("vended");
199
+ const finalHost = await readFile(sharedHomeAuthPath, "utf8");
200
+ expect(finalHost).toContain("acct-x");
201
+ expect(finalHost).toContain("cache");
202
+ });
203
+ it("vend keeps the shared-home credential when the cache copy is older or a tie", async () => {
204
+ for (const cacheRefresh of [OLDER, NEWER]) {
205
+ const hostRefresh = cacheRefresh === OLDER ? NEWER : NEWER; // host newer or tie
206
+ const { env, sharedHomeAuthPath } = await stageHostAndCache({
207
+ hostAuth: subscriptionAuth({ accountId: "acct-x", lastRefresh: hostRefresh, marker: "host" }),
208
+ cacheAuthByAccount: {
209
+ "acct-x": subscriptionAuth({ accountId: "acct-x", lastRefresh: cacheRefresh, marker: "cache" }),
210
+ },
211
+ });
212
+ const before = await readFile(sharedHomeAuthPath, "utf8");
213
+ const outcome = await selectVendCredential(sharedHomeAuthPath, resolveEntry(env), () => undefined, env);
214
+ expect(outcome).toBe("kept-host");
215
+ expect(await readFile(sharedHomeAuthPath, "utf8")).toBe(before);
216
+ }
217
+ });
218
+ it("vend never selects a cache slot with a different account_id than the host holds", async () => {
219
+ const { env, sharedHomeAuthPath } = await stageHostAndCache({
220
+ hostAuth: subscriptionAuth({ accountId: "acct-x", lastRefresh: OLDER, marker: "host" }),
221
+ cacheAuthByAccount: {
222
+ "acct-y": subscriptionAuth({ accountId: "acct-y", lastRefresh: NEWER, marker: "other" }),
223
+ },
224
+ });
225
+ const before = await readFile(sharedHomeAuthPath, "utf8");
226
+ const outcome = await selectVendCredential(sharedHomeAuthPath, resolveEntry(env), () => undefined, env);
227
+ expect(outcome).toBe("kept-host");
228
+ expect(await readFile(sharedHomeAuthPath, "utf8")).toBe(before);
229
+ });
230
+ it("vend does nothing when the host shared home has no auth.json (no random pick from the cache)", async () => {
231
+ const { env, sharedHomeAuthPath } = await stageHostAndCache({
232
+ cacheAuthByAccount: {
233
+ "acct-y": subscriptionAuth({ accountId: "acct-y", lastRefresh: NEWER, marker: "other" }),
234
+ },
235
+ });
236
+ const outcome = await selectVendCredential(sharedHomeAuthPath, resolveEntry(env), () => undefined, env);
237
+ expect(outcome).toBe("no-host-identity");
238
+ await expect(lstat(sharedHomeAuthPath)).rejects.toThrow();
239
+ });
240
+ it("vend does nothing when the host shared home holds an apikey (no subscription identity)", async () => {
241
+ const { env, sharedHomeAuthPath } = await stageHostAndCache({
242
+ hostAuth: JSON.stringify({ OPENAI_API_KEY: "sk-host" }),
243
+ cacheAuthByAccount: {
244
+ "acct-y": subscriptionAuth({ accountId: "acct-y", lastRefresh: NEWER, marker: "other" }),
245
+ },
246
+ });
247
+ const before = await readFile(sharedHomeAuthPath, "utf8");
248
+ const outcome = await selectVendCredential(sharedHomeAuthPath, resolveEntry(env), () => undefined, env);
249
+ expect(outcome).toBe("no-host-identity");
250
+ expect(await readFile(sharedHomeAuthPath, "utf8")).toBe(before);
251
+ });
252
+ it("the vend never emits token bytes or a raw account_id to the log", async () => {
253
+ const { env, sharedHomeAuthPath } = await stageHostAndCache({
254
+ hostAuth: subscriptionAuth({ accountId: "SECRET-ACCT", lastRefresh: OLDER, marker: "HOST-SENTINEL" }),
255
+ cacheAuthByAccount: {
256
+ "SECRET-ACCT": subscriptionAuth({ accountId: "SECRET-ACCT", lastRefresh: NEWER, marker: "CACHE-SENTINEL" }),
257
+ },
258
+ });
259
+ const logs = [];
260
+ await selectVendCredential(sharedHomeAuthPath, resolveEntry(env), (line) => {
261
+ logs.push(line);
262
+ }, env);
263
+ const combined = logs.join("\n");
264
+ expect(combined).not.toContain("SENTINEL");
265
+ expect(combined).not.toContain("SECRET-ACCT");
266
+ expect(combined).not.toContain("id-token");
267
+ });
268
+ });
269
+ describe("Phase 5: cache-clear operator action and off-switch", () => {
270
+ it("clearCodexAuthCacheEntry removes one identity slot and leaves other slots intact", async () => {
271
+ const home = await makeInstanceRoot();
272
+ const env = envFor(home);
273
+ const keepPath = await ensureCodexAuthCacheEntryDir(env, "acct-keep", "company-a");
274
+ const dropPath = await ensureCodexAuthCacheEntryDir(env, "acct-drop", "company-a");
275
+ await writeFile(keepPath, subscriptionAuth({ accountId: "acct-keep" }), { mode: 0o600 });
276
+ await writeFile(dropPath, subscriptionAuth({ accountId: "acct-drop" }), { mode: 0o600 });
277
+ await clearCodexAuthCacheEntry(env, "acct-drop", "company-a");
278
+ await expect(lstat(path.dirname(dropPath))).rejects.toThrow();
279
+ expect(await readFile(keepPath, "utf8")).toContain("acct-keep");
280
+ });
281
+ it("clearCodexAuthCacheEntry rejects an account_id that escapes the cache root", async () => {
282
+ const home = await makeInstanceRoot();
283
+ const env = envFor(home);
284
+ await expect(clearCodexAuthCacheEntry(env, "../../etc", "company-a")).rejects.toThrow();
285
+ await expect(clearCodexAuthCacheEntry(env, "a/b", "company-a")).rejects.toThrow();
286
+ });
287
+ it("clearCodexAuthCacheEntry is a benign no-op for a missing slot", async () => {
288
+ const home = await makeInstanceRoot();
289
+ const env = envFor(home);
290
+ await expect(clearCodexAuthCacheEntry(env, "acct-absent", "company-a")).resolves.toBeUndefined();
291
+ });
292
+ it("clearCodexAuthCache removes every slot", async () => {
293
+ const home = await makeInstanceRoot();
294
+ const env = envFor(home);
295
+ await ensureCodexAuthCacheEntryDir(env, "acct-1", "company-a");
296
+ await ensureCodexAuthCacheEntryDir(env, "acct-2", "company-a");
297
+ const cacheDir = resolveCodexAuthCacheDir(env, "company-a");
298
+ expect((await readdir(cacheDir)).sort()).toEqual(["acct-1", "acct-2"]);
299
+ await clearCodexAuthCache(env, "company-a");
300
+ await expect(lstat(cacheDir)).rejects.toThrow();
301
+ });
302
+ it("isCodexAuthCacheEnabled defaults to on and turns off on an explicit falsy flag", () => {
303
+ expect(isCodexAuthCacheEnabled({})).toBe(true);
304
+ expect(isCodexAuthCacheEnabled({ PAPERCLIP_CODEX_AUTH_CACHE: "1" })).toBe(true);
305
+ expect(isCodexAuthCacheEnabled({ PAPERCLIP_CODEX_AUTH_CACHE: "on" })).toBe(true);
306
+ expect(isCodexAuthCacheEnabled({ PAPERCLIP_CODEX_AUTH_CACHE: "0" })).toBe(false);
307
+ expect(isCodexAuthCacheEnabled({ PAPERCLIP_CODEX_AUTH_CACHE: "false" })).toBe(false);
308
+ expect(isCodexAuthCacheEnabled({ PAPERCLIP_CODEX_AUTH_CACHE: "off" })).toBe(false);
309
+ expect(isCodexAuthCacheEnabled({ PAPERCLIP_CODEX_AUTH_CACHE: "no" })).toBe(false);
310
+ });
311
+ });
312
+ describe("Phase 6: whole-promotion serialization for one company", () => {
313
+ it("withCodexAccountHomePromotionLock never overlaps two concurrent callers for the same company", async () => {
314
+ // The device-login route holds this lock across its whole promotion
315
+ // sequence: the account-home directory decision, the credential write,
316
+ // and the secret bind or cleanup that follows. Two different logins for
317
+ // the SAME Codex account must run that whole sequence one at a time, so
318
+ // a login can never delete the shared account-home directory while
319
+ // another login's own sequence is still writing its credential or
320
+ // binding its own secret to that same directory. This proves the lock
321
+ // itself enforces that: two concurrent callers for one company never run
322
+ // their callbacks at the same time, whichever caller goes first.
323
+ const home = await makeInstanceRoot();
324
+ const env = envFor(home);
325
+ const events = [];
326
+ let releaseFirstCaller;
327
+ const firstCallerGate = new Promise((resolve) => {
328
+ releaseFirstCaller = resolve;
329
+ });
330
+ const firstCall = withCodexAccountHomePromotionLock(env, "company-shared", async () => {
331
+ events.push("first-enter");
332
+ await firstCallerGate;
333
+ events.push("first-exit");
334
+ return "first";
335
+ });
336
+ // Give the first caller a chance to acquire the lock and enter its
337
+ // callback before the second caller starts racing for the same lock.
338
+ await new Promise((resolve) => setTimeout(resolve, 20));
339
+ const secondCall = withCodexAccountHomePromotionLock(env, "company-shared", async () => {
340
+ events.push("second-enter");
341
+ events.push("second-exit");
342
+ return "second";
343
+ });
344
+ // The second caller must stay blocked on the lock while the first
345
+ // caller still holds it: it must never log `second-enter` before the
346
+ // first caller's `first-exit`.
347
+ await new Promise((resolve) => setTimeout(resolve, 20));
348
+ expect(events).toEqual(["first-enter"]);
349
+ releaseFirstCaller();
350
+ const [first, second] = await Promise.all([firstCall, secondCall]);
351
+ expect(first).toBe("first");
352
+ expect(second).toBe("second");
353
+ expect(events).toEqual(["first-enter", "first-exit", "second-enter", "second-exit"]);
354
+ });
355
+ it("withCodexAccountHomePromotionLock keeps two different companies independent", async () => {
356
+ // The lock is per company, so two different companies' device logins
357
+ // never wait on each other.
358
+ const home = await makeInstanceRoot();
359
+ const env = envFor(home);
360
+ const events = [];
361
+ let releaseCompanyA;
362
+ const companyAGate = new Promise((resolve) => {
363
+ releaseCompanyA = resolve;
364
+ });
365
+ const companyACall = withCodexAccountHomePromotionLock(env, "company-a", async () => {
366
+ events.push("a-enter");
367
+ await companyAGate;
368
+ events.push("a-exit");
369
+ });
370
+ await new Promise((resolve) => setTimeout(resolve, 20));
371
+ const companyBCall = withCodexAccountHomePromotionLock(env, "company-b", async () => {
372
+ events.push("b-enter");
373
+ events.push("b-exit");
374
+ });
375
+ await companyBCall;
376
+ // Company B's callback ran and finished while company A's callback was
377
+ // still waiting on its own gate, so the two locks never contended.
378
+ expect(events).toEqual(["a-enter", "b-enter", "b-exit"]);
379
+ releaseCompanyA();
380
+ await companyACall;
381
+ expect(events).toEqual(["a-enter", "b-enter", "b-exit", "a-exit"]);
382
+ });
383
+ });
384
+ describe("Phase 7: account-home secret-mutation serialization for one company", () => {
385
+ it("withAccountHomeSecretMutationLock never overlaps two concurrent callers for the same company", async () => {
386
+ // The secrets service holds this lock for the whole of a `local_encrypted`
387
+ // secret's create or rotate call, and an account-home cleanup's claimant
388
+ // scan holds it for the whole of its final check-and-delete step. This
389
+ // proves the lock itself enforces mutual exclusion between any two
390
+ // holders for one company, whichever caller goes first.
391
+ const home = await makeInstanceRoot();
392
+ const env = envFor(home);
393
+ const events = [];
394
+ let releaseFirstCaller;
395
+ const firstCallerGate = new Promise((resolve) => {
396
+ releaseFirstCaller = resolve;
397
+ });
398
+ const firstCall = withAccountHomeSecretMutationLock(env, "company-shared", async () => {
399
+ events.push("first-enter");
400
+ await firstCallerGate;
401
+ events.push("first-exit");
402
+ return "first";
403
+ });
404
+ await new Promise((resolve) => setTimeout(resolve, 20));
405
+ const secondCall = withAccountHomeSecretMutationLock(env, "company-shared", async () => {
406
+ events.push("second-enter");
407
+ events.push("second-exit");
408
+ return "second";
409
+ });
410
+ // The second caller must stay blocked on the lock while the first
411
+ // caller still holds it: it must never log `second-enter` before the
412
+ // first caller's `first-exit`.
413
+ await new Promise((resolve) => setTimeout(resolve, 20));
414
+ expect(events).toEqual(["first-enter"]);
415
+ releaseFirstCaller();
416
+ const [first, second] = await Promise.all([firstCall, secondCall]);
417
+ expect(first).toBe("first");
418
+ expect(second).toBe("second");
419
+ expect(events).toEqual(["first-enter", "first-exit", "second-enter", "second-exit"]);
420
+ });
421
+ it("withAccountHomeSecretMutationLock keeps two different companies independent", async () => {
422
+ const home = await makeInstanceRoot();
423
+ const env = envFor(home);
424
+ const events = [];
425
+ let releaseCompanyA;
426
+ const companyAGate = new Promise((resolve) => {
427
+ releaseCompanyA = resolve;
428
+ });
429
+ const companyACall = withAccountHomeSecretMutationLock(env, "company-a", async () => {
430
+ events.push("a-enter");
431
+ await companyAGate;
432
+ events.push("a-exit");
433
+ });
434
+ await new Promise((resolve) => setTimeout(resolve, 20));
435
+ const companyBCall = withAccountHomeSecretMutationLock(env, "company-b", async () => {
436
+ events.push("b-enter");
437
+ events.push("b-exit");
438
+ });
439
+ await companyBCall;
440
+ expect(events).toEqual(["a-enter", "b-enter", "b-exit"]);
441
+ releaseCompanyA();
442
+ await companyACall;
443
+ expect(events).toEqual(["a-enter", "b-enter", "b-exit", "a-exit"]);
444
+ });
445
+ it("withAccountHomeSecretMutationLock does not contend with withCodexAccountHomePromotionLock for the same company", async () => {
446
+ // The two locks use separate lock directories (Security condition: no
447
+ // shared lock key), so a device-login promotion that holds
448
+ // `withCodexAccountHomePromotionLock` for its whole sequence can still
449
+ // call into a secrets-service write that takes this lock without
450
+ // deadlocking on itself.
451
+ const home = await makeInstanceRoot();
452
+ const env = envFor(home);
453
+ const events = [];
454
+ await withCodexAccountHomePromotionLock(env, "company-shared", async () => {
455
+ events.push("promotion-enter");
456
+ await withAccountHomeSecretMutationLock(env, "company-shared", async () => {
457
+ events.push("mutation-enter");
458
+ events.push("mutation-exit");
459
+ });
460
+ events.push("promotion-exit");
461
+ });
462
+ expect(events).toEqual(["promotion-enter", "mutation-enter", "mutation-exit", "promotion-exit"]);
463
+ });
464
+ });
465
+ describe("Phase 8: account-home directory validity before a secret write commits", () => {
466
+ it("resolves for a value naming a directory that still exists under the cache root", async () => {
467
+ const home = await makeInstanceRoot();
468
+ const env = envFor(home);
469
+ const companyId = "company-still-exists";
470
+ const entryPath = await ensureCodexAuthCacheEntryDir(env, "acct-still-exists", companyId);
471
+ const accountHomeDir = path.dirname(entryPath);
472
+ await expect(assertAccountHomeCacheDirStillValid(env, companyId, accountHomeDir)).resolves.toBeUndefined();
473
+ });
474
+ it("rejects a value naming a directory under the cache root that no longer exists", async () => {
475
+ // This is the shape an account-home cleanup leaves behind: a value that
476
+ // once named a real directory, now removed. A create or a rotate that
477
+ // is about to commit this exact value must fail instead of writing a
478
+ // secret that points at nothing.
479
+ const home = await makeInstanceRoot();
480
+ const env = envFor(home);
481
+ const companyId = "company-removed";
482
+ const entryPath = await ensureCodexAuthCacheEntryDir(env, "acct-removed", companyId);
483
+ const accountHomeDir = path.dirname(entryPath);
484
+ await rm(accountHomeDir, { recursive: true, force: true });
485
+ await expect(assertAccountHomeCacheDirStillValid(env, companyId, accountHomeDir)).rejects.toThrow(/no longer exists/);
486
+ });
487
+ it("leaves a value alone when it does not sit under this company's cache root", async () => {
488
+ // Most `local_encrypted` secret values (an API key, a token, a
489
+ // hand-typed string) never sit under the cache root, so this check must
490
+ // never reject a write that only happens to name a missing path.
491
+ const home = await makeInstanceRoot();
492
+ const env = envFor(home);
493
+ await expect(assertAccountHomeCacheDirStillValid(env, "company-unrelated", "/some/unrelated/missing/path")).resolves.toBeUndefined();
494
+ });
495
+ });
496
+ });
497
+ //# sourceMappingURL=codex-auth-cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-auth-cache.test.js","sourceRoot":"","sources":["../../src/server/codex-auth-cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /** Outcome of a copy-back attempt. No token material is ever surfaced. */
2
+ export type CopyBackCodexAuthOutcome = "copied" | "kept-host";
3
+ export interface CopyBackCodexAuthInput {
4
+ /**
5
+ * Reads the sandbox `auth.json` bytes back from the (about-to-be-destroyed)
6
+ * sandbox. In production this is bound to the managed-runtime restore
7
+ * context's `readFile` for `${assetDir}/auth.json`.
8
+ */
9
+ readSandboxAuth: () => Promise<Buffer>;
10
+ /**
11
+ * Absolute path of the shared host credential to (maybe) overwrite — the
12
+ * symlink *source* the managed Codex homes point their `auth.json` at, never
13
+ * an in-sandbox or per-agent symlink.
14
+ */
15
+ hostAuthPath: string;
16
+ /** Non-leaking progress sink: receives decision/outcome lines only. */
17
+ log: (line: string) => void | Promise<void>;
18
+ /**
19
+ * Resolves and ensures the per-identity cache slot path for a sandbox
20
+ * `account_id`. When this is provided AND the cache off-switch is on, the
21
+ * copy-back also writes the fresher, usable subscription credential into its
22
+ * per-identity cache slot as a second, additive write, keyed by the real
23
+ * `account_id`. This is independent of the host default overwrite: it can
24
+ * write a cache slot for a different identity than the host holds (matrix rows
25
+ * 1b, 3), and it never touches the host default store. When absent, no cache
26
+ * write happens.
27
+ */
28
+ resolveCacheEntryPath?: (accountId: string) => Promise<string>;
29
+ /** Environment for the cache off-switch read. Defaults to `process.env`. */
30
+ env?: NodeJS.ProcessEnv;
31
+ }
32
+ /**
33
+ * Guards, locks, and atomically installs a strictly-newer sandbox Codex
34
+ * `auth.json` onto the shared host credential at teardown.
35
+ *
36
+ * Sequence, all under `withDirectoryMergeLock` on the host target's directory
37
+ * so a concurrent inbound restore or another copy-back can't interleave:
38
+ * 1. Read the sandbox credential bytes. A genuinely absent sandbox
39
+ * `auth.json` (ENOENT) means there is simply nothing to copy back, so it
40
+ * resolves to `kept-host` (benign no-op, host untouched); every other read
41
+ * error stays fail-loud.
42
+ * 2. Stage them to a `0600` temp file on the **same filesystem** as the host
43
+ * target (its directory), which doubles as the predicate `source`.
44
+ * 3. Run the Phase-3 decision predicate (`source` = sandbox temp, `destination`
45
+ * = host). Exit 10 → adopt the sandbox copy; exit 20 → keep the host copy.
46
+ * 4. On exit 10, `rename` the staged temp over the host target — an atomic
47
+ * same-directory swap that preserves mode `0600`. On exit 20, discard it.
48
+ * The staged temp is always removed (rename consumes it on the copy path; the
49
+ * finally cleans it up otherwise), so a failure never leaves a partial file.
50
+ * Never logs token bytes — only the decision outcome.
51
+ */
52
+ export declare function copyBackCodexAuth(input: CopyBackCodexAuthInput): Promise<CopyBackCodexAuthOutcome>;
53
+ //# sourceMappingURL=codex-auth-copyback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-auth-copyback.d.ts","sourceRoot":"","sources":["../../src/server/codex-auth-copyback.ts"],"names":[],"mappings":"AAyBA,0EAA0E;AAC1E,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;;;;;;OASG;IACH,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAmHxG"}