xcode-copilot-server 2.0.1 → 2.2.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/README.md +32 -9
- package/dist/cli-validators.d.ts +6 -0
- package/dist/cli-validators.js +35 -0
- package/dist/cli-validators.js.map +1 -0
- package/dist/config.d.ts +2 -2
- package/dist/config.js +10 -9
- package/dist/config.js.map +1 -1
- package/dist/index.js +107 -76
- package/dist/index.js.map +1 -1
- package/dist/logger.js +15 -4
- package/dist/logger.js.map +1 -1
- package/dist/settings-patcher.d.ts +29 -0
- package/dist/settings-patcher.js +79 -0
- package/dist/settings-patcher.js.map +1 -0
- package/dist/ui.d.ts +29 -0
- package/dist/ui.js +63 -0
- package/dist/ui.js.map +1 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -39,12 +39,18 @@ npx xcode-copilot-server
|
|
|
39
39
|
xcode-copilot-server [options]
|
|
40
40
|
|
|
41
41
|
Options:
|
|
42
|
-
--port <number> Port to listen on (default: 8080)
|
|
43
|
-
--proxy <provider>
|
|
44
|
-
--log-level <level> Log verbosity
|
|
45
|
-
--config <path> Path to config file
|
|
46
|
-
--cwd <path>
|
|
47
|
-
--
|
|
42
|
+
-p, --port <number> Port to listen on (default: 8080)
|
|
43
|
+
--proxy <provider> API format: openai, anthropic (default: openai)
|
|
44
|
+
-l, --log-level <level> Log verbosity (default: info)
|
|
45
|
+
-c, --config <path> Path to config file
|
|
46
|
+
--cwd <path> Working directory for Copilot sessions
|
|
47
|
+
--auto-patch Auto-patch settings.json on start, restore on exit
|
|
48
|
+
-v, --version Output the version number
|
|
49
|
+
-h, --help Show help
|
|
50
|
+
|
|
51
|
+
Commands:
|
|
52
|
+
patch-settings Patch Claude Agent's settings.json and exit (Anthropic mode)
|
|
53
|
+
restore-settings Restore Claude Agent's settings.json from backup and exit
|
|
48
54
|
```
|
|
49
55
|
|
|
50
56
|
The `--proxy` flag determines which API the server exposes:
|
|
@@ -70,7 +76,15 @@ To enable tool calling, select the provider and enable "Allow tools" under "Adva
|
|
|
70
76
|
|
|
71
77
|
1. Open Xcode and go to Settings > Intelligence > Anthropic > Claude Agent
|
|
72
78
|
2. Enable Claude Agent and sign in with an API key (the key can be any random text, since the calls are proxied through the server)
|
|
73
|
-
3.
|
|
79
|
+
3. Start the server with `--auto-patch` to automatically configure `settings.json`:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
xcode-copilot-server --proxy anthropic --auto-patch
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This creates (or updates) `settings.json` at `~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/` to point to the server, and restores the original file when the server shuts down. If `settings.json` already exists, a backup is saved as `settings.json.backup` and restored on exit.
|
|
86
|
+
|
|
87
|
+
Alternatively, you can manage `settings.json` yourself. Create it manually at the path above:
|
|
74
88
|
|
|
75
89
|
```json
|
|
76
90
|
{
|
|
@@ -81,9 +95,18 @@ To enable tool calling, select the provider and enable "Allow tools" under "Adva
|
|
|
81
95
|
}
|
|
82
96
|
```
|
|
83
97
|
|
|
84
|
-
Set the port to match your `--port` flag (default 8080). The auth token can be any non-empty string.
|
|
98
|
+
Set the port to match your `--port` flag (default 8080). The auth token can be any non-empty string. Then start the server without `--auto-patch`:
|
|
85
99
|
|
|
86
|
-
|
|
100
|
+
```bash
|
|
101
|
+
xcode-copilot-server --proxy anthropic
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
You can also use the `patch-settings` and `restore-settings` subcommands to patch or restore `settings.json` without starting the server:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
xcode-copilot-server patch-settings --port 8080
|
|
108
|
+
xcode-copilot-server restore-settings
|
|
109
|
+
```
|
|
87
110
|
|
|
88
111
|
The tool bridge is enabled by default in Anthropic mode (`toolBridge: true` in the config). It intercepts tool calls from the Copilot session and forwards them to Xcode, so Claude Agent can read files, search code, and make edits through the IDE.
|
|
89
112
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type LogLevel } from "./logger.js";
|
|
2
|
+
import { type ProxyName } from "./providers/index.js";
|
|
3
|
+
export declare function parsePort(value: string): number;
|
|
4
|
+
export declare function parseLogLevel(value: string): LogLevel;
|
|
5
|
+
export declare function parseProxy(value: string): ProxyName;
|
|
6
|
+
export declare function validateAutoPatch(proxy: ProxyName, autoPatch: boolean): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { LEVEL_PRIORITY } from "./logger.js";
|
|
2
|
+
import { providers } from "./providers/index.js";
|
|
3
|
+
const VALID_LOG_LEVELS = Object.keys(LEVEL_PRIORITY);
|
|
4
|
+
const VALID_PROXIES = Object.keys(providers);
|
|
5
|
+
function isLogLevel(value) {
|
|
6
|
+
return value in LEVEL_PRIORITY;
|
|
7
|
+
}
|
|
8
|
+
function isProxyName(value) {
|
|
9
|
+
return value in providers;
|
|
10
|
+
}
|
|
11
|
+
export function parsePort(value) {
|
|
12
|
+
const port = parseInt(value, 10);
|
|
13
|
+
if (isNaN(port) || port < 1 || port > 65535) {
|
|
14
|
+
throw new Error(`Invalid port "${value}". Must be 1-65535.`);
|
|
15
|
+
}
|
|
16
|
+
return port;
|
|
17
|
+
}
|
|
18
|
+
export function parseLogLevel(value) {
|
|
19
|
+
if (!isLogLevel(value)) {
|
|
20
|
+
throw new Error(`Invalid log level "${value}". Valid: ${VALID_LOG_LEVELS.join(", ")}`);
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
export function parseProxy(value) {
|
|
25
|
+
if (!isProxyName(value)) {
|
|
26
|
+
throw new Error(`Invalid proxy "${value}". Valid: ${VALID_PROXIES.join(", ")}`);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
export function validateAutoPatch(proxy, autoPatch) {
|
|
31
|
+
if (autoPatch && proxy !== "anthropic") {
|
|
32
|
+
throw new Error("--auto-patch can only be used with --proxy anthropic");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=cli-validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-validators.js","sourceRoot":"","sources":["../src/cli-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAkB,MAAM,sBAAsB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAe,CAAC;AACnE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;AAE5D,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,IAAI,cAAc,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,aAAa,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,aAAa,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,SAAkB;IACpE,IAAI,SAAS,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Logger } from "./logger.js";
|
|
2
|
+
import type { ProxyName } from "./providers/index.js";
|
|
2
3
|
import { type MCPServer, type RawServerConfig } from "./schemas/config.js";
|
|
3
4
|
export type { MCPLocalServer, MCPRemoteServer, MCPServer, ApprovalRule, ReasoningEffort, } from "./schemas/config.js";
|
|
5
|
+
export type { ProxyName };
|
|
4
6
|
export type ServerConfig = Omit<RawServerConfig, "bodyLimitMiB" | "openai" | "anthropic"> & {
|
|
5
7
|
toolBridge: boolean;
|
|
6
8
|
mcpServers: Record<string, MCPServer>;
|
|
7
9
|
bodyLimit: number;
|
|
8
10
|
};
|
|
9
|
-
import type { ProxyName } from "./providers/index.js";
|
|
10
|
-
export type { ProxyName };
|
|
11
11
|
export declare function resolveConfigPath(projectCwd: string | undefined, processCwd: string, defaultPath: string): string;
|
|
12
12
|
export declare function loadConfig(configPath: string, logger: Logger, proxy: ProxyName): Promise<ServerConfig>;
|
package/dist/config.js
CHANGED
|
@@ -39,12 +39,17 @@ export async function loadConfig(configPath, logger, proxy) {
|
|
|
39
39
|
const absolutePath = isAbsolute(configPath)
|
|
40
40
|
? configPath
|
|
41
41
|
: resolve(process.cwd(), configPath);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
let text;
|
|
43
|
+
try {
|
|
44
|
+
text = await readFile(absolutePath, "utf-8");
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
48
|
+
logger.warn(`No config file at ${absolutePath}, using defaults`);
|
|
49
|
+
return DEFAULT_CONFIG;
|
|
50
|
+
}
|
|
51
|
+
throw err;
|
|
45
52
|
}
|
|
46
|
-
logger.info(`Reading config from ${absolutePath}`);
|
|
47
|
-
const text = await readFile(absolutePath, "utf-8");
|
|
48
53
|
let raw;
|
|
49
54
|
try {
|
|
50
55
|
raw = JSON5.parse(text);
|
|
@@ -76,10 +81,6 @@ export async function loadConfig(configPath, logger, proxy) {
|
|
|
76
81
|
toolBridge: provider.toolBridge,
|
|
77
82
|
mcpServers: resolveServerPaths(provider.mcpServers, configDir),
|
|
78
83
|
};
|
|
79
|
-
const cliToolsSummary = config.allowedCliTools.includes("*")
|
|
80
|
-
? "all CLI tools allowed"
|
|
81
|
-
: `${String(config.allowedCliTools.length)} allowed CLI tool(s)`;
|
|
82
|
-
logger.info(`Loaded ${String(Object.keys(config.mcpServers).length)} MCP server(s), ${cliToolsSummary}`);
|
|
83
84
|
return config;
|
|
84
85
|
}
|
|
85
86
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,102 +1,91 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { join, dirname } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { Command } from "commander";
|
|
4
6
|
import { CopilotService } from "./copilot-service.js";
|
|
5
7
|
import { loadConfig, resolveConfigPath } from "./config.js";
|
|
6
8
|
import { createServer } from "./server.js";
|
|
7
|
-
import { Logger
|
|
9
|
+
import { Logger } from "./logger.js";
|
|
8
10
|
import { providers } from "./providers/index.js";
|
|
11
|
+
import { patchSettings, restoreSettings } from "./settings-patcher.js";
|
|
12
|
+
import { parsePort, parseLogLevel, parseProxy, validateAutoPatch, } from "./cli-validators.js";
|
|
13
|
+
import { bold, dim, createSpinner, printBanner } from "./ui.js";
|
|
9
14
|
const PACKAGE_ROOT = dirname(import.meta.dirname);
|
|
10
15
|
const DEFAULT_CONFIG_PATH = join(PACKAGE_ROOT, "config.json5");
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
function isLogLevel(value) {
|
|
14
|
-
return value in LEVEL_PRIORITY;
|
|
15
|
-
}
|
|
16
|
-
function isProxy(value) {
|
|
17
|
-
return value in providers;
|
|
18
|
-
}
|
|
19
|
-
const USAGE = `Usage: xcode-copilot-server [options]
|
|
20
|
-
|
|
21
|
-
Options:
|
|
22
|
-
--port <number> Port to listen on (default: 8080)
|
|
23
|
-
--proxy <provider> API format to expose: ${VALID_PROXIES.join(", ")} (default: openai)
|
|
24
|
-
--log-level <level> Log verbosity: ${VALID_LOG_LEVELS.join(", ")} (default: info)
|
|
25
|
-
--config <path> Path to config file (auto-detected from --cwd, then process cwd, else bundled)
|
|
26
|
-
--cwd <path> Working directory for Copilot sessions (default: process cwd)
|
|
27
|
-
--help Show this help message`;
|
|
28
|
-
function parseCliArgs() {
|
|
29
|
-
try {
|
|
30
|
-
return parseArgs({
|
|
31
|
-
options: {
|
|
32
|
-
port: { type: "string", default: "8080" },
|
|
33
|
-
proxy: { type: "string", default: "openai" },
|
|
34
|
-
"log-level": { type: "string", default: "info" },
|
|
35
|
-
config: { type: "string" },
|
|
36
|
-
cwd: { type: "string" },
|
|
37
|
-
help: { type: "boolean", default: false },
|
|
38
|
-
},
|
|
39
|
-
strict: true,
|
|
40
|
-
allowPositionals: false,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
console.error(String(err instanceof Error ? err.message : err));
|
|
45
|
-
console.error(`Run with --help for usage information.`);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
async function main() {
|
|
50
|
-
const { values } = parseCliArgs();
|
|
51
|
-
if (values.help) {
|
|
52
|
-
console.log(USAGE);
|
|
53
|
-
process.exit(0);
|
|
54
|
-
}
|
|
55
|
-
const port = parseInt(values.port, 10);
|
|
56
|
-
if (isNaN(port) || port < 1 || port > 65535) {
|
|
57
|
-
console.error(`Invalid port "${values.port}". Must be 1-65535.`);
|
|
58
|
-
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
const proxy = values.proxy;
|
|
61
|
-
if (!isProxy(proxy)) {
|
|
62
|
-
console.error(`Invalid proxy "${proxy}". Valid: ${VALID_PROXIES.join(", ")}`);
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
const provider = providers[proxy];
|
|
66
|
-
const rawLevel = values["log-level"];
|
|
67
|
-
if (!isLogLevel(rawLevel)) {
|
|
68
|
-
console.error(`Invalid log level "${rawLevel}". Valid: ${VALID_LOG_LEVELS.join(", ")}`);
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
71
|
-
const logLevel = rawLevel;
|
|
16
|
+
async function startServer(options) {
|
|
17
|
+
const logLevel = parseLogLevel(options.logLevel);
|
|
72
18
|
const logger = new Logger(logLevel);
|
|
73
|
-
const
|
|
19
|
+
const port = parsePort(options.port);
|
|
20
|
+
const proxy = parseProxy(options.proxy);
|
|
21
|
+
const autoPatch = options.autoPatch === true;
|
|
22
|
+
validateAutoPatch(proxy, autoPatch);
|
|
23
|
+
const provider = providers[proxy];
|
|
24
|
+
const configPath = options.config ?? resolveConfigPath(options.cwd, process.cwd(), DEFAULT_CONFIG_PATH);
|
|
74
25
|
const config = await loadConfig(configPath, logger, proxy);
|
|
75
|
-
const cwd =
|
|
26
|
+
const cwd = options.cwd;
|
|
76
27
|
const service = new CopilotService({
|
|
77
28
|
logLevel,
|
|
78
29
|
logger,
|
|
79
30
|
cwd,
|
|
80
31
|
});
|
|
81
|
-
|
|
32
|
+
const quiet = logLevel === "none";
|
|
33
|
+
if (!quiet) {
|
|
34
|
+
console.log();
|
|
35
|
+
console.log(` ${bold("xcode-copilot-server")} ${dim(`v${version}`)}`);
|
|
36
|
+
console.log();
|
|
37
|
+
}
|
|
38
|
+
const bootSpinner = quiet ? null : createSpinner("Starting Copilot SDK...");
|
|
82
39
|
await service.start();
|
|
83
|
-
|
|
40
|
+
bootSpinner?.succeed("Copilot SDK started");
|
|
41
|
+
const authSpinner = quiet ? null : createSpinner("Authenticating...");
|
|
84
42
|
const auth = await service.getAuthStatus();
|
|
85
43
|
if (!auth.isAuthenticated) {
|
|
86
|
-
|
|
44
|
+
authSpinner?.fail("Not authenticated");
|
|
45
|
+
logger.error("Sign in with the Copilot CLI (copilot login) or GitHub CLI (gh auth login), or set a GITHUB_TOKEN environment variable.");
|
|
87
46
|
await service.stop();
|
|
88
47
|
process.exit(1);
|
|
89
48
|
}
|
|
90
|
-
|
|
49
|
+
const login = auth.login ?? "unknown";
|
|
50
|
+
const authType = auth.authType ?? "unknown";
|
|
51
|
+
authSpinner?.succeed(`Authenticated as ${bold(login)} ${dim(`(${authType})`)}`);
|
|
52
|
+
if (autoPatch) {
|
|
53
|
+
await patchSettings({ port, logger });
|
|
54
|
+
}
|
|
91
55
|
const ctx = { service, logger, config, port };
|
|
92
56
|
const app = await createServer(ctx, provider);
|
|
57
|
+
const listenSpinner = quiet ? null : createSpinner(`Starting server on port ${String(port)}...`);
|
|
58
|
+
const prevPinoLevel = app.log.level;
|
|
59
|
+
app.log.level = "silent";
|
|
93
60
|
await app.listen({ port, host: "127.0.0.1" });
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
61
|
+
app.log.level = prevPinoLevel;
|
|
62
|
+
listenSpinner?.succeed(`Listening on ${bold(`http://localhost:${String(port)}`)}`);
|
|
63
|
+
if (!quiet) {
|
|
64
|
+
printBanner({
|
|
65
|
+
port,
|
|
66
|
+
proxy,
|
|
67
|
+
providerName: provider.name,
|
|
68
|
+
routes: provider.routes,
|
|
69
|
+
cwd: service.cwd,
|
|
70
|
+
autoPatch,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
logger.debug(`Config loaded from ${configPath}`);
|
|
74
|
+
const mcpCount = Object.keys(config.mcpServers).length;
|
|
75
|
+
const cliToolsSummary = config.allowedCliTools.includes("*")
|
|
76
|
+
? "all CLI tools allowed"
|
|
77
|
+
: `${String(config.allowedCliTools.length)} allowed CLI tool(s)`;
|
|
78
|
+
logger.debug(`${String(mcpCount)} MCP server(s), ${cliToolsSummary}`);
|
|
98
79
|
const shutdown = async (signal) => {
|
|
99
80
|
logger.info(`Got ${signal}, shutting down...`);
|
|
81
|
+
if (autoPatch) {
|
|
82
|
+
try {
|
|
83
|
+
await restoreSettings({ logger });
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
logger.error(`Failed to restore settings.json: ${String(err)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
100
89
|
await app.close();
|
|
101
90
|
const stopPromise = service.stop().then(() => {
|
|
102
91
|
logger.info("Clean shutdown complete");
|
|
@@ -108,10 +97,52 @@ async function main() {
|
|
|
108
97
|
await Promise.race([stopPromise, timeoutPromise]);
|
|
109
98
|
process.exit(0);
|
|
110
99
|
};
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
const onSignal = (signal) => {
|
|
101
|
+
shutdown(signal).catch((err) => {
|
|
102
|
+
console.error("Shutdown error:", err);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
process.on("SIGINT", () => { onSignal("SIGINT"); });
|
|
107
|
+
process.on("SIGTERM", () => { onSignal("SIGTERM"); });
|
|
108
|
+
}
|
|
109
|
+
async function patchSettingsCommand(options) {
|
|
110
|
+
const logLevel = parseLogLevel(options.logLevel);
|
|
111
|
+
const logger = new Logger(logLevel);
|
|
112
|
+
const port = parsePort(options.port);
|
|
113
|
+
await patchSettings({ port, logger });
|
|
114
|
+
}
|
|
115
|
+
async function restoreSettingsCommand(options) {
|
|
116
|
+
const logLevel = parseLogLevel(options.logLevel);
|
|
117
|
+
const logger = new Logger(logLevel);
|
|
118
|
+
await restoreSettings({ logger });
|
|
113
119
|
}
|
|
114
|
-
|
|
120
|
+
// Can't use JSON import because rootDir is src/ and package.json is at the project root.
|
|
121
|
+
const { version } = z.object({ version: z.string() }).parse(JSON.parse(await readFile(join(PACKAGE_ROOT, "package.json"), "utf-8")));
|
|
122
|
+
const program = new Command()
|
|
123
|
+
.name("xcode-copilot-server")
|
|
124
|
+
.description("Proxy API server for Xcode, powered by GitHub Copilot")
|
|
125
|
+
.version(version, "-v, --version");
|
|
126
|
+
program
|
|
127
|
+
.option("-p, --port <number>", "port to listen on", "8080")
|
|
128
|
+
.option("--proxy <provider>", "API format: openai, anthropic", "openai")
|
|
129
|
+
.option("-l, --log-level <level>", "log verbosity", "info")
|
|
130
|
+
.option("-c, --config <path>", "path to config file")
|
|
131
|
+
.option("--cwd <path>", "working directory for Copilot sessions")
|
|
132
|
+
.option("--auto-patch", "auto-patch settings.json on start, restore on exit")
|
|
133
|
+
.action((options) => startServer(options));
|
|
134
|
+
program
|
|
135
|
+
.command("patch-settings")
|
|
136
|
+
.description("Patch settings.json to point to this server, then exit")
|
|
137
|
+
.option("-p, --port <number>", "port to write into settings.json", "8080")
|
|
138
|
+
.option("-l, --log-level <level>", "log verbosity", "info")
|
|
139
|
+
.action((options) => patchSettingsCommand(options));
|
|
140
|
+
program
|
|
141
|
+
.command("restore-settings")
|
|
142
|
+
.description("Restore settings.json from backup, then exit")
|
|
143
|
+
.option("-l, --log-level <level>", "log verbosity", "info")
|
|
144
|
+
.action((options) => restoreSettingsCommand(options));
|
|
145
|
+
program.parseAsync().catch((err) => {
|
|
115
146
|
console.error("Fatal error:", err);
|
|
116
147
|
process.exit(1);
|
|
117
148
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bold, dim, red, yellow, cyan, symbols } from "./ui.js";
|
|
1
2
|
export const LEVEL_PRIORITY = {
|
|
2
3
|
none: 0,
|
|
3
4
|
error: 1,
|
|
@@ -6,6 +7,12 @@ export const LEVEL_PRIORITY = {
|
|
|
6
7
|
debug: 4,
|
|
7
8
|
all: 5,
|
|
8
9
|
};
|
|
10
|
+
const LEVEL_STYLE = {
|
|
11
|
+
error: { label: red(bold("ERROR")), symbol: symbols.error },
|
|
12
|
+
warn: { label: yellow(bold("WARN")), symbol: symbols.warn },
|
|
13
|
+
info: { label: cyan("INFO"), symbol: symbols.info },
|
|
14
|
+
debug: { label: dim("DEBUG"), symbol: symbols.debug },
|
|
15
|
+
};
|
|
9
16
|
export class Logger {
|
|
10
17
|
level;
|
|
11
18
|
threshold;
|
|
@@ -15,22 +22,26 @@ export class Logger {
|
|
|
15
22
|
}
|
|
16
23
|
error(msg, ...args) {
|
|
17
24
|
if (this.threshold >= LEVEL_PRIORITY.error) {
|
|
18
|
-
|
|
25
|
+
const { label, symbol } = LEVEL_STYLE.error;
|
|
26
|
+
console.error(`${dim(new Date().toISOString())} ${symbol} ${label} ${msg}`, ...args);
|
|
19
27
|
}
|
|
20
28
|
}
|
|
21
29
|
warn(msg, ...args) {
|
|
22
30
|
if (this.threshold >= LEVEL_PRIORITY.warning) {
|
|
23
|
-
|
|
31
|
+
const { label, symbol } = LEVEL_STYLE.warn;
|
|
32
|
+
console.warn(`${dim(new Date().toISOString())} ${symbol} ${label} ${msg}`, ...args);
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
35
|
info(msg, ...args) {
|
|
27
36
|
if (this.threshold >= LEVEL_PRIORITY.info) {
|
|
28
|
-
|
|
37
|
+
const { label, symbol } = LEVEL_STYLE.info;
|
|
38
|
+
console.log(`${dim(new Date().toISOString())} ${symbol} ${label} ${msg}`, ...args);
|
|
29
39
|
}
|
|
30
40
|
}
|
|
31
41
|
debug(msg, ...args) {
|
|
32
42
|
if (this.threshold >= LEVEL_PRIORITY.debug) {
|
|
33
|
-
|
|
43
|
+
const { label, symbol } = LEVEL_STYLE.debug;
|
|
44
|
+
console.log(`${dim(new Date().toISOString())} ${symbol} ${label} ${dim(msg)}`, ...args);
|
|
34
45
|
}
|
|
35
46
|
}
|
|
36
47
|
}
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,GAAG,EAAE,CAAC;CACmC,CAAC;AAI5C,MAAM,OAAO,MAAM;IACR,KAAK,CAAW;IACjB,SAAS,CAAS;IAE1B,YAAY,QAAkB,MAAM;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,IAAI,CAAC,SAAS,IAAI,cAAc,CAAC,KAAK,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger } from "./logger.js";
|
|
2
|
+
export interface SettingsPaths {
|
|
3
|
+
dir: string;
|
|
4
|
+
file: string;
|
|
5
|
+
backup: string;
|
|
6
|
+
}
|
|
7
|
+
export interface Settings {
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface PatchResult {
|
|
12
|
+
patched: boolean;
|
|
13
|
+
port?: number;
|
|
14
|
+
}
|
|
15
|
+
interface BaseOptions {
|
|
16
|
+
logger: Logger;
|
|
17
|
+
paths?: SettingsPaths;
|
|
18
|
+
}
|
|
19
|
+
export interface PatchOptions extends BaseOptions {
|
|
20
|
+
port: number;
|
|
21
|
+
authToken?: string;
|
|
22
|
+
}
|
|
23
|
+
export type RestoreOptions = BaseOptions;
|
|
24
|
+
export type DetectOptions = BaseOptions;
|
|
25
|
+
export declare function defaultSettingsPaths(): SettingsPaths;
|
|
26
|
+
export declare function detectPatchState(options: DetectOptions): Promise<PatchResult>;
|
|
27
|
+
export declare function patchSettings(options: PatchOptions): Promise<void>;
|
|
28
|
+
export declare function restoreSettings(options: RestoreOptions): Promise<void>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile, rename, unlink, mkdir, copyFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
export function defaultSettingsPaths() {
|
|
6
|
+
const dir = join(homedir(), "Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig");
|
|
7
|
+
return {
|
|
8
|
+
dir,
|
|
9
|
+
file: join(dir, "settings.json"),
|
|
10
|
+
backup: join(dir, "settings.json.backup"),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function isSettings(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
async function readSettingsFile(path) {
|
|
17
|
+
if (!existsSync(path))
|
|
18
|
+
return null;
|
|
19
|
+
const content = await readFile(path, "utf-8");
|
|
20
|
+
const parsed = JSON.parse(content);
|
|
21
|
+
return isSettings(parsed) ? parsed : null;
|
|
22
|
+
}
|
|
23
|
+
export async function detectPatchState(options) {
|
|
24
|
+
const { logger } = options;
|
|
25
|
+
const p = options.paths ?? defaultSettingsPaths();
|
|
26
|
+
if (!existsSync(p.backup)) {
|
|
27
|
+
return { patched: false };
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const settings = await readSettingsFile(p.file);
|
|
31
|
+
const url = settings?.env?.ANTHROPIC_BASE_URL;
|
|
32
|
+
if (url) {
|
|
33
|
+
const match = /localhost:(\d+)/.exec(url);
|
|
34
|
+
if (match?.[1]) {
|
|
35
|
+
return { patched: true, port: parseInt(match[1], 10) };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
logger.warn(`Could not read settings.json to extract port: ${String(err)}`);
|
|
41
|
+
}
|
|
42
|
+
return { patched: true };
|
|
43
|
+
}
|
|
44
|
+
export async function patchSettings(options) {
|
|
45
|
+
const { logger } = options;
|
|
46
|
+
const p = options.paths ?? defaultSettingsPaths();
|
|
47
|
+
await mkdir(p.dir, { recursive: true });
|
|
48
|
+
// Only back up once so crash recovery doesn't overwrite the original.
|
|
49
|
+
if (existsSync(p.file) && !existsSync(p.backup)) {
|
|
50
|
+
await copyFile(p.file, p.backup);
|
|
51
|
+
logger.info("Backed up settings.json");
|
|
52
|
+
}
|
|
53
|
+
let settings = {};
|
|
54
|
+
try {
|
|
55
|
+
settings = await readSettingsFile(p.file) ?? {};
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
logger.warn(`Could not read settings.json, starting fresh: ${String(err)}`);
|
|
59
|
+
}
|
|
60
|
+
settings.env = {
|
|
61
|
+
...settings.env,
|
|
62
|
+
ANTHROPIC_BASE_URL: `http://localhost:${String(options.port)}`,
|
|
63
|
+
ANTHROPIC_AUTH_TOKEN: options.authToken ?? "12345",
|
|
64
|
+
};
|
|
65
|
+
await writeFile(p.file, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
66
|
+
logger.info(`Patched settings.json to point to http://localhost:${String(options.port)}`);
|
|
67
|
+
}
|
|
68
|
+
export async function restoreSettings(options) {
|
|
69
|
+
const { logger } = options;
|
|
70
|
+
const p = options.paths ?? defaultSettingsPaths();
|
|
71
|
+
if (existsSync(p.file)) {
|
|
72
|
+
await unlink(p.file);
|
|
73
|
+
}
|
|
74
|
+
if (existsSync(p.backup)) {
|
|
75
|
+
await rename(p.backup, p.file);
|
|
76
|
+
logger.info("Restored settings.json from backup");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=settings-patcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-patcher.js","sourceRoot":"","sources":["../src/settings-patcher.ts"],"names":[],"mappings":"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"}
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const bold: import("picocolors/types.js").Formatter;
|
|
2
|
+
export declare const dim: import("picocolors/types.js").Formatter;
|
|
3
|
+
export declare const red: import("picocolors/types.js").Formatter;
|
|
4
|
+
export declare const green: import("picocolors/types.js").Formatter;
|
|
5
|
+
export declare const cyan: import("picocolors/types.js").Formatter;
|
|
6
|
+
export declare const yellow: import("picocolors/types.js").Formatter;
|
|
7
|
+
export declare const symbols: {
|
|
8
|
+
readonly success: string;
|
|
9
|
+
readonly error: string;
|
|
10
|
+
readonly info: string;
|
|
11
|
+
readonly warn: string;
|
|
12
|
+
readonly debug: string;
|
|
13
|
+
};
|
|
14
|
+
export interface Spinner {
|
|
15
|
+
update(text: string): void;
|
|
16
|
+
succeed(text: string): void;
|
|
17
|
+
fail(text: string): void;
|
|
18
|
+
stop(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function createSpinner(text: string): Spinner;
|
|
21
|
+
export interface BannerInfo {
|
|
22
|
+
port: number;
|
|
23
|
+
proxy: string;
|
|
24
|
+
providerName: string;
|
|
25
|
+
routes: string[];
|
|
26
|
+
cwd: string;
|
|
27
|
+
autoPatch: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function printBanner(info: BannerInfo): void;
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
export const bold = pc.bold;
|
|
4
|
+
export const dim = pc.dim;
|
|
5
|
+
export const red = pc.red;
|
|
6
|
+
export const green = pc.green;
|
|
7
|
+
export const cyan = pc.cyan;
|
|
8
|
+
export const yellow = pc.yellow;
|
|
9
|
+
export const symbols = {
|
|
10
|
+
success: green("✓"),
|
|
11
|
+
error: red("✗"),
|
|
12
|
+
info: cyan("●"),
|
|
13
|
+
warn: yellow("!"),
|
|
14
|
+
debug: dim("·"),
|
|
15
|
+
};
|
|
16
|
+
const FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
17
|
+
const INTERVAL_MS = 80;
|
|
18
|
+
export function createSpinner(text) {
|
|
19
|
+
if (!process.stdout.isTTY) {
|
|
20
|
+
process.stdout.write(` ${dim("...")} ${text}\n`);
|
|
21
|
+
return {
|
|
22
|
+
update() { },
|
|
23
|
+
succeed(t) { process.stdout.write(` ${symbols.success} ${t}\n`); },
|
|
24
|
+
fail(t) { process.stderr.write(` ${symbols.error} ${t}\n`); },
|
|
25
|
+
stop() { },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
let frameIndex = 0;
|
|
29
|
+
let current = text;
|
|
30
|
+
const render = () => {
|
|
31
|
+
readline.clearLine(process.stdout, 0);
|
|
32
|
+
readline.cursorTo(process.stdout, 0);
|
|
33
|
+
const frame = FRAMES[frameIndex] ?? FRAMES[0];
|
|
34
|
+
process.stdout.write(` ${cyan(frame)} ${current}`);
|
|
35
|
+
};
|
|
36
|
+
render();
|
|
37
|
+
const timer = setInterval(() => {
|
|
38
|
+
frameIndex = (frameIndex + 1) % FRAMES.length;
|
|
39
|
+
render();
|
|
40
|
+
}, INTERVAL_MS);
|
|
41
|
+
const clear = () => {
|
|
42
|
+
clearInterval(timer);
|
|
43
|
+
readline.clearLine(process.stdout, 0);
|
|
44
|
+
readline.cursorTo(process.stdout, 0);
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
update(t) { current = t; },
|
|
48
|
+
succeed(t) { clear(); process.stdout.write(` ${symbols.success} ${t}\n`); },
|
|
49
|
+
fail(t) { clear(); process.stderr.write(` ${symbols.error} ${t}\n`); },
|
|
50
|
+
stop() { clear(); },
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function printBanner(info) {
|
|
54
|
+
console.log();
|
|
55
|
+
console.log(` ${dim("Provider")} ${info.providerName} ${dim(`(--proxy ${info.proxy})`)}`);
|
|
56
|
+
console.log(` ${dim("Routes")} ${info.routes.join(dim(", "))}`);
|
|
57
|
+
console.log(` ${dim("Directory")} ${info.cwd}`);
|
|
58
|
+
if (info.autoPatch) {
|
|
59
|
+
console.log(` ${dim("Auto-patch")} ${green("enabled")}`);
|
|
60
|
+
}
|
|
61
|
+
console.log();
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=ui.js.map
|
package/dist/ui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xcode-copilot-server",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "OpenAI-compatible proxy API server for Xcode, powered by GitHub Copilot",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,8 +32,10 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@fastify/cors": "11.2.0",
|
|
34
34
|
"@github/copilot-sdk": "0.1.23",
|
|
35
|
+
"commander": "14.0.3",
|
|
35
36
|
"fastify": "5.7.4",
|
|
36
37
|
"json5": "2.2.3",
|
|
38
|
+
"picocolors": "1.1.1",
|
|
37
39
|
"tokenx": "1.3.0",
|
|
38
40
|
"zod": "4.3.6"
|
|
39
41
|
},
|