@right-link/paperclip-plugin-codex-remote 0.3.1

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 (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/dist/cli/format-event.d.ts +2 -0
  4. package/dist/cli/format-event.d.ts.map +1 -0
  5. package/dist/cli/format-event.js +213 -0
  6. package/dist/cli/format-event.js.map +1 -0
  7. package/dist/cli/index.d.ts +2 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +2 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/quota-probe.d.ts +3 -0
  12. package/dist/cli/quota-probe.d.ts.map +1 -0
  13. package/dist/cli/quota-probe.js +97 -0
  14. package/dist/cli/quota-probe.js.map +1 -0
  15. package/dist/index.d.ts +17 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +84 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/server/adapter.d.ts +16 -0
  20. package/dist/server/adapter.d.ts.map +1 -0
  21. package/dist/server/adapter.js +157 -0
  22. package/dist/server/adapter.js.map +1 -0
  23. package/dist/server/adapter.test.d.ts +2 -0
  24. package/dist/server/adapter.test.d.ts.map +1 -0
  25. package/dist/server/adapter.test.js +84 -0
  26. package/dist/server/adapter.test.js.map +1 -0
  27. package/dist/server/codex-args.d.ts +13 -0
  28. package/dist/server/codex-args.d.ts.map +1 -0
  29. package/dist/server/codex-args.js +60 -0
  30. package/dist/server/codex-args.js.map +1 -0
  31. package/dist/server/codex-args.test.d.ts +2 -0
  32. package/dist/server/codex-args.test.d.ts.map +1 -0
  33. package/dist/server/codex-args.test.js +94 -0
  34. package/dist/server/codex-args.test.js.map +1 -0
  35. package/dist/server/codex-home.d.ts +47 -0
  36. package/dist/server/codex-home.d.ts.map +1 -0
  37. package/dist/server/codex-home.js +378 -0
  38. package/dist/server/codex-home.js.map +1 -0
  39. package/dist/server/codex-home.test.d.ts +2 -0
  40. package/dist/server/codex-home.test.d.ts.map +1 -0
  41. package/dist/server/codex-home.test.js +244 -0
  42. package/dist/server/codex-home.test.js.map +1 -0
  43. package/dist/server/execute.d.ts +16 -0
  44. package/dist/server/execute.d.ts.map +1 -0
  45. package/dist/server/execute.js +906 -0
  46. package/dist/server/execute.js.map +1 -0
  47. package/dist/server/execute.remote.test.d.ts +2 -0
  48. package/dist/server/execute.remote.test.d.ts.map +1 -0
  49. package/dist/server/execute.remote.test.js +487 -0
  50. package/dist/server/execute.remote.test.js.map +1 -0
  51. package/dist/server/index.d.ts +8 -0
  52. package/dist/server/index.d.ts.map +1 -0
  53. package/dist/server/index.js +57 -0
  54. package/dist/server/index.js.map +1 -0
  55. package/dist/server/parse.d.ts +22 -0
  56. package/dist/server/parse.d.ts.map +1 -0
  57. package/dist/server/parse.js +213 -0
  58. package/dist/server/parse.js.map +1 -0
  59. package/dist/server/parse.test.d.ts +2 -0
  60. package/dist/server/parse.test.d.ts.map +1 -0
  61. package/dist/server/parse.test.js +107 -0
  62. package/dist/server/parse.test.js.map +1 -0
  63. package/dist/server/quota-spawn-error.test.d.ts +2 -0
  64. package/dist/server/quota-spawn-error.test.d.ts.map +1 -0
  65. package/dist/server/quota-spawn-error.test.js +77 -0
  66. package/dist/server/quota-spawn-error.test.js.map +1 -0
  67. package/dist/server/quota.d.ts +64 -0
  68. package/dist/server/quota.d.ts.map +1 -0
  69. package/dist/server/quota.js +432 -0
  70. package/dist/server/quota.js.map +1 -0
  71. package/dist/server/sandbox-env.d.ts +4 -0
  72. package/dist/server/sandbox-env.d.ts.map +1 -0
  73. package/dist/server/sandbox-env.js +23 -0
  74. package/dist/server/sandbox-env.js.map +1 -0
  75. package/dist/server/skills.d.ts +8 -0
  76. package/dist/server/skills.d.ts.map +1 -0
  77. package/dist/server/skills.js +24 -0
  78. package/dist/server/skills.js.map +1 -0
  79. package/dist/server/tailscale.d.ts +24 -0
  80. package/dist/server/tailscale.d.ts.map +1 -0
  81. package/dist/server/tailscale.js +95 -0
  82. package/dist/server/tailscale.js.map +1 -0
  83. package/dist/server/test.d.ts +3 -0
  84. package/dist/server/test.d.ts.map +1 -0
  85. package/dist/server/test.js +811 -0
  86. package/dist/server/test.js.map +1 -0
  87. package/dist/server/test.remote.test.d.ts +2 -0
  88. package/dist/server/test.remote.test.d.ts.map +1 -0
  89. package/dist/server/test.remote.test.js +257 -0
  90. package/dist/server/test.remote.test.js.map +1 -0
  91. package/dist/ui/build-config.d.ts +3 -0
  92. package/dist/ui/build-config.d.ts.map +1 -0
  93. package/dist/ui/build-config.js +113 -0
  94. package/dist/ui/build-config.js.map +1 -0
  95. package/dist/ui/build-config.test.d.ts +2 -0
  96. package/dist/ui/build-config.test.d.ts.map +1 -0
  97. package/dist/ui/build-config.test.js +49 -0
  98. package/dist/ui/build-config.test.js.map +1 -0
  99. package/dist/ui/index.d.ts +3 -0
  100. package/dist/ui/index.d.ts.map +1 -0
  101. package/dist/ui/index.js +3 -0
  102. package/dist/ui/index.js.map +1 -0
  103. package/dist/ui/parse-stdout.d.ts +3 -0
  104. package/dist/ui/parse-stdout.d.ts.map +1 -0
  105. package/dist/ui/parse-stdout.js +261 -0
  106. package/dist/ui/parse-stdout.js.map +1 -0
  107. package/dist/ui/parse-stdout.test.d.ts +2 -0
  108. package/dist/ui/parse-stdout.test.d.ts.map +1 -0
  109. package/dist/ui/parse-stdout.test.js +77 -0
  110. package/dist/ui/parse-stdout.test.js.map +1 -0
  111. package/dist/ui-parser.d.ts +2 -0
  112. package/dist/ui-parser.d.ts.map +1 -0
  113. package/dist/ui-parser.js +245 -0
  114. package/dist/ui-parser.js.map +1 -0
  115. package/package.json +69 -0
@@ -0,0 +1,157 @@
1
+ /**
2
+ * External adapter entry point.
3
+ *
4
+ * Paperclip's adapter-plugin store loads an external adapter package by
5
+ * importing its main entry and calling `createServerAdapter()`, which must
6
+ * return a complete `ServerAdapterModule`. This module assembles the
7
+ * standalone codex_remote adapter from the package's own building blocks plus
8
+ * the sandbox preflight / remote-default behavior that previously lived in a
9
+ * host-side registry wrapper — so nothing needs to change in upstream
10
+ * Paperclip to register this adapter.
11
+ */
12
+ import { buildSandboxNpmInstallCommand, getAdapterSessionManagement, } from "@paperclipai/adapter-utils";
13
+ import { execute as baseExecute } from "./execute.js";
14
+ import { testEnvironment as baseTestEnvironment } from "./test.js";
15
+ import { listCodexSkills, syncCodexSkills } from "./skills.js";
16
+ import { sessionCodec, getQuotaWindows } from "./index.js";
17
+ import { models, modelProfiles, agentConfigurationDoc, type } from "../index.js";
18
+ export const CODEX_REMOTE_TYPE = type;
19
+ const DEFAULT_REMOTE_TIMEOUT_SEC = 300;
20
+ const CODEX_RUNTIME_PACKAGE = "@openai/codex";
21
+ const CODEX_RUNTIME_FALLBACK_COMMAND = "codex";
22
+ function requireRemoteTarget(ctx) {
23
+ const target = ctx.executionTarget;
24
+ if (!target || target.kind !== "remote") {
25
+ throw new Error("codex_remote requires a remote execution target.");
26
+ }
27
+ if (target.transport === "sandbox" && !target.runner) {
28
+ throw new Error("codex_remote requires a sandbox runner from the environment provider.");
29
+ }
30
+ return target;
31
+ }
32
+ function isSandboxTarget(target) {
33
+ return target.transport === "sandbox";
34
+ }
35
+ function failureResult(error, prefix) {
36
+ const message = error instanceof Error ? error.message : String(error);
37
+ return {
38
+ exitCode: 1,
39
+ signal: null,
40
+ timedOut: false,
41
+ errorMessage: `${prefix}: ${message}`,
42
+ resultJson: {
43
+ error: message,
44
+ phase: prefix,
45
+ },
46
+ };
47
+ }
48
+ export function applyCodexRemoteDefaults(config) {
49
+ const hasExplicitTimeout = typeof config.timeoutSec === "number" && Number.isFinite(config.timeoutSec) && config.timeoutSec > 0;
50
+ return {
51
+ ...config,
52
+ timeoutSec: hasExplicitTimeout ? config.timeoutSec : DEFAULT_REMOTE_TIMEOUT_SEC,
53
+ dangerouslyBypassApprovalsAndSandbox: true,
54
+ // Codex Remote is sandbox-runtime only. The agent owns repository cloning
55
+ // and Git finalization when the task requires them, so do not upload the
56
+ // host workspace or request provider Git-clone realization.
57
+ remoteWorkspaceSync: false,
58
+ };
59
+ }
60
+ async function verifySandboxWorkspace(input) {
61
+ const shell = input.target.shellCommand === "sh" ? "sh" : "bash";
62
+ const marker = input.bridgeChannel ? "BRIDGE_SESSION_OK" : "WORKSPACE_OK";
63
+ const label = input.bridgeChannel ? "bridge channel" : "main session";
64
+ const result = await input.target.runner.execute({
65
+ command: shell,
66
+ args: [
67
+ "-c",
68
+ `mkdir -p ${JSON.stringify(input.target.remoteCwd)} && ls -la ${JSON.stringify(input.target.remoteCwd)} 2>&1 && echo ${marker}`,
69
+ ],
70
+ cwd: "/",
71
+ env: input.bridgeChannel ? { PAPERCLIP_SANDBOX_EXEC_CHANNEL: "bridge" } : undefined,
72
+ timeoutMs: input.bridgeChannel ? 90_000 : 30_000,
73
+ });
74
+ if (result.timedOut || (result.exitCode ?? 1) !== 0) {
75
+ const detail = [result.stderr, result.stdout].filter(Boolean).join("\n").trim();
76
+ throw new Error(`codex_remote sandbox workspace verify (${label}) failed with exit=${result.exitCode ?? "null"} timedOut=${result.timedOut}${detail ? `: ${detail}` : ""}`);
77
+ }
78
+ await input.ctx.onLog("stdout", `[paperclip] codex_remote workspace verify (${label}): exit=${result.exitCode} timedOut=${result.timedOut}\n${result.stdout || ""}\n${result.stderr || ""}`);
79
+ }
80
+ async function executeCodexRemote(ctx) {
81
+ const target = requireRemoteTarget(ctx);
82
+ const config = applyCodexRemoteDefaults(ctx.config);
83
+ const codexRunTimeoutMs = typeof config.timeoutSec === "number" && config.timeoutSec > 0
84
+ ? config.timeoutSec * 1_000
85
+ : DEFAULT_REMOTE_TIMEOUT_SEC * 1_000;
86
+ if (isSandboxTarget(target)) {
87
+ try {
88
+ await verifySandboxWorkspace({ ctx, target });
89
+ await verifySandboxWorkspace({ ctx, target, bridgeChannel: true });
90
+ }
91
+ catch (error) {
92
+ return failureResult(error, "codex_remote_prepare_failed");
93
+ }
94
+ }
95
+ try {
96
+ return await baseExecute({
97
+ ...ctx,
98
+ executionTarget: isSandboxTarget(target)
99
+ ? {
100
+ ...target,
101
+ timeoutMs: codexRunTimeoutMs,
102
+ }
103
+ : target,
104
+ config,
105
+ });
106
+ }
107
+ catch (error) {
108
+ return failureResult(error, "codex_remote_execute_failed");
109
+ }
110
+ }
111
+ function hasPathSeparator(value) {
112
+ return value.includes("/") || value.includes("\\");
113
+ }
114
+ function shellQuote(value) {
115
+ return `'${value.replace(/'/g, `'\\''`)}'`;
116
+ }
117
+ function readConfiguredCommand(config) {
118
+ const value = typeof config.command === "string" ? config.command.trim() : "";
119
+ return value.length > 0 ? value : CODEX_RUNTIME_FALLBACK_COMMAND;
120
+ }
121
+ function buildRuntimeCommandSpec(config) {
122
+ const command = readConfiguredCommand(config);
123
+ const canSelfInstall = !hasPathSeparator(command) && command === CODEX_RUNTIME_FALLBACK_COMMAND;
124
+ const installLine = buildSandboxNpmInstallCommand(CODEX_RUNTIME_PACKAGE);
125
+ return {
126
+ command,
127
+ detectCommand: command,
128
+ installCommand: canSelfInstall
129
+ ? `if ! command -v ${shellQuote(command)} >/dev/null 2>&1; then ${installLine}; fi`
130
+ : null,
131
+ };
132
+ }
133
+ export function createServerAdapter() {
134
+ return {
135
+ type: CODEX_REMOTE_TYPE,
136
+ execute: (ctx) => executeCodexRemote(ctx),
137
+ testEnvironment: (ctx) => baseTestEnvironment({
138
+ ...ctx,
139
+ adapterType: CODEX_REMOTE_TYPE,
140
+ config: applyCodexRemoteDefaults(ctx.config),
141
+ }),
142
+ listSkills: listCodexSkills,
143
+ syncSkills: syncCodexSkills,
144
+ sessionCodec,
145
+ sessionManagement: getAdapterSessionManagement(CODEX_REMOTE_TYPE) ?? undefined,
146
+ models,
147
+ modelProfiles,
148
+ supportsLocalAgentJwt: true,
149
+ supportsInstructionsBundle: true,
150
+ instructionsPathKey: "instructionsFilePath",
151
+ requiresMaterializedRuntimeSkills: false,
152
+ getRuntimeCommandSpec: (config) => buildRuntimeCommandSpec(config),
153
+ getQuotaWindows,
154
+ agentConfigurationDoc,
155
+ };
156
+ }
157
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/server/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../src/server/adapter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,84 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { applyCodexRemoteDefaults, createServerAdapter, CODEX_REMOTE_TYPE } from "./adapter.js";
3
+ vi.mock("./execute.js", () => ({
4
+ execute: vi.fn(async () => ({
5
+ exitCode: 0,
6
+ signal: null,
7
+ timedOut: false,
8
+ resultJson: { ok: true },
9
+ })),
10
+ }));
11
+ describe("createServerAdapter", () => {
12
+ it("returns a complete standalone codex_remote module", () => {
13
+ const adapter = createServerAdapter();
14
+ expect(adapter.type).toBe("codex_remote");
15
+ expect(CODEX_REMOTE_TYPE).toBe("codex_remote");
16
+ expect(typeof adapter.execute).toBe("function");
17
+ expect(typeof adapter.testEnvironment).toBe("function");
18
+ expect(typeof adapter.getRuntimeCommandSpec).toBe("function");
19
+ expect(Array.isArray(adapter.models)).toBe(true);
20
+ expect(adapter.instructionsPathKey).toBe("instructionsFilePath");
21
+ expect(adapter.requiresMaterializedRuntimeSkills).toBe(false);
22
+ });
23
+ it("provisions the @openai/codex runtime command by default", () => {
24
+ const adapter = createServerAdapter();
25
+ const spec = adapter.getRuntimeCommandSpec?.({});
26
+ expect(spec?.command).toBe("codex");
27
+ expect(spec?.detectCommand).toBe("codex");
28
+ expect(spec?.installCommand).toContain("@openai/codex");
29
+ });
30
+ it("does not self-install when an explicit command path is configured", () => {
31
+ const adapter = createServerAdapter();
32
+ const spec = adapter.getRuntimeCommandSpec?.({ command: "/usr/local/bin/codex" });
33
+ expect(spec?.command).toBe("/usr/local/bin/codex");
34
+ expect(spec?.installCommand).toBeNull();
35
+ });
36
+ it("rejects a non-remote execution target", async () => {
37
+ const adapter = createServerAdapter();
38
+ await expect(adapter.execute({
39
+ config: {},
40
+ executionTarget: { kind: "local" },
41
+ onLog: async () => { },
42
+ })).rejects.toThrow(/remote execution target/);
43
+ });
44
+ it("accepts an SSH execution target", async () => {
45
+ const adapter = createServerAdapter();
46
+ const result = await adapter.execute({
47
+ config: {},
48
+ executionTarget: {
49
+ kind: "remote",
50
+ transport: "ssh",
51
+ remoteCwd: "/workspace",
52
+ spec: {
53
+ host: "127.0.0.1",
54
+ port: 2222,
55
+ username: "paperclip",
56
+ remoteWorkspacePath: "/workspace",
57
+ remoteCwd: "/workspace",
58
+ privateKey: "PRIVATE KEY",
59
+ knownHosts: "[127.0.0.1]:2222 ssh-ed25519 AAAA",
60
+ strictHostKeyChecking: true,
61
+ },
62
+ },
63
+ onLog: async () => { },
64
+ });
65
+ expect(result.exitCode).toBe(0);
66
+ });
67
+ });
68
+ describe("applyCodexRemoteDefaults", () => {
69
+ it("applies sandbox-only remote defaults", () => {
70
+ const result = applyCodexRemoteDefaults({});
71
+ expect(result.timeoutSec).toBe(300);
72
+ expect(result.dangerouslyBypassApprovalsAndSandbox).toBe(true);
73
+ expect(result.remoteWorkspaceSync).toBe(false);
74
+ });
75
+ it("preserves an explicit positive timeout", () => {
76
+ const result = applyCodexRemoteDefaults({ timeoutSec: 900 });
77
+ expect(result.timeoutSec).toBe(900);
78
+ });
79
+ it("replaces a non-positive timeout with the default", () => {
80
+ expect(applyCodexRemoteDefaults({ timeoutSec: 0 }).timeoutSec).toBe(300);
81
+ expect(applyCodexRemoteDefaults({ timeoutSec: -5 }).timeoutSec).toBe(300);
82
+ });
83
+ });
84
+ //# sourceMappingURL=adapter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["../../src/server/adapter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type BuildCodexExecArgsResult = {
2
+ args: string[];
3
+ model: string;
4
+ fastModeRequested: boolean;
5
+ fastModeApplied: boolean;
6
+ fastModeIgnoredReason: string | null;
7
+ };
8
+ export declare function buildCodexExecArgs(config: unknown, options?: {
9
+ resumeSessionId?: string | null;
10
+ skipGitRepoCheck?: boolean;
11
+ isolatePaperclipTaskSystem?: boolean;
12
+ }): BuildCodexExecArgsResult;
13
+ //# sourceMappingURL=codex-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-args.d.ts","sourceRoot":"","sources":["../../src/server/codex-args.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC,CAAC;AAkBF,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,EACf,OAAO,GAAE;IACP,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACjC,GACL,wBAAwB,CAmD1B"}
@@ -0,0 +1,60 @@
1
+ import { asBoolean, asString, asStringArray } from "@paperclipai/adapter-utils/server-utils";
2
+ import { CODEX_REMOTE_FAST_MODE_SUPPORTED_MODELS, isCodexRemoteFastModeSupported, } from "../index.js";
3
+ function readExtraArgs(config) {
4
+ const fromExtraArgs = asStringArray(asRecord(config).extraArgs);
5
+ if (fromExtraArgs.length > 0)
6
+ return fromExtraArgs;
7
+ return asStringArray(asRecord(config).args);
8
+ }
9
+ function asRecord(value) {
10
+ return typeof value === "object" && value !== null && !Array.isArray(value)
11
+ ? value
12
+ : {};
13
+ }
14
+ function formatFastModeSupportedModels() {
15
+ return `${CODEX_REMOTE_FAST_MODE_SUPPORTED_MODELS.join(", ")} or manually configured model IDs`;
16
+ }
17
+ export function buildCodexExecArgs(config, options = {}) {
18
+ const record = asRecord(config);
19
+ const model = asString(record.model, "").trim();
20
+ const modelReasoningEffort = asString(record.modelReasoningEffort, asString(record.reasoningEffort, "")).trim();
21
+ const search = asBoolean(record.search, false);
22
+ const fastModeRequested = asBoolean(record.fastMode, false);
23
+ const fastModeApplied = fastModeRequested && isCodexRemoteFastModeSupported(model);
24
+ const bypass = asBoolean(record.dangerouslyBypassApprovalsAndSandbox, asBoolean(record.dangerouslyBypassSandbox, false));
25
+ const extraArgs = readExtraArgs(record);
26
+ const args = ["exec", "--json"];
27
+ if (options.skipGitRepoCheck)
28
+ args.push("--skip-git-repo-check");
29
+ if (options.isolatePaperclipTaskSystem) {
30
+ args.push("-c", "mcp_servers={}", "-c", "plugins={}", "-c", "marketplaces={}");
31
+ }
32
+ if (search)
33
+ args.unshift("--search");
34
+ if (bypass)
35
+ args.push("--dangerously-bypass-approvals-and-sandbox");
36
+ if (model)
37
+ args.push("--model", model);
38
+ if (modelReasoningEffort) {
39
+ args.push("-c", `model_reasoning_effort=${JSON.stringify(modelReasoningEffort)}`);
40
+ }
41
+ if (fastModeApplied) {
42
+ args.push("-c", 'service_tier="fast"', "-c", "features.fast_mode=true");
43
+ }
44
+ if (extraArgs.length > 0)
45
+ args.push(...extraArgs);
46
+ if (options.resumeSessionId)
47
+ args.push("resume", options.resumeSessionId, "-");
48
+ else
49
+ args.push("-");
50
+ return {
51
+ args,
52
+ model,
53
+ fastModeRequested,
54
+ fastModeApplied,
55
+ fastModeIgnoredReason: fastModeRequested && !fastModeApplied
56
+ ? `Configured fast mode is currently only supported on ${formatFastModeSupportedModels()}; Paperclip will ignore it for model ${model || "(default)"}.`
57
+ : null,
58
+ };
59
+ }
60
+ //# sourceMappingURL=codex-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-args.js","sourceRoot":"","sources":["../../src/server/codex-args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EACL,uCAAuC,EACvC,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AAUrB,SAAS,aAAa,CAAC,MAAe;IACpC,MAAM,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;IAChE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,aAAa,CAAC;IACnD,OAAO,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,6BAA6B;IACpC,OAAO,GAAG,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAAe,EACf,UAII,EAAE;IAEN,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,oBAAoB,GAAG,QAAQ,CACnC,MAAM,CAAC,oBAAoB,EAC3B,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,CAAC,CACrC,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/C,MAAM,iBAAiB,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,iBAAiB,IAAI,8BAA8B,CAAC,KAAK,CAAC,CAAC;IACnF,MAAM,MAAM,GAAG,SAAS,CACtB,MAAM,CAAC,oCAAoC,EAC3C,SAAS,CAAC,MAAM,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAClD,CAAC;IACF,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAExC,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,IAAI,OAAO,CAAC,gBAAgB;QAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACjE,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CACP,IAAI,EACJ,gBAAgB,EAChB,IAAI,EACJ,YAAY,EACZ,IAAI,EACJ,iBAAiB,CAClB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM;QAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACpE,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,oBAAoB,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,yBAAyB,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,eAAe;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;;QAC1E,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEpB,OAAO;QACL,IAAI;QACJ,KAAK;QACL,iBAAiB;QACjB,eAAe;QACf,qBAAqB,EACnB,iBAAiB,IAAI,CAAC,eAAe;YACnC,CAAC,CAAC,uDAAuD,6BAA6B,EAAE,wCAAwC,KAAK,IAAI,WAAW,GAAG;YACvJ,CAAC,CAAC,IAAI;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codex-args.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-args.test.d.ts","sourceRoot":"","sources":["../../src/server/codex-args.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildCodexExecArgs } from "./codex-args.js";
3
+ describe("buildCodexExecArgs", () => {
4
+ it("enables Codex fast mode overrides for GPT-5.4", () => {
5
+ const result = buildCodexExecArgs({
6
+ model: "gpt-5.4",
7
+ search: true,
8
+ fastMode: true,
9
+ });
10
+ expect(result.fastModeRequested).toBe(true);
11
+ expect(result.fastModeApplied).toBe(true);
12
+ expect(result.fastModeIgnoredReason).toBeNull();
13
+ expect(result.args).toEqual([
14
+ "--search",
15
+ "exec",
16
+ "--json",
17
+ "--model",
18
+ "gpt-5.4",
19
+ "-c",
20
+ 'service_tier="fast"',
21
+ "-c",
22
+ "features.fast_mode=true",
23
+ "-",
24
+ ]);
25
+ });
26
+ it("enables Codex fast mode overrides for manual models", () => {
27
+ const result = buildCodexExecArgs({
28
+ model: "gpt-5.5",
29
+ fastMode: true,
30
+ });
31
+ expect(result.fastModeRequested).toBe(true);
32
+ expect(result.fastModeApplied).toBe(true);
33
+ expect(result.fastModeIgnoredReason).toBeNull();
34
+ expect(result.args).toEqual([
35
+ "exec",
36
+ "--json",
37
+ "--model",
38
+ "gpt-5.5",
39
+ "-c",
40
+ 'service_tier="fast"',
41
+ "-c",
42
+ "features.fast_mode=true",
43
+ "-",
44
+ ]);
45
+ });
46
+ it("ignores fast mode for unsupported models", () => {
47
+ const result = buildCodexExecArgs({
48
+ model: "gpt-5.3-codex",
49
+ fastMode: true,
50
+ });
51
+ expect(result.fastModeRequested).toBe(true);
52
+ expect(result.fastModeApplied).toBe(false);
53
+ expect(result.fastModeIgnoredReason).toContain("currently only supported on gpt-5.4 or manually configured model IDs");
54
+ expect(result.args).toEqual([
55
+ "exec",
56
+ "--json",
57
+ "--model",
58
+ "gpt-5.3-codex",
59
+ "-",
60
+ ]);
61
+ });
62
+ it("adds --skip-git-repo-check when requested", () => {
63
+ const result = buildCodexExecArgs({
64
+ model: "gpt-5.3-codex",
65
+ }, { skipGitRepoCheck: true });
66
+ expect(result.args).toEqual([
67
+ "exec",
68
+ "--json",
69
+ "--skip-git-repo-check",
70
+ "--model",
71
+ "gpt-5.3-codex",
72
+ "-",
73
+ ]);
74
+ });
75
+ it("can isolate sandbox runs from external task-management tools while keeping user config", () => {
76
+ const result = buildCodexExecArgs({
77
+ model: "gpt-5.3-codex",
78
+ }, { isolatePaperclipTaskSystem: true });
79
+ expect(result.args).toEqual([
80
+ "exec",
81
+ "--json",
82
+ "-c",
83
+ "mcp_servers={}",
84
+ "-c",
85
+ "plugins={}",
86
+ "-c",
87
+ "marketplaces={}",
88
+ "--model",
89
+ "gpt-5.3-codex",
90
+ "-",
91
+ ]);
92
+ });
93
+ });
94
+ //# sourceMappingURL=codex-args.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-args.test.js","sourceRoot":"","sources":["../../src/server/codex-args.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { AdapterExecutionContext } from "@paperclipai/adapter-utils";
2
+ /**
3
+ * Reduces a Codex `config.toml` to the minimum needed inside a remote sandbox:
4
+ * the allowlisted top-level keys ({@link REMOTE_KEPT_TOP_LEVEL_KEYS}) plus the
5
+ * `[model_providers.*]` sections. Everything else — MCP servers, project trust
6
+ * lists, plugins, marketplaces, desktop/Windows host settings — is dropped, so
7
+ * Codex starts clean and fast and never tries to launch host-only tooling.
8
+ *
9
+ * Each provider also gets `supports_websockets = false` injected: Codex defaults
10
+ * to a `wss://` transport for the Responses API, but a sandbox reaching the
11
+ * provider through a userspace-Tailscale HTTP proxy cannot open that WebSocket,
12
+ * so Codex burns ~75s retrying it before falling back to HTTP on every run (the
13
+ * misleading "failed to refresh available models: timeout waiting for child
14
+ * process to exit"). Forcing HTTP removes that stall.
15
+ */
16
+ export declare function sanitizeRemoteCodexConfigToml(toml: string): string;
17
+ /**
18
+ * Injects `supports_websockets = false` into every `[model_providers.<name>]`
19
+ * section that does not already set the flag. Unlike
20
+ * {@link sanitizeRemoteCodexConfigToml}, this preserves all other config
21
+ * content — it is safe to apply to both local and remote config copies.
22
+ */
23
+ export declare function injectWebsocketsDisabled(toml: string): string;
24
+ /**
25
+ * Builds a throwaway Codex home directory suitable for syncing into a remote
26
+ * sandbox: the same auth/instructions as the managed home, but with a
27
+ * sandbox-sanitized `config.toml` (see {@link sanitizeRemoteCodexConfigToml}).
28
+ * The caller must invoke `cleanup()` when the run finishes.
29
+ */
30
+ export declare function prepareRemoteCodexHomeAsset(sourceHome: string): Promise<{
31
+ dir: string;
32
+ cleanup: () => Promise<void>;
33
+ }>;
34
+ export declare function pathExists(candidate: string): Promise<boolean>;
35
+ export declare function resolveSharedCodexHomeDir(env?: NodeJS.ProcessEnv): string;
36
+ export declare function resolveManagedCodexHomeDir(env: NodeJS.ProcessEnv, companyId?: string): string;
37
+ /**
38
+ * Writes an `auth.json` containing only `OPENAI_API_KEY` so the codex CLI can
39
+ * authenticate via API key. Overwrites any existing file or symlink at that
40
+ * path. Required because the codex CLI (>= 0.122) ignores the `OPENAI_API_KEY`
41
+ * environment variable and only reads credentials from `$CODEX_HOME/auth.json`.
42
+ */
43
+ export declare function writeApiKeyAuthJson(home: string, apiKey: string): Promise<void>;
44
+ export declare function prepareManagedCodexHome(env: NodeJS.ProcessEnv, onLog: AdapterExecutionContext["onLog"], companyId?: string, options?: {
45
+ apiKey?: string | null;
46
+ }): Promise<string>;
47
+ //# sourceMappingURL=codex-home.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-home.d.ts","sourceRoot":"","sources":["../../src/server/codex-home.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AA+C1E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+ElE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgC7D;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CA0BxD;AAMD,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEpE;AAED,wBAAgB,yBAAyB,CACvC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAGR;AAMD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CASR;AA0FD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrF;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,KAAK,EAAE,uBAAuB,CAAC,OAAO,CAAC,EACvC,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GACvC,OAAO,CAAC,MAAM,CAAC,CAiEjB"}