@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,245 @@
1
+ import { chmod, lstat, mkdir, mkdtemp, readFile, rm, stat, 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 { MAX_AUTH_JSON_BYTES, deriveProofHome, installDeviceLoginCredential, removeProofHome, resolveProofHomeRoot, } from "./device-login-export.js";
6
+ import { resolveManagedCodexHomeDir, resolveSharedCodexHomeDir } from "./codex-home.js";
7
+ const COMPANY = "company-a";
8
+ const RUN = "run-1234";
9
+ const NEWER = "2026-07-09T02:00:00Z";
10
+ const OLDER = "2026-07-09T01:00:00Z";
11
+ const ACCOUNT = "acct-42";
12
+ const OTHER_ACCOUNT = "acct-99";
13
+ const TOKEN_SENTINEL = "SENTINEL_TOKEN_XYZ";
14
+ describe("device-login credential export", () => {
15
+ const cleanupDirs = [];
16
+ afterEach(async () => {
17
+ while (cleanupDirs.length > 0) {
18
+ const dir = cleanupDirs.pop();
19
+ if (!dir)
20
+ continue;
21
+ await chmod(dir, 0o700).catch(() => undefined);
22
+ await rm(dir, { recursive: true, force: true }).catch(() => undefined);
23
+ }
24
+ });
25
+ async function makeInstanceRoot() {
26
+ const dir = await mkdtemp(path.join(os.tmpdir(), "paperclip-codex-proof-"));
27
+ cleanupDirs.push(dir);
28
+ return dir;
29
+ }
30
+ function envFor(instanceHome, extra = {}) {
31
+ return { PAPERCLIP_HOME: instanceHome, PAPERCLIP_INSTANCE_ID: "default", ...extra };
32
+ }
33
+ function subscriptionAuth(input) {
34
+ const suffix = input.marker ?? input.accountId;
35
+ return Buffer.from(JSON.stringify({
36
+ tokens: {
37
+ id_token: `id-token-${suffix}`,
38
+ access_token: `access-token-${suffix}`,
39
+ refresh_token: `${TOKEN_SENTINEL}-${suffix}`,
40
+ account_id: input.accountId,
41
+ },
42
+ ...(input.lastRefresh ? { last_refresh: input.lastRefresh } : {}),
43
+ }));
44
+ }
45
+ const noopLog = (_line) => { };
46
+ it("deriveProofHome returns a unique, run-scoped path under a company-scoped root", async () => {
47
+ const home = await makeInstanceRoot();
48
+ const env = envFor(home);
49
+ const root = resolveProofHomeRoot(env, COMPANY);
50
+ expect(root).toBe(path.resolve(home, "instances", "default", "companies", COMPANY, "codex-device-login-proof"));
51
+ const a = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
52
+ const b = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
53
+ expect(a.startsWith(root + path.sep)).toBe(true);
54
+ expect(a).toContain(RUN);
55
+ expect(a).not.toBe(b); // unique per call
56
+ // Never the shared or the managed home.
57
+ expect(a).not.toBe(resolveSharedCodexHomeDir(env));
58
+ expect(a).not.toBe(resolveManagedCodexHomeDir(env, COMPANY));
59
+ });
60
+ it("export_creates_root_and_home_at_mode_0700", async () => {
61
+ const home = await makeInstanceRoot();
62
+ const env = envFor(home);
63
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
64
+ await installDeviceLoginCredential({
65
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER }),
66
+ proofHome,
67
+ env,
68
+ companyId: COMPANY,
69
+ log: noopLog,
70
+ });
71
+ const root = resolveProofHomeRoot(env, COMPANY);
72
+ expect((await stat(root)).mode & 0o777).toBe(0o700);
73
+ expect((await stat(proofHome)).mode & 0o777).toBe(0o700);
74
+ });
75
+ it("export_seeds_empty_proof_home_with_mode_0600", async () => {
76
+ const home = await makeInstanceRoot();
77
+ const env = envFor(home);
78
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
79
+ const outcome = await installDeviceLoginCredential({
80
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER }),
81
+ proofHome,
82
+ env,
83
+ companyId: COMPANY,
84
+ log: noopLog,
85
+ });
86
+ expect(outcome).toBe("seeded");
87
+ const authPath = path.join(proofHome, "auth.json");
88
+ expect((await stat(authPath)).mode & 0o777).toBe(0o600);
89
+ const written = JSON.parse(await readFile(authPath, "utf8"));
90
+ expect(written.tokens.account_id).toBe(ACCOUNT);
91
+ });
92
+ it("export_rejects_default_shared_and_managed_home", async () => {
93
+ const home = await makeInstanceRoot();
94
+ const env = envFor(home, { CODEX_HOME: path.join(home, "shared-codex") });
95
+ const bytes = subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER });
96
+ const shared = resolveSharedCodexHomeDir(env);
97
+ const managed = resolveManagedCodexHomeDir(env, COMPANY);
98
+ const agentManaged = path.resolve(managed, "..", "agents", "agent-1", "codex-home");
99
+ for (const target of [shared, managed, agentManaged]) {
100
+ await expect(installDeviceLoginCredential({ sandboxAuthBytes: bytes, proofHome: target, env, companyId: COMPANY, log: noopLog })).rejects.toThrow();
101
+ }
102
+ });
103
+ it("export_rejects_symlink_or_non_regular_path", async () => {
104
+ const home = await makeInstanceRoot();
105
+ const env = envFor(home);
106
+ const root = resolveProofHomeRoot(env, COMPANY);
107
+ await mkdir(root, { recursive: true, mode: 0o700 });
108
+ const bytes = subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER });
109
+ // A symlinked proof home is rejected.
110
+ const realDir = path.join(home, "elsewhere");
111
+ await mkdir(realDir, { recursive: true, mode: 0o700 });
112
+ const linkedHome = path.join(root, `${RUN}-linked`);
113
+ await symlink(realDir, linkedHome);
114
+ await expect(installDeviceLoginCredential({ sandboxAuthBytes: bytes, proofHome: linkedHome, env, companyId: COMPANY, log: noopLog })).rejects.toThrow();
115
+ // A proof home whose auth.json is a symlink is rejected.
116
+ const symAuthHome = path.join(root, `${RUN}-symauth`);
117
+ await mkdir(symAuthHome, { recursive: true, mode: 0o700 });
118
+ await symlink(path.join(home, "target.json"), path.join(symAuthHome, "auth.json"));
119
+ await expect(installDeviceLoginCredential({ sandboxAuthBytes: bytes, proofHome: symAuthHome, env, companyId: COMPANY, log: noopLog })).rejects.toThrow();
120
+ });
121
+ it("export_rejects_api_key_malformed_or_oversized_payload", async () => {
122
+ const home = await makeInstanceRoot();
123
+ const env = envFor(home);
124
+ const apiKey = Buffer.from(JSON.stringify({ OPENAI_API_KEY: "sk-secret-key" }));
125
+ const malformed = Buffer.from("this is not json {");
126
+ const oversized = Buffer.concat([
127
+ subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER }),
128
+ Buffer.alloc(MAX_AUTH_JSON_BYTES + 10, 0x20),
129
+ ]);
130
+ for (const bytes of [apiKey, malformed, oversized]) {
131
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
132
+ await expect(installDeviceLoginCredential({ sandboxAuthBytes: bytes, proofHome, env, companyId: COMPANY, log: noopLog })).rejects.toThrow();
133
+ // No file was written on a rejected payload.
134
+ await expect(stat(path.join(proofHome, "auth.json"))).rejects.toThrow();
135
+ }
136
+ });
137
+ it("export_updates_home_with_strictly_newer_same_identity", async () => {
138
+ const home = await makeInstanceRoot();
139
+ const env = envFor(home);
140
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
141
+ const authPath = path.join(proofHome, "auth.json");
142
+ await installDeviceLoginCredential({
143
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: OLDER, marker: "old" }),
144
+ proofHome,
145
+ env,
146
+ companyId: COMPANY,
147
+ log: noopLog,
148
+ });
149
+ const outcome = await installDeviceLoginCredential({
150
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER, marker: "new" }),
151
+ proofHome,
152
+ env,
153
+ companyId: COMPANY,
154
+ log: noopLog,
155
+ });
156
+ expect(outcome).toBe("updated");
157
+ const written = JSON.parse(await readFile(authPath, "utf8"));
158
+ expect(written.last_refresh).toBe(NEWER);
159
+ expect(written.tokens.refresh_token).toContain("new");
160
+ });
161
+ it("export_keeps_home_on_older_or_different_identity", async () => {
162
+ const home = await makeInstanceRoot();
163
+ const env = envFor(home);
164
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
165
+ const authPath = path.join(proofHome, "auth.json");
166
+ await installDeviceLoginCredential({
167
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER, marker: "keep" }),
168
+ proofHome,
169
+ env,
170
+ companyId: COMPANY,
171
+ log: noopLog,
172
+ });
173
+ // Older same identity: kept.
174
+ const olderOutcome = await installDeviceLoginCredential({
175
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: OLDER, marker: "older" }),
176
+ proofHome,
177
+ env,
178
+ companyId: COMPANY,
179
+ log: noopLog,
180
+ });
181
+ expect(olderOutcome).toBe("kept");
182
+ // Different identity, even newer: kept.
183
+ const otherOutcome = await installDeviceLoginCredential({
184
+ sandboxAuthBytes: subscriptionAuth({ accountId: OTHER_ACCOUNT, lastRefresh: NEWER, marker: "other" }),
185
+ proofHome,
186
+ env,
187
+ companyId: COMPANY,
188
+ log: noopLog,
189
+ });
190
+ expect(otherOutcome).toBe("kept");
191
+ const written = JSON.parse(await readFile(authPath, "utf8"));
192
+ expect(written.tokens.account_id).toBe(ACCOUNT);
193
+ expect(written.tokens.refresh_token).toContain("keep");
194
+ });
195
+ it("export_logs_contain_no_token_bytes", async () => {
196
+ const home = await makeInstanceRoot();
197
+ const env = envFor(home);
198
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
199
+ const logs = [];
200
+ await installDeviceLoginCredential({
201
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER }),
202
+ proofHome,
203
+ env,
204
+ companyId: COMPANY,
205
+ log: (line) => {
206
+ logs.push(line);
207
+ },
208
+ });
209
+ const haystack = logs.join("\n");
210
+ expect(haystack).not.toContain(TOKEN_SENTINEL);
211
+ expect(haystack).not.toContain(ACCOUNT);
212
+ });
213
+ it("cleanup_removes_proof_home_and_leaves_default_home_unchanged", async () => {
214
+ const home = await makeInstanceRoot();
215
+ const env = envFor(home, { CODEX_HOME: path.join(home, "shared-codex") });
216
+ // A sentinel in a fake shared/default home must survive the cleanup.
217
+ const shared = resolveSharedCodexHomeDir(env);
218
+ await mkdir(shared, { recursive: true, mode: 0o700 });
219
+ const sentinel = path.join(shared, "auth.json");
220
+ await writeFile(sentinel, JSON.stringify({ tokens: { account_id: "host", refresh_token: "host" } }), { mode: 0o600 });
221
+ const proofHome = deriveProofHome({ env, companyId: COMPANY, runId: RUN });
222
+ await installDeviceLoginCredential({
223
+ sandboxAuthBytes: subscriptionAuth({ accountId: ACCOUNT, lastRefresh: NEWER }),
224
+ proofHome,
225
+ env,
226
+ companyId: COMPANY,
227
+ log: noopLog,
228
+ });
229
+ expect((await lstat(proofHome)).isDirectory()).toBe(true);
230
+ await removeProofHome(proofHome, { env, companyId: COMPANY });
231
+ await expect(lstat(proofHome)).rejects.toThrow();
232
+ // The fake default home is untouched.
233
+ expect(await readFile(sentinel, "utf8")).toContain("host");
234
+ });
235
+ it("removeProofHome refuses a path outside the proof root", async () => {
236
+ const home = await makeInstanceRoot();
237
+ const env = envFor(home);
238
+ const outside = path.join(home, "not-a-proof-home");
239
+ await mkdir(outside, { recursive: true });
240
+ await expect(removeProofHome(outside, { env, companyId: COMPANY })).rejects.toThrow();
241
+ // The outside directory is untouched.
242
+ expect((await lstat(outside)).isDirectory()).toBe(true);
243
+ });
244
+ });
245
+ //# sourceMappingURL=device-login-export.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-login-export.test.js","sourceRoot":"","sources":["../../src/server/device-login-export.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface DeviceLoginPrompt {
2
+ url: string;
3
+ code: string;
4
+ }
5
+ export declare const DEVICE_LOGIN_URL = "https://auth.openai.com/codex/device";
6
+ /**
7
+ * Parses Codex device-login output. Removes ANSI color sequences first, so
8
+ * colored output from Codex CLI 0.128.0 and later reads the same as plain
9
+ * output. The parser reads the URL first, then finds the "one-time code"
10
+ * preamble after the URL, then reads the code from the dedicated code line right
11
+ * after the preamble line. So the code binds to the prompt line that introduces
12
+ * it, and a code-shaped token between the URL and the preamble, on the preamble
13
+ * line, or mixed with other text on a later line, cannot form a prompt. Returns
14
+ * the login URL and the one-time code when both are present and valid. Returns
15
+ * null for any other input, including a non-string input, an absent prompt, a URL
16
+ * with a query or a fragment, a wrong origin or path, and a malformed short code.
17
+ * Never throws on input, and never puts the URL or the code into a log or an error.
18
+ */
19
+ export declare function parseDeviceLoginPrompt(text: string): DeviceLoginPrompt | null;
20
+ //# sourceMappingURL=device-login-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-login-parse.d.ts","sourceRoot":"","sources":["../../src/server/device-login-parse.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAID,eAAO,MAAM,gBAAgB,yCAAyC,CAAC;AAgIvE;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAQ7E"}
@@ -0,0 +1,155 @@
1
+ // The device-login output parser. It reads the Codex `login --device-auth`
2
+ // output and returns the login URL and the one-time code, or null.
3
+ //
4
+ // Security (Control 1 — strict validation): the parser accepts only the exact
5
+ // origin and path of the device-login URL. It rejects any query, any fragment, a
6
+ // different origin, and a different path. It accepts only the short-code
7
+ // structure `XXXX-XXXXX` (four characters, a hyphen, then five characters). The
8
+ // parser never logs the URL, the code, or any input byte, and it keeps them out
9
+ // of every thrown error. The parser is a pure function.
10
+ //
11
+ // The parser returns the printed URL after the platform `URL` parser validates
12
+ // and normalizes it. It never returns the raw matched token: the accepting
13
+ // rules above already bound the token to the exact origin, path, and empty
14
+ // query and fragment, so the normalized form carries no unvalidated byte.
15
+ // The one and only accepted device-login origin and path. `findExactDeviceUrl`
16
+ // checks a candidate token against these exact values before it accepts it.
17
+ export const DEVICE_LOGIN_URL = "https://auth.openai.com/codex/device";
18
+ // Codex CLI 0.128.0 and later wrap the login URL and the one-time code in ANSI
19
+ // color sequences. A color sequence is a Control Sequence Introducer (CSI): the
20
+ // ESC control byte, a `[`, zero or more parameter bytes (0x30-0x3F), zero or
21
+ // more intermediate bytes (0x20-0x2F), and one final byte (0x40-0x7E). The
22
+ // parser removes every CSI sequence first, so a colored URL or code reads the
23
+ // same as a plain one. The strip only normalizes the input; the URL and the
24
+ // code still pass the strict validation below.
25
+ // eslint-disable-next-line no-control-regex
26
+ const ANSI_CSI_RE = /\x1b\[[0-?]*[ -/]*[@-~]/g;
27
+ // A candidate URL token is a run of non-space characters that starts with an
28
+ // http or https scheme. The parser validates each candidate with the `URL`
29
+ // class; the regular expression only splits tokens out of the text.
30
+ const URL_TOKEN_RE = /https?:\/\/\S+/g;
31
+ // Trailing punctuation that prose commonly puts right after a URL. The parser
32
+ // strips only these characters. It never strips `?` or `#`, so a URL with a
33
+ // query or a fragment stays malformed and the parser rejects it.
34
+ const TRAILING_PUNCTUATION_RE = /[)\].,;:!]+$/;
35
+ // The one-time code structure on a dedicated line: four characters, a hyphen,
36
+ // then five characters, and nothing else on the line. The Codex prompt prints
37
+ // the code alone on the line that comes right after the preamble line. So the
38
+ // pattern matches the whole line. A code-shaped token that shares a line with
39
+ // other text cannot match. The real code alphabet is a Codex detail that the
40
+ // grounded capture did not keep (the capture redacted the code to `?`). So the
41
+ // parser binds the token class to alphanumerics and the redaction sentinel `?`.
42
+ const CODE_LINE_RE = /^([A-Za-z0-9?]{4}-[A-Za-z0-9?]{5})$/;
43
+ // The prompt line that introduces the one-time code. The Codex prompt prints
44
+ // the phrase "one-time code" on the line right before the code. The parser
45
+ // anchors the code search on this phrase. So the code binds to the prompt line
46
+ // that introduces it. A code-shaped token that sits between the URL and this
47
+ // phrase cannot bind, because the parser reads the code only after the phrase.
48
+ const CODE_PREAMBLE_RE = /one-time code/i;
49
+ // The maximum number of characters between the end of the URL and the start of
50
+ // the code preamble. The Codex prompt prints the preamble about one line after
51
+ // the URL. The parser looks for the preamble only inside this window after the
52
+ // URL. So a preamble far away in the output cannot bind to the URL.
53
+ const MAX_URL_TO_PREAMBLE_GAP = 256;
54
+ // The maximum number of characters after the end of the preamble line that the
55
+ // parser reads for the code. The Codex prompt prints the code on the line right
56
+ // after the preamble line. The parser looks for the code only inside this window
57
+ // after the preamble line. The window is large enough for the real code line and
58
+ // small enough to reject distant noise.
59
+ const MAX_PREAMBLE_TO_CODE_GAP = 128;
60
+ /**
61
+ * Returns the validated device-login URL and its end index when `text` holds it
62
+ * as a standalone token with the exact origin `https://auth.openai.com` and the
63
+ * exact path `/codex/device` and no query, fragment, or credentials. Returns
64
+ * null otherwise. Returns the platform `URL` parser's normalized form of the
65
+ * matched token, so the accepting rules bound the output even though it is not a
66
+ * fixed constant. The `end` index is the position of the first character after
67
+ * the matched token in `text`.
68
+ */
69
+ function findExactDeviceUrl(text) {
70
+ for (const match of text.matchAll(URL_TOKEN_RE)) {
71
+ const token = match[0];
72
+ const cleaned = token.replace(TRAILING_PUNCTUATION_RE, "");
73
+ let parsed;
74
+ try {
75
+ parsed = new URL(cleaned);
76
+ }
77
+ catch {
78
+ continue;
79
+ }
80
+ if (parsed.protocol === "https:" &&
81
+ parsed.host === "auth.openai.com" &&
82
+ parsed.pathname === "/codex/device" &&
83
+ parsed.search === "" &&
84
+ parsed.hash === "" &&
85
+ parsed.username === "" &&
86
+ parsed.password === "") {
87
+ return { url: parsed.toString(), end: (match.index ?? 0) + token.length };
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ /**
93
+ * Returns the one-time code when `text` holds the code preamble after
94
+ * `fromIndex` and a dedicated code line after that preamble line. The parser
95
+ * first finds the "one-time code" preamble in a window after the URL. It then
96
+ * advances past the end of the preamble line and reads the first non-blank line
97
+ * after it. That line must hold only the `XXXX-XXXXX` code. So the code binds to
98
+ * the dedicated code line that the prompt prints right after the preamble line.
99
+ * A code-shaped token between the URL and the preamble cannot bind. A code-shaped
100
+ * token that shares the preamble line cannot bind. A code-shaped token inside a
101
+ * line that also holds other text cannot bind. Returns null when the preamble is
102
+ * absent, when the preamble has no line break after it, or when the first
103
+ * non-blank line after the preamble line is not a code line.
104
+ */
105
+ function findShortCode(text, fromIndex) {
106
+ const preambleWindow = text.slice(fromIndex, fromIndex + MAX_URL_TO_PREAMBLE_GAP);
107
+ const preambleMatch = CODE_PREAMBLE_RE.exec(preambleWindow);
108
+ if (!preambleMatch)
109
+ return null;
110
+ // Advance to the end of the preamble line. The code sits on the next line, so
111
+ // the parser reads the code only after the preamble line ends. A code-shaped
112
+ // token on the preamble line cannot bind.
113
+ const preambleEnd = fromIndex + preambleMatch.index + preambleMatch[0].length;
114
+ const lineBreak = text.indexOf("\n", preambleEnd);
115
+ if (lineBreak === -1)
116
+ return null;
117
+ const codeWindow = text.slice(lineBreak + 1, lineBreak + 1 + MAX_PREAMBLE_TO_CODE_GAP);
118
+ // Read the first non-blank line after the preamble line. It must hold only the
119
+ // code. So the parser binds the code to the dedicated code line, and it rejects
120
+ // a line that mixes the code with other text.
121
+ for (const line of codeWindow.split("\n")) {
122
+ const trimmed = line.trim();
123
+ if (trimmed.length === 0)
124
+ continue;
125
+ const match = CODE_LINE_RE.exec(trimmed);
126
+ return match ? match[1] : null;
127
+ }
128
+ return null;
129
+ }
130
+ /**
131
+ * Parses Codex device-login output. Removes ANSI color sequences first, so
132
+ * colored output from Codex CLI 0.128.0 and later reads the same as plain
133
+ * output. The parser reads the URL first, then finds the "one-time code"
134
+ * preamble after the URL, then reads the code from the dedicated code line right
135
+ * after the preamble line. So the code binds to the prompt line that introduces
136
+ * it, and a code-shaped token between the URL and the preamble, on the preamble
137
+ * line, or mixed with other text on a later line, cannot form a prompt. Returns
138
+ * the login URL and the one-time code when both are present and valid. Returns
139
+ * null for any other input, including a non-string input, an absent prompt, a URL
140
+ * with a query or a fragment, a wrong origin or path, and a malformed short code.
141
+ * Never throws on input, and never puts the URL or the code into a log or an error.
142
+ */
143
+ export function parseDeviceLoginPrompt(text) {
144
+ if (typeof text !== "string" || text.length === 0)
145
+ return null;
146
+ const clean = text.replace(ANSI_CSI_RE, "");
147
+ const urlMatch = findExactDeviceUrl(clean);
148
+ if (!urlMatch)
149
+ return null;
150
+ const code = findShortCode(clean, urlMatch.end);
151
+ if (!code)
152
+ return null;
153
+ return { url: urlMatch.url, code };
154
+ }
155
+ //# sourceMappingURL=device-login-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-login-parse.js","sourceRoot":"","sources":["../../src/server/device-login-parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=device-login-parse.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-login-parse.test.d.ts","sourceRoot":"","sources":["../../src/server/device-login-parse.test.ts"],"names":[],"mappings":""}