@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.
- package/LICENSE +22 -0
- package/dist/cli/format-event.d.ts +2 -0
- package/dist/cli/format-event.d.ts.map +1 -0
- package/dist/cli/format-event.js +218 -0
- package/dist/cli/format-event.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/quota-probe.d.ts +3 -0
- package/dist/cli/quota-probe.d.ts.map +1 -0
- package/dist/cli/quota-probe.js +104 -0
- package/dist/cli/quota-probe.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +155 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +58 -0
- package/dist/index.test.js.map +1 -0
- package/dist/server/acp.d.ts +30 -0
- package/dist/server/acp.d.ts.map +1 -0
- package/dist/server/acp.js +532 -0
- package/dist/server/acp.js.map +1 -0
- package/dist/server/acp.test.d.ts +2 -0
- package/dist/server/acp.test.d.ts.map +1 -0
- package/dist/server/acp.test.js +1087 -0
- package/dist/server/acp.test.js.map +1 -0
- package/dist/server/adapter-auth-promotion.d.ts +102 -0
- package/dist/server/adapter-auth-promotion.d.ts.map +1 -0
- package/dist/server/adapter-auth-promotion.js +210 -0
- package/dist/server/adapter-auth-promotion.js.map +1 -0
- package/dist/server/adapter-auth-promotion.test.d.ts +2 -0
- package/dist/server/adapter-auth-promotion.test.d.ts.map +1 -0
- package/dist/server/adapter-auth-promotion.test.js +658 -0
- package/dist/server/adapter-auth-promotion.test.js.map +1 -0
- package/dist/server/auth-check.d.ts +8 -0
- package/dist/server/auth-check.d.ts.map +1 -0
- package/dist/server/auth-check.js +8 -0
- package/dist/server/auth-check.js.map +1 -0
- package/dist/server/auth-precedence.d.ts +16 -0
- package/dist/server/auth-precedence.d.ts.map +1 -0
- package/dist/server/auth-precedence.js +20 -0
- package/dist/server/auth-precedence.js.map +1 -0
- package/dist/server/auth-precedence.test.d.ts +2 -0
- package/dist/server/auth-precedence.test.d.ts.map +1 -0
- package/dist/server/auth-precedence.test.js +100 -0
- package/dist/server/auth-precedence.test.js.map +1 -0
- package/dist/server/codex-args.d.ts +13 -0
- package/dist/server/codex-args.d.ts.map +1 -0
- package/dist/server/codex-args.js +76 -0
- package/dist/server/codex-args.js.map +1 -0
- package/dist/server/codex-args.test.d.ts +2 -0
- package/dist/server/codex-args.test.d.ts.map +1 -0
- package/dist/server/codex-args.test.js +243 -0
- package/dist/server/codex-args.test.js.map +1 -0
- package/dist/server/codex-auth-cache.d.ts +206 -0
- package/dist/server/codex-auth-cache.d.ts.map +1 -0
- package/dist/server/codex-auth-cache.js +501 -0
- package/dist/server/codex-auth-cache.js.map +1 -0
- package/dist/server/codex-auth-cache.test.d.ts +2 -0
- package/dist/server/codex-auth-cache.test.d.ts.map +1 -0
- package/dist/server/codex-auth-cache.test.js +497 -0
- package/dist/server/codex-auth-cache.test.js.map +1 -0
- package/dist/server/codex-auth-copyback.d.ts +53 -0
- package/dist/server/codex-auth-copyback.d.ts.map +1 -0
- package/dist/server/codex-auth-copyback.js +123 -0
- package/dist/server/codex-auth-copyback.js.map +1 -0
- package/dist/server/codex-auth-copyback.test.d.ts +2 -0
- package/dist/server/codex-auth-copyback.test.d.ts.map +1 -0
- package/dist/server/codex-auth-copyback.test.js +507 -0
- package/dist/server/codex-auth-copyback.test.js.map +1 -0
- package/dist/server/codex-auth-merge-decision.cjs +170 -0
- package/dist/server/codex-auth-merge-decision.d.ts +22 -0
- package/dist/server/codex-auth-merge-decision.d.ts.map +1 -0
- package/dist/server/codex-auth-merge-decision.js +58 -0
- package/dist/server/codex-auth-merge-decision.js.map +1 -0
- package/dist/server/codex-auth-merge-decision.test.d.ts +2 -0
- package/dist/server/codex-auth-merge-decision.test.d.ts.map +1 -0
- package/dist/server/codex-auth-merge-decision.test.js +230 -0
- package/dist/server/codex-auth-merge-decision.test.js.map +1 -0
- package/dist/server/codex-auth-merge-extract.sh +73 -0
- package/dist/server/codex-auth-merge-scripts.d.ts +21 -0
- package/dist/server/codex-auth-merge-scripts.d.ts.map +1 -0
- package/dist/server/codex-auth-merge-scripts.js +40 -0
- package/dist/server/codex-auth-merge-scripts.js.map +1 -0
- package/dist/server/codex-auth-merge.test.d.ts +2 -0
- package/dist/server/codex-auth-merge.test.d.ts.map +1 -0
- package/dist/server/codex-auth-merge.test.js +714 -0
- package/dist/server/codex-auth-merge.test.js.map +1 -0
- package/dist/server/codex-auth-seed-write.d.ts +30 -0
- package/dist/server/codex-auth-seed-write.d.ts.map +1 -0
- package/dist/server/codex-auth-seed-write.js +41 -0
- package/dist/server/codex-auth-seed-write.js.map +1 -0
- package/dist/server/codex-home.d.ts +162 -0
- package/dist/server/codex-home.d.ts.map +1 -0
- package/dist/server/codex-home.js +771 -0
- package/dist/server/codex-home.js.map +1 -0
- package/dist/server/codex-home.test.d.ts +2 -0
- package/dist/server/codex-home.test.d.ts.map +1 -0
- package/dist/server/codex-home.test.js +1183 -0
- package/dist/server/codex-home.test.js.map +1 -0
- package/dist/server/config-schema.d.ts +3 -0
- package/dist/server/config-schema.d.ts.map +1 -0
- package/dist/server/config-schema.js +67 -0
- package/dist/server/config-schema.js.map +1 -0
- package/dist/server/device-login-export.d.ts +56 -0
- package/dist/server/device-login-export.d.ts.map +1 -0
- package/dist/server/device-login-export.js +230 -0
- package/dist/server/device-login-export.js.map +1 -0
- package/dist/server/device-login-export.test.d.ts +2 -0
- package/dist/server/device-login-export.test.d.ts.map +1 -0
- package/dist/server/device-login-export.test.js +245 -0
- package/dist/server/device-login-export.test.js.map +1 -0
- package/dist/server/device-login-parse.d.ts +20 -0
- package/dist/server/device-login-parse.d.ts.map +1 -0
- package/dist/server/device-login-parse.js +155 -0
- package/dist/server/device-login-parse.js.map +1 -0
- package/dist/server/device-login-parse.test.d.ts +2 -0
- package/dist/server/device-login-parse.test.d.ts.map +1 -0
- package/dist/server/device-login-parse.test.js +269 -0
- package/dist/server/device-login-parse.test.js.map +1 -0
- package/dist/server/device-login-runner.d.ts +69 -0
- package/dist/server/device-login-runner.d.ts.map +1 -0
- package/dist/server/device-login-runner.js +109 -0
- package/dist/server/device-login-runner.js.map +1 -0
- package/dist/server/device-login-runner.test.d.ts +2 -0
- package/dist/server/device-login-runner.test.d.ts.map +1 -0
- package/dist/server/device-login-runner.test.js +201 -0
- package/dist/server/device-login-runner.test.js.map +1 -0
- package/dist/server/engine-availability.test.d.ts +2 -0
- package/dist/server/engine-availability.test.d.ts.map +1 -0
- package/dist/server/engine-availability.test.js +41 -0
- package/dist/server/engine-availability.test.js.map +1 -0
- package/dist/server/execute.acp-fallback.test.d.ts +2 -0
- package/dist/server/execute.acp-fallback.test.d.ts.map +1 -0
- package/dist/server/execute.acp-fallback.test.js +123 -0
- package/dist/server/execute.acp-fallback.test.js.map +1 -0
- package/dist/server/execute.auth-precedence.test.d.ts +2 -0
- package/dist/server/execute.auth-precedence.test.d.ts.map +1 -0
- package/dist/server/execute.auth-precedence.test.js +137 -0
- package/dist/server/execute.auth-precedence.test.js.map +1 -0
- package/dist/server/execute.auth.test.d.ts +2 -0
- package/dist/server/execute.auth.test.d.ts.map +1 -0
- package/dist/server/execute.auth.test.js +197 -0
- package/dist/server/execute.auth.test.js.map +1 -0
- package/dist/server/execute.d.ts +40 -0
- package/dist/server/execute.d.ts.map +1 -0
- package/dist/server/execute.js +1290 -0
- package/dist/server/execute.js.map +1 -0
- package/dist/server/execute.remote.test.d.ts +2 -0
- package/dist/server/execute.remote.test.d.ts.map +1 -0
- package/dist/server/execute.remote.test.js +556 -0
- package/dist/server/execute.remote.test.js.map +1 -0
- package/dist/server/execute.stderr-error.test.d.ts +2 -0
- package/dist/server/execute.stderr-error.test.d.ts.map +1 -0
- package/dist/server/execute.stderr-error.test.js +142 -0
- package/dist/server/execute.stderr-error.test.js.map +1 -0
- package/dist/server/execute.test.d.ts +2 -0
- package/dist/server/execute.test.d.ts.map +1 -0
- package/dist/server/execute.test.js +240 -0
- package/dist/server/execute.test.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +71 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/output-inactivity-monitor.d.ts +62 -0
- package/dist/server/output-inactivity-monitor.d.ts.map +1 -0
- package/dist/server/output-inactivity-monitor.integration.test.d.ts +2 -0
- package/dist/server/output-inactivity-monitor.integration.test.d.ts.map +1 -0
- package/dist/server/output-inactivity-monitor.integration.test.js +136 -0
- package/dist/server/output-inactivity-monitor.integration.test.js.map +1 -0
- package/dist/server/output-inactivity-monitor.js +112 -0
- package/dist/server/output-inactivity-monitor.js.map +1 -0
- package/dist/server/output-inactivity-monitor.test.d.ts +2 -0
- package/dist/server/output-inactivity-monitor.test.d.ts.map +1 -0
- package/dist/server/output-inactivity-monitor.test.js +284 -0
- package/dist/server/output-inactivity-monitor.test.js.map +1 -0
- package/dist/server/parse.d.ts +51 -0
- package/dist/server/parse.d.ts.map +1 -0
- package/dist/server/parse.js +261 -0
- package/dist/server/parse.js.map +1 -0
- package/dist/server/parse.test.d.ts +2 -0
- package/dist/server/parse.test.d.ts.map +1 -0
- package/dist/server/parse.test.js +186 -0
- package/dist/server/parse.test.js.map +1 -0
- package/dist/server/process-activity-monitor.d.ts +21 -0
- package/dist/server/process-activity-monitor.d.ts.map +1 -0
- package/dist/server/process-activity-monitor.js +103 -0
- package/dist/server/process-activity-monitor.js.map +1 -0
- package/dist/server/process-activity-monitor.test.d.ts +2 -0
- package/dist/server/process-activity-monitor.test.d.ts.map +1 -0
- package/dist/server/process-activity-monitor.test.js +82 -0
- package/dist/server/process-activity-monitor.test.js.map +1 -0
- package/dist/server/quota-spawn-error.test.d.ts +2 -0
- package/dist/server/quota-spawn-error.test.d.ts.map +1 -0
- package/dist/server/quota-spawn-error.test.js +174 -0
- package/dist/server/quota-spawn-error.test.js.map +1 -0
- package/dist/server/quota.d.ts +66 -0
- package/dist/server/quota.d.ts.map +1 -0
- package/dist/server/quota.js +511 -0
- package/dist/server/quota.js.map +1 -0
- package/dist/server/runtime-config.d.ts +11 -0
- package/dist/server/runtime-config.d.ts.map +1 -0
- package/dist/server/runtime-config.js +380 -0
- package/dist/server/runtime-config.js.map +1 -0
- package/dist/server/runtime-config.test.d.ts +2 -0
- package/dist/server/runtime-config.test.d.ts.map +1 -0
- package/dist/server/runtime-config.test.js +367 -0
- package/dist/server/runtime-config.test.js.map +1 -0
- package/dist/server/skills.d.ts +8 -0
- package/dist/server/skills.d.ts.map +1 -0
- package/dist/server/skills.js +26 -0
- package/dist/server/skills.js.map +1 -0
- package/dist/server/test.d.ts +3 -0
- package/dist/server/test.d.ts.map +1 -0
- package/dist/server/test.js +458 -0
- package/dist/server/test.js.map +1 -0
- package/dist/server/test.remote.test.d.ts +2 -0
- package/dist/server/test.remote.test.d.ts.map +1 -0
- package/dist/server/test.remote.test.js +396 -0
- package/dist/server/test.remote.test.js.map +1 -0
- package/dist/ui/build-config.d.ts +5 -0
- package/dist/ui/build-config.d.ts.map +1 -0
- package/dist/ui/build-config.js +229 -0
- package/dist/ui/build-config.js.map +1 -0
- package/dist/ui/build-config.test.d.ts +2 -0
- package/dist/ui/build-config.test.d.ts.map +1 -0
- package/dist/ui/build-config.test.js +272 -0
- package/dist/ui/build-config.test.js.map +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +8 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/parse-stdout.d.ts +3 -0
- package/dist/ui/parse-stdout.d.ts.map +1 -0
- package/dist/ui/parse-stdout.js +265 -0
- package/dist/ui/parse-stdout.js.map +1 -0
- package/dist/ui/parse-stdout.test.d.ts +2 -0
- package/dist/ui/parse-stdout.test.d.ts.map +1 -0
- package/dist/ui/parse-stdout.test.js +77 -0
- package/dist/ui/parse-stdout.test.js.map +1 -0
- package/package.json +61 -0
- package/skills/agentmail/SKILL.md +70 -0
- package/skills/paperclip/SKILL.md +712 -0
- package/skills/paperclip/references/api-reference.md +1675 -0
- package/skills/paperclip/references/artifacts.md +158 -0
- package/skills/paperclip/references/cases.md +295 -0
- package/skills/paperclip/references/company-skills.md +266 -0
- package/skills/paperclip/references/issue-workspaces.md +80 -0
- package/skills/paperclip/references/routines.md +231 -0
- package/skills/paperclip/references/workflows.md +141 -0
- package/skills/paperclip/scripts/paperclip-upload-artifact.sh +592 -0
- package/skills/paperclip-board/SKILL.md +619 -0
- package/skills/paperclip-converting-plans-to-tasks/SKILL.md +60 -0
- package/skills/paperclip-create-agent/SKILL.md +179 -0
- package/skills/paperclip-create-agent/references/agent-instruction-templates.md +123 -0
- package/skills/paperclip-create-agent/references/agents/coder.md +64 -0
- package/skills/paperclip-create-agent/references/agents/qa.md +88 -0
- package/skills/paperclip-create-agent/references/agents/securityengineer.md +135 -0
- package/skills/paperclip-create-agent/references/agents/uxdesigner.md +115 -0
- package/skills/paperclip-create-agent/references/api-reference.md +110 -0
- package/skills/paperclip-create-agent/references/baseline-role-guide.md +168 -0
- package/skills/paperclip-create-agent/references/draft-review-checklist.md +95 -0
- package/skills/para-memory-files/SKILL.md +100 -0
- package/skills/para-memory-files/references/schemas.md +35 -0
- package/skills/slack/SKILL.md +65 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { parseDeviceLoginPrompt } from "./device-login-parse.js";
|
|
6
|
+
const fixturesDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "__fixtures__");
|
|
7
|
+
function readFixture(name) {
|
|
8
|
+
return readFileSync(path.join(fixturesDir, name), "utf8");
|
|
9
|
+
}
|
|
10
|
+
const EXACT_URL = "https://auth.openai.com/codex/device";
|
|
11
|
+
describe("parseDeviceLoginPrompt", () => {
|
|
12
|
+
it("parse_returns_url_and_code_from_sample", () => {
|
|
13
|
+
const result = parseDeviceLoginPrompt(readFixture("device-login-sample.txt"));
|
|
14
|
+
expect(result).not.toBeNull();
|
|
15
|
+
expect(result?.url).toBe(EXACT_URL);
|
|
16
|
+
// The committed sample keeps the capture-time redaction of the code. The
|
|
17
|
+
// parser extracts the four-hyphen-five structure without a real secret.
|
|
18
|
+
expect(result?.code).toBe("????-?????");
|
|
19
|
+
});
|
|
20
|
+
it("parse_returns_url_and_code_from_ansi_colored_output", () => {
|
|
21
|
+
// Codex CLI 0.128.0 and later add ANSI color (SGR) sequences around the URL
|
|
22
|
+
// and the code. A live sandbox run confirmed this format. The parser removes
|
|
23
|
+
// the Control Sequence Introducer sequences and reads the tokens the same as
|
|
24
|
+
// plain output.
|
|
25
|
+
const cyan = "\x1b[36m";
|
|
26
|
+
const bold = "\x1b[1m";
|
|
27
|
+
const reset = "\x1b[0m";
|
|
28
|
+
const text = [
|
|
29
|
+
"1. Open this link in your browser and sign in to your account",
|
|
30
|
+
`${cyan}${EXACT_URL}${reset}`,
|
|
31
|
+
"2. Enter this one-time code (expires in 15 minutes)",
|
|
32
|
+
`${bold}ABCD-EFGHJ${reset}`,
|
|
33
|
+
].join("\n");
|
|
34
|
+
const result = parseDeviceLoginPrompt(text);
|
|
35
|
+
expect(result).not.toBeNull();
|
|
36
|
+
expect(result?.url).toBe(EXACT_URL);
|
|
37
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
38
|
+
});
|
|
39
|
+
it("parse_returns_url_and_code_from_carriage_return_line_endings", () => {
|
|
40
|
+
// A pseudo-terminal ends each line with a carriage return and a line feed.
|
|
41
|
+
// The carriage return is whitespace, so the URL token stops before it, and the
|
|
42
|
+
// code line trims it. The parser reads the tokens the same as line-feed output.
|
|
43
|
+
const text = [
|
|
44
|
+
"1. Open this link in your browser and sign in to your account",
|
|
45
|
+
EXACT_URL,
|
|
46
|
+
"2. Enter this one-time code (expires in 15 minutes)",
|
|
47
|
+
"ABCD-EFGHJ",
|
|
48
|
+
].join("\r\n");
|
|
49
|
+
const result = parseDeviceLoginPrompt(text);
|
|
50
|
+
expect(result).not.toBeNull();
|
|
51
|
+
expect(result?.url).toBe(EXACT_URL);
|
|
52
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
53
|
+
});
|
|
54
|
+
it("parse_returns_url_and_code_with_a_terminal_title_osc_sequence", () => {
|
|
55
|
+
// A pseudo-terminal can emit an Operating System Command (OSC) title sequence
|
|
56
|
+
// in the stream. The device-auth prompt still prints the URL and the code as
|
|
57
|
+
// plain standalone tokens on their own lines. The OSC title sequence carries no
|
|
58
|
+
// URL token, so it does not shift the URL or the code, and the parser reads
|
|
59
|
+
// both tokens.
|
|
60
|
+
const osc = "\x1b]0;Codex\x07";
|
|
61
|
+
const text = [
|
|
62
|
+
`${osc}1. Open this link in your browser and sign in to your account`,
|
|
63
|
+
EXACT_URL,
|
|
64
|
+
"2. Enter this one-time code (expires in 15 minutes)",
|
|
65
|
+
"ABCD-EFGHJ",
|
|
66
|
+
].join("\n");
|
|
67
|
+
const result = parseDeviceLoginPrompt(text);
|
|
68
|
+
expect(result).not.toBeNull();
|
|
69
|
+
expect(result?.url).toBe(EXACT_URL);
|
|
70
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
71
|
+
});
|
|
72
|
+
it("parse_returns_url_and_code_from_a_merged_raw_pseudo_terminal_frame", () => {
|
|
73
|
+
// One buffer holds the whole prompt as a real pseudo-terminal emits it: a
|
|
74
|
+
// leading title Operating System Command (OSC) sequence, color Control
|
|
75
|
+
// Sequence Introducer (CSI) sequences around the URL and the code, and
|
|
76
|
+
// carriage-return line endings. The parser removes the color sequences and
|
|
77
|
+
// reads the plain tokens.
|
|
78
|
+
const title = "\x1b]0;Codex login\x07";
|
|
79
|
+
const cyan = "\x1b[36m";
|
|
80
|
+
const bold = "\x1b[1m";
|
|
81
|
+
const reset = "\x1b[0m";
|
|
82
|
+
const text = `${title}1. Open this link in your browser and sign in to your account\r\n` +
|
|
83
|
+
`${cyan}${EXACT_URL}${reset}\r\n` +
|
|
84
|
+
`2. Enter this one-time code (expires in 15 minutes)\r\n` +
|
|
85
|
+
`${bold}ABCD-EFGHJ${reset}\r\n`;
|
|
86
|
+
const result = parseDeviceLoginPrompt(text);
|
|
87
|
+
expect(result).not.toBeNull();
|
|
88
|
+
expect(result?.url).toBe(EXACT_URL);
|
|
89
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
90
|
+
});
|
|
91
|
+
it("parse_returns_null_when_prompt_absent", () => {
|
|
92
|
+
const text = "Some unrelated log line\nNothing to see here\n";
|
|
93
|
+
expect(parseDeviceLoginPrompt(text)).toBeNull();
|
|
94
|
+
});
|
|
95
|
+
it("parse_returns_null_for_url_with_query_or_fragment", () => {
|
|
96
|
+
const withQuery = [
|
|
97
|
+
"Open this link",
|
|
98
|
+
"https://auth.openai.com/codex/device?foo=bar",
|
|
99
|
+
"ABCD-EFGHJ",
|
|
100
|
+
].join("\n");
|
|
101
|
+
const withFragment = [
|
|
102
|
+
"Open this link",
|
|
103
|
+
"https://auth.openai.com/codex/device#section",
|
|
104
|
+
"ABCD-EFGHJ",
|
|
105
|
+
].join("\n");
|
|
106
|
+
expect(parseDeviceLoginPrompt(withQuery)).toBeNull();
|
|
107
|
+
expect(parseDeviceLoginPrompt(withFragment)).toBeNull();
|
|
108
|
+
});
|
|
109
|
+
it("parse_returns_the_printed_url_with_a_bare_trailing_fragment_marker", () => {
|
|
110
|
+
// A printed URL that ends with a bare `#` carries an empty fragment. The
|
|
111
|
+
// platform `URL` parser keeps the marker in its normalized form. The parser
|
|
112
|
+
// returns that normalized form, not the fixed constant.
|
|
113
|
+
const preamble = "2. Enter this one-time code (expires in 15 minutes)";
|
|
114
|
+
const text = [`${EXACT_URL}#`, preamble, "ABCD-EFGHJ"].join("\n");
|
|
115
|
+
const result = parseDeviceLoginPrompt(text);
|
|
116
|
+
expect(result).not.toBeNull();
|
|
117
|
+
expect(result?.url).toBe("https://auth.openai.com/codex/device#");
|
|
118
|
+
});
|
|
119
|
+
it("parse_returns_the_normalized_url_for_an_explicit_default_port_or_an_uppercase_host", () => {
|
|
120
|
+
// The platform `URL` parser normalizes an explicit default port and an
|
|
121
|
+
// uppercase host. The parser returns that normalized form.
|
|
122
|
+
const preamble = "2. Enter this one-time code (expires in 15 minutes)";
|
|
123
|
+
const withPort = [`${EXACT_URL.replace("auth.openai.com", "auth.openai.com:443")}`, preamble, "ABCD-EFGHJ"].join("\n");
|
|
124
|
+
const withUppercaseHost = [
|
|
125
|
+
`${EXACT_URL.replace("auth.openai.com", "AUTH.OPENAI.COM")}`,
|
|
126
|
+
preamble,
|
|
127
|
+
"ABCD-EFGHJ",
|
|
128
|
+
].join("\n");
|
|
129
|
+
expect(parseDeviceLoginPrompt(withPort)?.url).toBe(EXACT_URL);
|
|
130
|
+
expect(parseDeviceLoginPrompt(withUppercaseHost)?.url).toBe(EXACT_URL);
|
|
131
|
+
});
|
|
132
|
+
it("parse_returns_null_for_wrong_origin_or_path", () => {
|
|
133
|
+
const wrongOrigin = [
|
|
134
|
+
"Open this link",
|
|
135
|
+
"https://auth.example.com/codex/device",
|
|
136
|
+
"ABCD-EFGHJ",
|
|
137
|
+
].join("\n");
|
|
138
|
+
const wrongPath = [
|
|
139
|
+
"Open this link",
|
|
140
|
+
"https://auth.openai.com/codex/device/extra",
|
|
141
|
+
"ABCD-EFGHJ",
|
|
142
|
+
].join("\n");
|
|
143
|
+
const httpScheme = [
|
|
144
|
+
"Open this link",
|
|
145
|
+
"http://auth.openai.com/codex/device",
|
|
146
|
+
"ABCD-EFGHJ",
|
|
147
|
+
].join("\n");
|
|
148
|
+
expect(parseDeviceLoginPrompt(wrongOrigin)).toBeNull();
|
|
149
|
+
expect(parseDeviceLoginPrompt(wrongPath)).toBeNull();
|
|
150
|
+
expect(parseDeviceLoginPrompt(httpScheme)).toBeNull();
|
|
151
|
+
});
|
|
152
|
+
it("parse_returns_null_for_malformed_short_code", () => {
|
|
153
|
+
// Each input carries the code preamble after the URL, so the test exercises
|
|
154
|
+
// the code-structure check and not the preamble check.
|
|
155
|
+
const preamble = "2. Enter this one-time code (expires in 15 minutes)";
|
|
156
|
+
const shortCode = [EXACT_URL, preamble, "ABC-EFGHJ"].join("\n"); // 3 then 5
|
|
157
|
+
const longCode = [EXACT_URL, preamble, "ABCDE-EFGHJ"].join("\n"); // 5 then 5
|
|
158
|
+
const noHyphen = [EXACT_URL, preamble, "ABCDEFGHJ"].join("\n");
|
|
159
|
+
const noCode = [EXACT_URL, preamble, "no code on this line"].join("\n");
|
|
160
|
+
expect(parseDeviceLoginPrompt(shortCode)).toBeNull();
|
|
161
|
+
expect(parseDeviceLoginPrompt(longCode)).toBeNull();
|
|
162
|
+
expect(parseDeviceLoginPrompt(noHyphen)).toBeNull();
|
|
163
|
+
expect(parseDeviceLoginPrompt(noCode)).toBeNull();
|
|
164
|
+
});
|
|
165
|
+
it("parse_binds_code_to_url_and_ignores_a_code_before_the_url", () => {
|
|
166
|
+
// A code-shaped token appears before the URL. The parser reads the code only
|
|
167
|
+
// after the URL, so it uses the code that follows the URL.
|
|
168
|
+
const text = [
|
|
169
|
+
"WXYZ-98765",
|
|
170
|
+
"1. Open this link in your browser and sign in to your account",
|
|
171
|
+
EXACT_URL,
|
|
172
|
+
"2. Enter this one-time code (expires in 15 minutes)",
|
|
173
|
+
"ABCD-EFGHJ",
|
|
174
|
+
].join("\n");
|
|
175
|
+
const result = parseDeviceLoginPrompt(text);
|
|
176
|
+
expect(result).not.toBeNull();
|
|
177
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
178
|
+
});
|
|
179
|
+
it("parse_returns_null_when_only_code_is_before_the_url", () => {
|
|
180
|
+
// The only code-shaped token sits before the URL. No code follows the URL,
|
|
181
|
+
// so the parser rejects the output instead of binding the earlier token.
|
|
182
|
+
const text = ["WXYZ-98765", "Open this link", EXACT_URL].join("\n");
|
|
183
|
+
expect(parseDeviceLoginPrompt(text)).toBeNull();
|
|
184
|
+
});
|
|
185
|
+
it("parse_returns_null_when_code_is_far_after_the_url", () => {
|
|
186
|
+
// A code-shaped token sits far below the URL, past the proximity window. The
|
|
187
|
+
// parser does not bind a distant token to the URL.
|
|
188
|
+
const filler = "unrelated log line\n".repeat(40);
|
|
189
|
+
const text = [EXACT_URL, filler, "ABCD-EFGHJ"].join("\n");
|
|
190
|
+
expect(parseDeviceLoginPrompt(text)).toBeNull();
|
|
191
|
+
});
|
|
192
|
+
it("parse_ignores_a_code_between_the_url_and_the_code_preamble", () => {
|
|
193
|
+
// A code-shaped token sits after the URL but before the "one-time code"
|
|
194
|
+
// preamble line. The parser anchors the code on the preamble, so it ignores
|
|
195
|
+
// the earlier token and returns the real code after the preamble.
|
|
196
|
+
const text = [
|
|
197
|
+
"1. Open this link in your browser and sign in to your account",
|
|
198
|
+
EXACT_URL,
|
|
199
|
+
"session id WXYZ-98765 for this attempt",
|
|
200
|
+
"2. Enter this one-time code (expires in 15 minutes)",
|
|
201
|
+
"ABCD-EFGHJ",
|
|
202
|
+
].join("\n");
|
|
203
|
+
const result = parseDeviceLoginPrompt(text);
|
|
204
|
+
expect(result).not.toBeNull();
|
|
205
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
206
|
+
});
|
|
207
|
+
it("parse_ignores_a_code_that_shares_the_preamble_line", () => {
|
|
208
|
+
// A code-shaped token shares the preamble line with the "one-time code"
|
|
209
|
+
// phrase. The parser advances past the whole preamble line, so it ignores the
|
|
210
|
+
// token on that line and returns the code from the dedicated code line below.
|
|
211
|
+
const text = [
|
|
212
|
+
EXACT_URL,
|
|
213
|
+
"2. Enter this one-time code (ref WXYZ-98765, expires in 15 minutes)",
|
|
214
|
+
"ABCD-EFGHJ",
|
|
215
|
+
].join("\n");
|
|
216
|
+
const result = parseDeviceLoginPrompt(text);
|
|
217
|
+
expect(result).not.toBeNull();
|
|
218
|
+
expect(result?.code).toBe("ABCD-EFGHJ");
|
|
219
|
+
});
|
|
220
|
+
it("parse_returns_null_when_a_noise_line_follows_the_preamble", () => {
|
|
221
|
+
// A line that mixes a code-shaped token with other text sits right after the
|
|
222
|
+
// preamble line. The parser reads the code only from a dedicated code line, so
|
|
223
|
+
// it never surfaces the embedded token. It rejects the output instead. This
|
|
224
|
+
// proves the parser binds the code to the prompt-code line and not to any
|
|
225
|
+
// nearby code-shaped token.
|
|
226
|
+
const text = [
|
|
227
|
+
EXACT_URL,
|
|
228
|
+
"2. Enter this one-time code (expires in 15 minutes)",
|
|
229
|
+
"your session token is WXYZ-98765 here",
|
|
230
|
+
"ABCD-EFGHJ",
|
|
231
|
+
].join("\n");
|
|
232
|
+
expect(parseDeviceLoginPrompt(text)).toBeNull();
|
|
233
|
+
});
|
|
234
|
+
it("parse_returns_null_when_the_code_preamble_is_absent", () => {
|
|
235
|
+
// A valid code follows the URL, but the "one-time code" preamble is absent.
|
|
236
|
+
// The parser requires the preamble, so it rejects the output. This binds the
|
|
237
|
+
// code to the prompt structure and not to a bare code-shaped token.
|
|
238
|
+
const text = [
|
|
239
|
+
"1. Open this link in your browser and sign in to your account",
|
|
240
|
+
EXACT_URL,
|
|
241
|
+
"ABCD-EFGHJ",
|
|
242
|
+
].join("\n");
|
|
243
|
+
expect(parseDeviceLoginPrompt(text)).toBeNull();
|
|
244
|
+
});
|
|
245
|
+
it("parse_ignores_token_like_text", () => {
|
|
246
|
+
// Token-like noise without the exact device URL must not yield a prompt.
|
|
247
|
+
const text = [
|
|
248
|
+
"tokens received",
|
|
249
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.payload.signature",
|
|
250
|
+
"sk-proj-ABCD1234ABCD1234ABCD1234",
|
|
251
|
+
"ABCD-EFGHJ",
|
|
252
|
+
].join("\n");
|
|
253
|
+
expect(parseDeviceLoginPrompt(text)).toBeNull();
|
|
254
|
+
});
|
|
255
|
+
it("parse_returns_null_for_edge_sample", () => {
|
|
256
|
+
// The grounded edge row carries a URL, but a wrong path and a wrong origin
|
|
257
|
+
// segment, so the parser rejects it.
|
|
258
|
+
expect(parseDeviceLoginPrompt(readFixture("device-login-edge.txt"))).toBeNull();
|
|
259
|
+
});
|
|
260
|
+
it("keeps the url and the code out of a thrown error", () => {
|
|
261
|
+
// A non-string input is a programming error, but the message must never
|
|
262
|
+
// carry secret-bearing input. The parser returns null instead of throwing.
|
|
263
|
+
// @ts-expect-error deliberate wrong type
|
|
264
|
+
expect(parseDeviceLoginPrompt(undefined)).toBeNull();
|
|
265
|
+
// @ts-expect-error deliberate wrong type
|
|
266
|
+
expect(parseDeviceLoginPrompt(12345)).toBeNull();
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
//# sourceMappingURL=device-login-parse.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-login-parse.test.js","sourceRoot":"","sources":["../../src/server/device-login-parse.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type LoginRunnerDisposable, type LoginRunnerLifecycleOptions, type LoginRunnerOutcome, type LoginRunnerResult } from "@tickernelz/paperclip-pro-adapter-utils";
|
|
2
|
+
import { type DeviceLoginPrompt } from "./device-login-parse.js";
|
|
3
|
+
/** The default Codex device-login command. */
|
|
4
|
+
export declare const CODEX_DEVICE_LOGIN_COMMAND = "codex login --device-auth";
|
|
5
|
+
/**
|
|
6
|
+
* The sandbox side of the device-login run. The runner never calls Daytona
|
|
7
|
+
* directly; a caller injects a concrete driver. A production driver binds `start`
|
|
8
|
+
* to the shared login pseudo-terminal (PTY) transport, binds `readFile` to a
|
|
9
|
+
* descriptor-bound credential read, and binds `dispose` to the transport dispose.
|
|
10
|
+
*
|
|
11
|
+
* The `start` shape matches the shared login pseudo-terminal transport start
|
|
12
|
+
* method, so the driver runs the login command on a real pseudo-terminal. The
|
|
13
|
+
* login command
|
|
14
|
+
* needs a pseudo-terminal: pipe stdio emits no login prompt. The runner never
|
|
15
|
+
* calls `stop` or `write` on the driver; the device-login flow needs no delayed
|
|
16
|
+
* input, and the service owns the sandbox delete. The runner disposes the driver
|
|
17
|
+
* one time on every terminal state.
|
|
18
|
+
*/
|
|
19
|
+
export interface SandboxLoginDriver extends LoginRunnerDisposable {
|
|
20
|
+
/**
|
|
21
|
+
* Starts `command` on a pseudo-terminal and streams the terminal output to
|
|
22
|
+
* `onData` in memory, in order, as the pseudo-terminal emits it. Resolves with
|
|
23
|
+
* the command exit code when the command ends. A driver must not persist the raw
|
|
24
|
+
* output to any durable log.
|
|
25
|
+
*/
|
|
26
|
+
start(command: string, onData: (chunk: string) => void): Promise<{
|
|
27
|
+
exitCode: number | null;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Reads the credential bytes with one descriptor-bound read. The read is
|
|
31
|
+
* separate from the pseudo-terminal session; the session has no file-read
|
|
32
|
+
* method. A driver runs one fixed, server-controlled operation that opens the
|
|
33
|
+
* verified session home and the credential file with no symlink follow, checks
|
|
34
|
+
* the opened descriptor, and reads only from that same descriptor.
|
|
35
|
+
*/
|
|
36
|
+
readFile(path: string): Promise<Buffer>;
|
|
37
|
+
}
|
|
38
|
+
/** Receives the parsed prompt one time in memory. The caller displays it. */
|
|
39
|
+
export type DeviceLoginPromptSink = (prompt: DeviceLoginPrompt) => void;
|
|
40
|
+
/** The device-login runner outcome. It is a fixed, non-secret status. */
|
|
41
|
+
export type DeviceLoginOutcome = LoginRunnerOutcome;
|
|
42
|
+
/** The runner result. It never carries a URL, a code, or a token byte. */
|
|
43
|
+
export type DeviceLoginResult = LoginRunnerResult;
|
|
44
|
+
export interface RunDeviceLoginOptions extends LoginRunnerLifecycleOptions {
|
|
45
|
+
/** The login command. Defaults to {@link CODEX_DEVICE_LOGIN_COMMAND}. */
|
|
46
|
+
command?: string;
|
|
47
|
+
/** Parses the prompt from the login output. Defaults to
|
|
48
|
+
* {@link parseDeviceLoginPrompt}. */
|
|
49
|
+
parsePrompt?: (output: string) => DeviceLoginPrompt | null;
|
|
50
|
+
/** Receives the parsed prompt one time in memory. The caller displays it. */
|
|
51
|
+
onPrompt: DeviceLoginPromptSink;
|
|
52
|
+
/**
|
|
53
|
+
* Receives the sandbox `auth.json` bytes one time in memory on success. The
|
|
54
|
+
* runner reads the bytes with {@link SandboxLoginDriver.readFile} before it
|
|
55
|
+
* disposes the driver. Set together with {@link authPath}.
|
|
56
|
+
*/
|
|
57
|
+
onCredential?: (authBytes: Buffer) => void | Promise<void>;
|
|
58
|
+
/** The sandbox path of the credential file to read on success. */
|
|
59
|
+
authPath?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Runs the device-login command through `driver`. Surfaces the prompt one time
|
|
63
|
+
* through `onPrompt`. On success it reads the credential and surfaces the bytes
|
|
64
|
+
* one time through `onCredential`. Returns a fixed status. Always disposes the
|
|
65
|
+
* driver. Never logs the raw stream, and never puts a URL, a code, or a token
|
|
66
|
+
* into a log line, the result, or a thrown error.
|
|
67
|
+
*/
|
|
68
|
+
export declare function runDeviceLogin(driver: SandboxLoginDriver, options: RunDeviceLoginOptions): Promise<DeviceLoginResult>;
|
|
69
|
+
//# sourceMappingURL=device-login-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-login-runner.d.ts","sourceRoot":"","sources":["../../src/server/device-login-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAiBzF,8CAA8C;AAC9C,eAAO,MAAM,0BAA0B,8BAA8B,CAAC;AAatE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB;IAC/D;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC9F;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAED,6EAA6E;AAC7E,MAAM,MAAM,qBAAqB,GAAG,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAExE,yEAAyE;AACzE,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAEpD,0EAA0E;AAC1E,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD,MAAM,WAAW,qBAAsB,SAAQ,2BAA2B;IACxE,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;0CACsC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,iBAAiB,GAAG,IAAI,CAAC;IAC3D,6EAA6E;IAC7E,QAAQ,EAAE,qBAAqB,CAAC;IAChC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CA0E5B"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { raceLoginRunnerExit, } from "@tickernelz/paperclip-pro-adapter-utils";
|
|
2
|
+
import { parseDeviceLoginPrompt } from "./device-login-parse.js";
|
|
3
|
+
// The device-login runner. It runs the Codex device-login command through an
|
|
4
|
+
// injected {@link SandboxLoginDriver}, surfaces the login prompt one time in
|
|
5
|
+
// memory, and handles a timeout and a cancellation. The runner always disposes
|
|
6
|
+
// the driver.
|
|
7
|
+
//
|
|
8
|
+
// Security (Control 1 — secret handling): the runner treats every byte of the
|
|
9
|
+
// sandbox stream as secret-bearing, untrusted input. It parses the stream in an
|
|
10
|
+
// in-memory buffer only. It drops the buffer as soon as it finds the prompt. It
|
|
11
|
+
// never forwards the raw text to a log or an artifact, and it never stores the
|
|
12
|
+
// raw text on the result. The runner reports only a fixed, non-secret status. It
|
|
13
|
+
// passes the prompt one time through the in-memory `onPrompt` callback. It passes
|
|
14
|
+
// the credential bytes one time through the in-memory `onCredential` callback.
|
|
15
|
+
// The runner keeps the URL, the code, and any token byte out of every log line
|
|
16
|
+
// and every thrown error.
|
|
17
|
+
/** The default Codex device-login command. */
|
|
18
|
+
export const CODEX_DEVICE_LOGIN_COMMAND = "codex login --device-auth";
|
|
19
|
+
/**
|
|
20
|
+
* The maximum number of characters the runner keeps for the next chunk. The
|
|
21
|
+
* Codex prompt is small and puts the URL and the code close together. A sandbox
|
|
22
|
+
* can stream a large volume of output before the prompt. So after each parse the
|
|
23
|
+
* runner keeps only the most recent characters up to this limit. The retained
|
|
24
|
+
* buffer cannot grow without a bound across many chunks. The limit is far larger
|
|
25
|
+
* than the prompt, so the trailing window never drops a real prompt that spans a
|
|
26
|
+
* chunk boundary.
|
|
27
|
+
*/
|
|
28
|
+
const MAX_PARSE_BUFFER_CHARS = 64 * 1024;
|
|
29
|
+
/**
|
|
30
|
+
* Runs the device-login command through `driver`. Surfaces the prompt one time
|
|
31
|
+
* through `onPrompt`. On success it reads the credential and surfaces the bytes
|
|
32
|
+
* one time through `onCredential`. Returns a fixed status. Always disposes the
|
|
33
|
+
* driver. Never logs the raw stream, and never puts a URL, a code, or a token
|
|
34
|
+
* into a log line, the result, or a thrown error.
|
|
35
|
+
*/
|
|
36
|
+
export async function runDeviceLogin(driver, options) {
|
|
37
|
+
const { onPrompt, onCredential, authPath, timeoutMs, signal } = options;
|
|
38
|
+
const command = options.command ?? CODEX_DEVICE_LOGIN_COMMAND;
|
|
39
|
+
const parsePrompt = options.parsePrompt ?? parseDeviceLoginPrompt;
|
|
40
|
+
const log = options.log ?? (() => { });
|
|
41
|
+
let promptSurfaced = false;
|
|
42
|
+
// The in-memory parse buffer. The runner drops it as soon as it finds the
|
|
43
|
+
// prompt, so the secret-bearing stream never lives longer than one parse. The
|
|
44
|
+
// runner parses the full buffer, and it includes the whole new chunk. So a
|
|
45
|
+
// prompt at the start of one large chunk still parses. The runner bounds only
|
|
46
|
+
// the buffer that it keeps for the next chunk to {@link MAX_PARSE_BUFFER_CHARS}.
|
|
47
|
+
// The runner keeps the trailing window and drops the oldest characters. The
|
|
48
|
+
// prompt puts the URL and the code close together, so the trailing window
|
|
49
|
+
// always holds a real prompt that spans a chunk boundary.
|
|
50
|
+
let buffer = "";
|
|
51
|
+
const onStdout = (chunk) => {
|
|
52
|
+
if (promptSurfaced)
|
|
53
|
+
return;
|
|
54
|
+
buffer += chunk;
|
|
55
|
+
const prompt = parsePrompt(buffer);
|
|
56
|
+
if (prompt) {
|
|
57
|
+
promptSurfaced = true;
|
|
58
|
+
buffer = "";
|
|
59
|
+
onPrompt(prompt);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (buffer.length > MAX_PARSE_BUFFER_CHARS) {
|
|
63
|
+
buffer = buffer.slice(buffer.length - MAX_PARSE_BUFFER_CHARS);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
try {
|
|
67
|
+
if (signal?.aborted) {
|
|
68
|
+
log("[paperclip] Device login cancelled before start.");
|
|
69
|
+
return { outcome: "cancelled", exitCode: null, promptSurfaced };
|
|
70
|
+
}
|
|
71
|
+
const started = driver.start(command, onStdout);
|
|
72
|
+
const raced = await raceLoginRunnerExit(started, timeoutMs, signal);
|
|
73
|
+
if (raced.kind === "timeout") {
|
|
74
|
+
log("[paperclip] Device login timed out; disposing the sandbox.");
|
|
75
|
+
return { outcome: "timeout", exitCode: null, promptSurfaced };
|
|
76
|
+
}
|
|
77
|
+
if (raced.kind === "cancelled") {
|
|
78
|
+
log("[paperclip] Device login cancelled; disposing the sandbox.");
|
|
79
|
+
return { outcome: "cancelled", exitCode: null, promptSurfaced };
|
|
80
|
+
}
|
|
81
|
+
const exitCode = raced.exitCode;
|
|
82
|
+
if (exitCode !== 0) {
|
|
83
|
+
log("[paperclip] Device login command ended with a non-zero exit code.");
|
|
84
|
+
return { outcome: "failure", exitCode, promptSurfaced };
|
|
85
|
+
}
|
|
86
|
+
if (onCredential && authPath) {
|
|
87
|
+
const authBytes = await driver.readFile(authPath);
|
|
88
|
+
await onCredential(authBytes);
|
|
89
|
+
}
|
|
90
|
+
log("[paperclip] Device login command ended successfully.");
|
|
91
|
+
return { outcome: "success", exitCode, promptSurfaced };
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Convert any driver error to a fixed, non-secret error. The original error
|
|
95
|
+
// may embed streamed bytes, so the runner never propagates its message.
|
|
96
|
+
throw new Error("device login failed: the sandbox login command errored.");
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
// Always dispose the driver. A dispose error must not leak or mask the
|
|
100
|
+
// result, so the runner swallows it and logs a fixed line.
|
|
101
|
+
try {
|
|
102
|
+
await driver.dispose();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
log("[paperclip] Device login: the sandbox dispose step errored.");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=device-login-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-login-runner.js","sourceRoot":"","sources":["../../src/server/device-login-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-login-runner.test.d.ts","sourceRoot":"","sources":["../../src/server/device-login-runner.test.ts"],"names":[],"mappings":""}
|