xcode-copilot-server 3.4.0 → 3.4.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.
- package/dist/banner.d.ts +4 -4
- package/dist/banner.js +45 -12
- package/dist/banner.js.map +1 -1
- package/dist/bridge-constants.d.ts +2 -0
- package/dist/bridge-constants.js +3 -0
- package/dist/bridge-constants.js.map +1 -0
- package/dist/cli-validators.d.ts +0 -1
- package/dist/cli-validators.js +2 -2
- package/dist/cli-validators.js.map +1 -1
- package/dist/config-schema.d.ts +107 -0
- package/dist/config-schema.js +53 -0
- package/dist/config-schema.js.map +1 -0
- package/dist/config.d.ts +3 -28
- package/dist/config.js +23 -62
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/conversation-manager.d.ts +9 -4
- package/dist/conversation-manager.js +44 -61
- package/dist/conversation-manager.js.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/launchd/agent.d.ts +5 -9
- package/dist/launchd/agent.js +13 -12
- package/dist/launchd/agent.js.map +1 -1
- package/dist/launchd/index.d.ts +3 -3
- package/dist/launchd/index.js +1 -1
- package/dist/launchd/index.js.map +1 -1
- package/dist/launchd/socket.d.ts +2 -1
- package/dist/providers/claude/provider.js +40 -64
- package/dist/providers/claude/provider.js.map +1 -1
- package/dist/providers/claude/streaming.d.ts +10 -1
- package/dist/providers/claude/streaming.js +7 -3
- package/dist/providers/claude/streaming.js.map +1 -1
- package/dist/providers/claude/tool-results.js +1 -1
- package/dist/providers/claude/tool-results.js.map +1 -1
- package/dist/providers/codex/provider.js +28 -60
- package/dist/providers/codex/provider.js.map +1 -1
- package/dist/providers/codex/streaming.d.ts +12 -3
- package/dist/providers/codex/streaming.js +6 -6
- package/dist/providers/codex/streaming.js.map +1 -1
- package/dist/providers/codex/tool-results.js +1 -1
- package/dist/providers/codex/tool-results.js.map +1 -1
- package/dist/providers/index.d.ts +4 -23
- package/dist/providers/index.js +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/names.d.ts +4 -0
- package/dist/providers/names.js +7 -0
- package/dist/providers/names.js.map +1 -0
- package/dist/providers/openai/provider.js +5 -14
- package/dist/providers/openai/provider.js.map +1 -1
- package/dist/providers/shared/continuation.d.ts +10 -0
- package/dist/providers/shared/continuation.js +18 -0
- package/dist/providers/shared/continuation.js.map +1 -0
- package/dist/providers/shared/prompt-utils.d.ts +0 -11
- package/dist/providers/shared/prompt-utils.js +0 -11
- package/dist/providers/shared/prompt-utils.js.map +1 -1
- package/dist/providers/shared/session-config.d.ts +12 -3
- package/dist/providers/shared/session-config.js +24 -7
- package/dist/providers/shared/session-config.js.map +1 -1
- package/dist/providers/shared/streaming-core.d.ts +12 -2
- package/dist/providers/shared/streaming-core.js +183 -161
- package/dist/providers/shared/streaming-core.js.map +1 -1
- package/dist/providers/shared/streaming-orchestrator.d.ts +11 -0
- package/dist/providers/shared/streaming-orchestrator.js +11 -0
- package/dist/providers/shared/streaming-orchestrator.js.map +1 -0
- package/dist/providers/shared/user-agent-guard.d.ts +3 -0
- package/dist/providers/shared/user-agent-guard.js +17 -0
- package/dist/providers/shared/user-agent-guard.js.map +1 -0
- package/dist/settings-patcher/claude.d.ts +1 -2
- package/dist/settings-patcher/claude.js +35 -13
- package/dist/settings-patcher/claude.js.map +1 -1
- package/dist/settings-patcher/codex.d.ts +1 -20
- package/dist/settings-patcher/codex.js +58 -31
- package/dist/settings-patcher/codex.js.map +1 -1
- package/dist/settings-patcher/index.d.ts +2 -15
- package/dist/settings-patcher/index.js +15 -36
- package/dist/settings-patcher/index.js.map +1 -1
- package/dist/settings-patcher/types.d.ts +21 -0
- package/dist/settings-patcher/url-utils.d.ts +1 -0
- package/dist/settings-patcher/url-utils.js +6 -0
- package/dist/settings-patcher/url-utils.js.map +1 -0
- package/dist/shutdown.d.ts +16 -0
- package/dist/shutdown.js +53 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/startup.js +65 -139
- package/dist/startup.js.map +1 -1
- package/dist/tool-bridge/constants.d.ts +4 -2
- package/dist/tool-bridge/constants.js +4 -2
- package/dist/tool-bridge/constants.js.map +1 -1
- package/dist/tool-bridge/index.d.ts +2 -2
- package/dist/tool-bridge/index.js +6 -5
- package/dist/tool-bridge/index.js.map +1 -1
- package/dist/tool-bridge/routes.d.ts +2 -2
- package/dist/tool-bridge/routes.js +24 -22
- package/dist/tool-bridge/routes.js.map +1 -1
- package/dist/tool-bridge/session-lifecycle.js +6 -3
- package/dist/tool-bridge/session-lifecycle.js.map +1 -1
- package/dist/tool-bridge/state.d.ts +4 -25
- package/dist/tool-bridge/state.js +6 -65
- package/dist/tool-bridge/state.js.map +1 -1
- package/dist/tool-bridge/tool-router.d.ts +1 -0
- package/dist/tool-bridge/tool-router.js +26 -19
- package/dist/tool-bridge/tool-router.js.map +1 -1
- package/dist/utils/child-process.d.ts +2 -0
- package/dist/utils/child-process.js +8 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/type-guards.d.ts +2 -0
- package/dist/utils/type-guards.js +7 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/package.json +1 -1
|
@@ -6,16 +6,18 @@
|
|
|
6
6
|
// any Codex process it spawns) can see it without a shell restart.
|
|
7
7
|
import { existsSync } from "node:fs";
|
|
8
8
|
import { readFile, writeFile, unlink, mkdir } from "node:fs/promises";
|
|
9
|
-
import { execFile as execFileCb } from "node:child_process";
|
|
10
|
-
import { promisify } from "node:util";
|
|
11
9
|
import { join } from "node:path";
|
|
12
10
|
import { homedir } from "node:os";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
import { extractLocalhostPort } from "./url-utils.js";
|
|
12
|
+
import { defaultExec } from "../utils/child-process.js";
|
|
13
|
+
import { isRecord } from "../utils/type-guards.js";
|
|
14
|
+
function isEnvBackup(value) {
|
|
15
|
+
if (!isRecord(value))
|
|
16
|
+
return false;
|
|
17
|
+
return (("OPENAI_BASE_URL" in value && (typeof value.OPENAI_BASE_URL === "string" || value.OPENAI_BASE_URL === null)) &&
|
|
18
|
+
("OPENAI_API_KEY" in value && (typeof value.OPENAI_API_KEY === "string" || value.OPENAI_API_KEY === null)));
|
|
17
19
|
}
|
|
18
|
-
|
|
20
|
+
function defaultCodexBackupPath() {
|
|
19
21
|
return join(homedir(), "Library/Developer/Xcode/CodingAssistant/codex", "env.backup.json");
|
|
20
22
|
}
|
|
21
23
|
async function launchctlGetenv(exec, name) {
|
|
@@ -24,6 +26,7 @@ async function launchctlGetenv(exec, name) {
|
|
|
24
26
|
return value || null;
|
|
25
27
|
}
|
|
26
28
|
catch {
|
|
29
|
+
// launchctl exits non-zero when the env var is unset, that's expected
|
|
27
30
|
return null;
|
|
28
31
|
}
|
|
29
32
|
}
|
|
@@ -37,15 +40,16 @@ export async function detectCodexPatchState(options) {
|
|
|
37
40
|
try {
|
|
38
41
|
const url = await launchctlGetenv(exec, "OPENAI_BASE_URL");
|
|
39
42
|
if (url) {
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
return { patched: true, port
|
|
43
|
+
const port = extractLocalhostPort(url);
|
|
44
|
+
if (port !== undefined) {
|
|
45
|
+
return { patched: true, port };
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
catch (err) {
|
|
47
50
|
logger.warn(`Could not read OPENAI_BASE_URL: ${String(err)}`);
|
|
48
51
|
}
|
|
52
|
+
// Backup exists, so a restore is needed even if we can't read the current port.
|
|
49
53
|
return { patched: true };
|
|
50
54
|
}
|
|
51
55
|
export async function patchCodexSettings(options) {
|
|
@@ -63,52 +67,75 @@ export async function patchCodexSettings(options) {
|
|
|
63
67
|
await mkdir(dir, { recursive: true });
|
|
64
68
|
await writeFile(backupFile, JSON.stringify(backup, null, 2) + "\n", "utf-8");
|
|
65
69
|
}
|
|
70
|
+
// Let exec errors propagate. The caller (patchSettings) decides how to handle them.
|
|
66
71
|
await exec("launchctl", ["setenv", "OPENAI_BASE_URL", baseUrl]);
|
|
67
72
|
await exec("launchctl", ["setenv", "OPENAI_API_KEY", "xcode-copilot"]);
|
|
68
73
|
}
|
|
74
|
+
async function unsetEnvVars(exec, logger) {
|
|
75
|
+
try {
|
|
76
|
+
await exec("launchctl", ["unsetenv", "OPENAI_BASE_URL"]);
|
|
77
|
+
await exec("launchctl", ["unsetenv", "OPENAI_API_KEY"]);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
logger.warn(`Failed to unset env vars: ${String(err)}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function readEnvBackup(backupFile, logger) {
|
|
84
|
+
if (!existsSync(backupFile))
|
|
85
|
+
return null;
|
|
86
|
+
const raw = await readFile(backupFile, "utf-8");
|
|
87
|
+
let parsed;
|
|
88
|
+
try {
|
|
89
|
+
parsed = JSON.parse(raw);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
logger.warn("Backup file contains invalid JSON, unsetting env vars");
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (!isEnvBackup(parsed)) {
|
|
96
|
+
logger.warn("Backup file has unexpected shape, unsetting env vars");
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return parsed;
|
|
100
|
+
}
|
|
69
101
|
export async function restoreCodexSettings(options) {
|
|
70
102
|
const { logger } = options;
|
|
71
103
|
const exec = options.exec ?? defaultExec;
|
|
72
104
|
const backupFile = options.backupFile ?? defaultCodexBackupPath();
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
await exec("launchctl", ["unsetenv", "OPENAI_BASE_URL"]);
|
|
77
|
-
await exec("launchctl", ["unsetenv", "OPENAI_API_KEY"]);
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
logger.warn(`Failed to unset env vars: ${String(err)}`);
|
|
81
|
-
}
|
|
105
|
+
const backup = await readEnvBackup(backupFile, logger);
|
|
106
|
+
if (!backup) {
|
|
107
|
+
await unsetEnvVars(exec, logger);
|
|
82
108
|
return;
|
|
83
109
|
}
|
|
110
|
+
// Best-effort: restore as many env vars as possible.
|
|
84
111
|
try {
|
|
85
|
-
const raw = await readFile(backupFile, "utf-8");
|
|
86
|
-
const backup = JSON.parse(raw);
|
|
87
112
|
if (backup.OPENAI_BASE_URL != null) {
|
|
88
113
|
await exec("launchctl", ["setenv", "OPENAI_BASE_URL", backup.OPENAI_BASE_URL]);
|
|
89
114
|
}
|
|
90
115
|
else {
|
|
91
116
|
await exec("launchctl", ["unsetenv", "OPENAI_BASE_URL"]);
|
|
92
117
|
}
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
logger.warn(`Failed to restore OPENAI_BASE_URL: ${String(err)}`);
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
93
123
|
if (backup.OPENAI_API_KEY != null) {
|
|
94
124
|
await exec("launchctl", ["setenv", "OPENAI_API_KEY", backup.OPENAI_API_KEY]);
|
|
95
125
|
}
|
|
96
126
|
else {
|
|
97
127
|
await exec("launchctl", ["unsetenv", "OPENAI_API_KEY"]);
|
|
98
128
|
}
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
logger.warn(`Failed to restore OPENAI_API_KEY: ${String(err)}`);
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
99
134
|
await unlink(backupFile);
|
|
100
|
-
logger.info("Restored env vars from backup");
|
|
101
135
|
}
|
|
102
136
|
catch (err) {
|
|
103
|
-
logger.warn(`Failed to
|
|
104
|
-
// Restore failed, just try to unset both
|
|
105
|
-
try {
|
|
106
|
-
await exec("launchctl", ["unsetenv", "OPENAI_BASE_URL"]);
|
|
107
|
-
await exec("launchctl", ["unsetenv", "OPENAI_API_KEY"]);
|
|
108
|
-
}
|
|
109
|
-
catch (unsetErr) {
|
|
110
|
-
logger.warn(`Failed to unset env vars during recovery: ${String(unsetErr)}`);
|
|
111
|
-
}
|
|
137
|
+
logger.warn(`Failed to remove backup file: ${String(err)}`);
|
|
112
138
|
}
|
|
139
|
+
logger.info("Restored env vars from backup");
|
|
113
140
|
}
|
|
114
141
|
//# sourceMappingURL=codex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/settings-patcher/codex.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,sEAAsE;AACtE,sHAAsH;AACtH,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/settings-patcher/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import type { Logger } from "copilot-sdk-proxy";
|
|
2
2
|
import type { ProxyName, ProxyMode } from "../providers/index.js";
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
export type { ExecFn, CodexPatchOptions, CodexRestoreOptions, CodexDetectOptions, } from "./codex.js";
|
|
6
|
-
export { defaultCodexBackupPath, detectCodexPatchState, patchCodexSettings, restoreCodexSettings, } from "./codex.js";
|
|
7
|
-
export declare const patcherByProxy: Partial<Record<ProxyName, {
|
|
8
|
-
patch: (opts: {
|
|
9
|
-
port: number;
|
|
10
|
-
logger: Logger;
|
|
11
|
-
}) => Promise<void>;
|
|
12
|
-
restore: (opts: {
|
|
13
|
-
logger: Logger;
|
|
14
|
-
}) => Promise<void>;
|
|
15
|
-
}>>;
|
|
16
|
-
export declare function patchAll(port: number, logger: Logger): Promise<void>;
|
|
17
|
-
export declare function restoreAll(logger: Logger): Promise<void>;
|
|
3
|
+
import type { SettingsPatcher } from "./types.js";
|
|
4
|
+
export declare const patcherByProxy: Partial<Record<ProxyName, SettingsPatcher>>;
|
|
18
5
|
export declare function patchSettings(proxy: ProxyMode | null, port: number, logger: Logger): Promise<void>;
|
|
19
6
|
export declare function restoreSettings(proxy: ProxyMode | null, logger: Logger): Promise<void>;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import { patchClaudeSettings, restoreClaudeSettings } from "./claude.js";
|
|
2
|
-
import { patchCodexSettings, restoreCodexSettings } from "./codex.js";
|
|
3
|
-
export { defaultSettingsPaths, detectPatchState, patchClaudeSettings, restoreClaudeSettings, } from "./claude.js";
|
|
4
|
-
export { defaultCodexBackupPath, detectCodexPatchState, patchCodexSettings, restoreCodexSettings, } from "./codex.js";
|
|
1
|
+
import { detectPatchState, patchClaudeSettings, restoreClaudeSettings } from "./claude.js";
|
|
2
|
+
import { detectCodexPatchState, patchCodexSettings, restoreCodexSettings } from "./codex.js";
|
|
5
3
|
export const patcherByProxy = {
|
|
6
|
-
claude: { patch: patchClaudeSettings, restore: restoreClaudeSettings },
|
|
7
|
-
codex: { patch: patchCodexSettings, restore: restoreCodexSettings },
|
|
4
|
+
claude: { detect: detectPatchState, patch: patchClaudeSettings, restore: restoreClaudeSettings },
|
|
5
|
+
codex: { detect: detectCodexPatchState, patch: patchCodexSettings, restore: restoreCodexSettings },
|
|
8
6
|
};
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function resolvePatchers(proxy) {
|
|
8
|
+
if (proxy === "auto" || !proxy)
|
|
9
|
+
return Object.values(patcherByProxy);
|
|
10
|
+
const p = patcherByProxy[proxy];
|
|
11
|
+
return p ? [p] : [];
|
|
12
|
+
}
|
|
13
|
+
export async function patchSettings(proxy, port, logger) {
|
|
14
|
+
for (const patcher of resolvePatchers(proxy)) {
|
|
11
15
|
await patcher.patch({ port, logger });
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
// Best-effort: continue restoring other providers if one fails.
|
|
19
|
+
export async function restoreSettings(proxy, logger) {
|
|
20
|
+
for (const patcher of resolvePatchers(proxy)) {
|
|
16
21
|
try {
|
|
17
22
|
await patcher.restore({ logger });
|
|
18
23
|
}
|
|
@@ -21,30 +26,4 @@ export async function restoreAll(logger) {
|
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
|
-
export async function patchSettings(proxy, port, logger) {
|
|
25
|
-
if (proxy === "auto" || !proxy) {
|
|
26
|
-
await patchAll(port, logger);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
const patcher = patcherByProxy[proxy];
|
|
30
|
-
if (patcher)
|
|
31
|
-
await patcher.patch({ port, logger });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export async function restoreSettings(proxy, logger) {
|
|
35
|
-
if (proxy === "auto" || !proxy) {
|
|
36
|
-
await restoreAll(logger);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
const patcher = patcherByProxy[proxy];
|
|
40
|
-
if (patcher) {
|
|
41
|
-
try {
|
|
42
|
-
await patcher.restore({ logger });
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
logger.error(`Failed to restore settings: ${String(err)}`);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
29
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings-patcher/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings-patcher/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE7F,MAAM,CAAC,MAAM,cAAc,GAAgD;IACzE,MAAM,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE,qBAAqB,EAAE;IAChG,KAAK,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,oBAAoB,EAAE;CACnG,CAAC;AAEF,SAAS,eAAe,CAAC,KAAuB;IAC9C,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACrE,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAChC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAuB,EAAE,IAAY,EAAE,MAAc;IACvF,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7C,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAuB,EAAE,MAAc;IAC3E,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,+BAA+B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Logger } from "copilot-sdk-proxy";
|
|
2
|
+
import type { ExecFn } from "../utils/child-process.js";
|
|
2
3
|
export interface SettingsPaths {
|
|
3
4
|
dir: string;
|
|
4
5
|
file: string;
|
|
@@ -12,6 +13,16 @@ export interface PatchResult {
|
|
|
12
13
|
patched: boolean;
|
|
13
14
|
port?: number;
|
|
14
15
|
}
|
|
16
|
+
export interface SettingsPatcher {
|
|
17
|
+
detect(options: DetectOptions): Promise<PatchResult>;
|
|
18
|
+
patch(options: {
|
|
19
|
+
port: number;
|
|
20
|
+
logger: Logger;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
restore(options: {
|
|
23
|
+
logger: Logger;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
}
|
|
15
26
|
interface BaseOptions {
|
|
16
27
|
logger: Logger;
|
|
17
28
|
paths?: SettingsPaths;
|
|
@@ -22,4 +33,14 @@ export interface PatchOptions extends BaseOptions {
|
|
|
22
33
|
}
|
|
23
34
|
export type RestoreOptions = BaseOptions;
|
|
24
35
|
export type DetectOptions = BaseOptions;
|
|
36
|
+
interface CodexBaseOptions {
|
|
37
|
+
logger: Logger;
|
|
38
|
+
exec?: ExecFn;
|
|
39
|
+
backupFile?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface CodexPatchOptions extends CodexBaseOptions {
|
|
42
|
+
port: number;
|
|
43
|
+
}
|
|
44
|
+
export type CodexRestoreOptions = CodexBaseOptions;
|
|
45
|
+
export type CodexDetectOptions = CodexBaseOptions;
|
|
25
46
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function extractLocalhostPort(url: string): number | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-utils.js","sourceRoot":"","sources":["../../src/settings-patcher/url-utils.ts"],"names":[],"mappings":"AAAA,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CopilotService, Logger, Stats } from "copilot-sdk-proxy";
|
|
2
|
+
import type { createServer } from "copilot-sdk-proxy";
|
|
3
|
+
import type { ProxyMode } from "./providers/names.js";
|
|
4
|
+
interface ShutdownContext {
|
|
5
|
+
app: Awaited<ReturnType<typeof createServer>>;
|
|
6
|
+
service: CopilotService;
|
|
7
|
+
logger: Logger;
|
|
8
|
+
stats: Stats;
|
|
9
|
+
shouldPatch: boolean;
|
|
10
|
+
proxyMode: ProxyMode;
|
|
11
|
+
quiet: boolean;
|
|
12
|
+
lastActivityRef: () => number;
|
|
13
|
+
idleTimeoutMinutes: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function registerShutdownHandlers(ctx: ShutdownContext): void;
|
|
16
|
+
export {};
|
package/dist/shutdown.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { printUsageSummary } from "copilot-sdk-proxy";
|
|
2
|
+
import { restoreSettings } from "./settings-patcher/index.js";
|
|
3
|
+
const STOP_TIMEOUT_MS = 3000;
|
|
4
|
+
export function registerShutdownHandlers(ctx) {
|
|
5
|
+
const { app, service, logger, stats, shouldPatch, proxyMode, quiet, idleTimeoutMinutes } = ctx;
|
|
6
|
+
const shutdown = async (signal) => {
|
|
7
|
+
process.on("uncaughtException", (err) => {
|
|
8
|
+
logger.debug(`Ignoring error during shutdown: ${err.message}`);
|
|
9
|
+
});
|
|
10
|
+
logger.info(`Got ${signal}, shutting down...`);
|
|
11
|
+
if (shouldPatch) {
|
|
12
|
+
await restoreSettings(proxyMode, logger);
|
|
13
|
+
}
|
|
14
|
+
await app.close();
|
|
15
|
+
const stopPromise = service.stop().then(() => {
|
|
16
|
+
logger.info("Clean shutdown complete");
|
|
17
|
+
});
|
|
18
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => {
|
|
19
|
+
logger.warn("Copilot client didn't stop in time, forcing exit");
|
|
20
|
+
resolve();
|
|
21
|
+
}, STOP_TIMEOUT_MS));
|
|
22
|
+
await Promise.race([stopPromise, timeoutPromise]);
|
|
23
|
+
if (!quiet) {
|
|
24
|
+
printUsageSummary(stats.snapshot());
|
|
25
|
+
}
|
|
26
|
+
process.exit(0);
|
|
27
|
+
};
|
|
28
|
+
let shuttingDown = false;
|
|
29
|
+
const onSignal = (signal) => {
|
|
30
|
+
if (shuttingDown)
|
|
31
|
+
return;
|
|
32
|
+
shuttingDown = true;
|
|
33
|
+
shutdown(signal).catch((err) => {
|
|
34
|
+
logger.error(`Shutdown error: ${String(err)}`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
process.on("SIGINT", () => { onSignal("SIGINT"); });
|
|
39
|
+
process.on("SIGTERM", () => { onSignal("SIGTERM"); });
|
|
40
|
+
if (idleTimeoutMinutes > 0) {
|
|
41
|
+
const idleMs = idleTimeoutMinutes * 60_000;
|
|
42
|
+
const checkInterval = Math.min(idleMs, 60_000);
|
|
43
|
+
const timer = setInterval(() => {
|
|
44
|
+
if (Date.now() - ctx.lastActivityRef() >= idleMs) {
|
|
45
|
+
clearInterval(timer);
|
|
46
|
+
logger.info(`Idle for ${String(idleTimeoutMinutes)} minute(s), shutting down`);
|
|
47
|
+
onSignal("idle-timeout");
|
|
48
|
+
}
|
|
49
|
+
}, checkInterval);
|
|
50
|
+
timer.unref();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"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"}
|