xcode-copilot-server 2.1.0 → 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 +18 -10
- 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 +94 -90
- package/dist/index.js.map +1 -1
- package/dist/logger.js +15 -4
- package/dist/logger.js.map +1 -1
- 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,15 +39,18 @@ npx xcode-copilot-server
|
|
|
39
39
|
xcode-copilot-server [options]
|
|
40
40
|
|
|
41
41
|
Options:
|
|
42
|
-
--port <number>
|
|
43
|
-
--proxy <provider>
|
|
44
|
-
--log-level <level>
|
|
45
|
-
--config <path>
|
|
46
|
-
--cwd <path>
|
|
47
|
-
--auto-patch
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
51
54
|
```
|
|
52
55
|
|
|
53
56
|
The `--proxy` flag determines which API the server exposes:
|
|
@@ -98,7 +101,12 @@ To enable tool calling, select the provider and enable "Allow tools" under "Adva
|
|
|
98
101
|
xcode-copilot-server --proxy anthropic
|
|
99
102
|
```
|
|
100
103
|
|
|
101
|
-
You can also use
|
|
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
|
+
```
|
|
102
110
|
|
|
103
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.
|
|
104
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,119 +1,81 @@
|
|
|
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";
|
|
9
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";
|
|
10
14
|
const PACKAGE_ROOT = dirname(import.meta.dirname);
|
|
11
15
|
const DEFAULT_CONFIG_PATH = join(PACKAGE_ROOT, "config.json5");
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
function isLogLevel(value) {
|
|
15
|
-
return value in LEVEL_PRIORITY;
|
|
16
|
-
}
|
|
17
|
-
function isProxy(value) {
|
|
18
|
-
return value in providers;
|
|
19
|
-
}
|
|
20
|
-
const USAGE = `Usage: xcode-copilot-server [options]
|
|
21
|
-
|
|
22
|
-
Options:
|
|
23
|
-
--port <number> Port to listen on (default: 8080)
|
|
24
|
-
--proxy <provider> API format to expose: ${VALID_PROXIES.join(", ")} (default: openai)
|
|
25
|
-
--log-level <level> Log verbosity: ${VALID_LOG_LEVELS.join(", ")} (default: info)
|
|
26
|
-
--config <path> Path to config file (auto-detected from --cwd, then process cwd, else bundled)
|
|
27
|
-
--cwd <path> Working directory for Copilot sessions (default: process cwd)
|
|
28
|
-
--auto-patch Auto-patch settings.json on start, restore on exit (anthropic mode)
|
|
29
|
-
--patch-settings Patch settings.json to point to this server, then exit
|
|
30
|
-
--restore-settings Restore settings.json from backup, then exit
|
|
31
|
-
--help Show this help message`;
|
|
32
|
-
function parseCliArgs() {
|
|
33
|
-
try {
|
|
34
|
-
return parseArgs({
|
|
35
|
-
options: {
|
|
36
|
-
port: { type: "string", default: "8080" },
|
|
37
|
-
proxy: { type: "string", default: "openai" },
|
|
38
|
-
"log-level": { type: "string", default: "info" },
|
|
39
|
-
config: { type: "string" },
|
|
40
|
-
cwd: { type: "string" },
|
|
41
|
-
"auto-patch": { type: "boolean", default: false },
|
|
42
|
-
"patch-settings": { type: "boolean", default: false },
|
|
43
|
-
"restore-settings": { type: "boolean", default: false },
|
|
44
|
-
help: { type: "boolean", default: false },
|
|
45
|
-
},
|
|
46
|
-
strict: true,
|
|
47
|
-
allowPositionals: false,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
console.error(String(err instanceof Error ? err.message : err));
|
|
52
|
-
console.error(`Run with --help for usage information.`);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async function main() {
|
|
57
|
-
const { values } = parseCliArgs();
|
|
58
|
-
if (values.help) {
|
|
59
|
-
console.log(USAGE);
|
|
60
|
-
process.exit(0);
|
|
61
|
-
}
|
|
62
|
-
const rawLevel = values["log-level"];
|
|
63
|
-
if (!isLogLevel(rawLevel)) {
|
|
64
|
-
console.error(`Invalid log level "${rawLevel}". Valid: ${VALID_LOG_LEVELS.join(", ")}`);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
const logLevel = rawLevel;
|
|
16
|
+
async function startServer(options) {
|
|
17
|
+
const logLevel = parseLogLevel(options.logLevel);
|
|
68
18
|
const logger = new Logger(logLevel);
|
|
69
|
-
const port =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
if (values["patch-settings"]) {
|
|
75
|
-
await patchSettings({ port, logger });
|
|
76
|
-
process.exit(0);
|
|
77
|
-
}
|
|
78
|
-
if (values["restore-settings"]) {
|
|
79
|
-
await restoreSettings({ logger });
|
|
80
|
-
process.exit(0);
|
|
81
|
-
}
|
|
82
|
-
const proxy = values.proxy;
|
|
83
|
-
if (!isProxy(proxy)) {
|
|
84
|
-
console.error(`Invalid proxy "${proxy}". Valid: ${VALID_PROXIES.join(", ")}`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
19
|
+
const port = parsePort(options.port);
|
|
20
|
+
const proxy = parseProxy(options.proxy);
|
|
21
|
+
const autoPatch = options.autoPatch === true;
|
|
22
|
+
validateAutoPatch(proxy, autoPatch);
|
|
87
23
|
const provider = providers[proxy];
|
|
88
|
-
const configPath =
|
|
24
|
+
const configPath = options.config ?? resolveConfigPath(options.cwd, process.cwd(), DEFAULT_CONFIG_PATH);
|
|
89
25
|
const config = await loadConfig(configPath, logger, proxy);
|
|
90
|
-
const cwd =
|
|
26
|
+
const cwd = options.cwd;
|
|
91
27
|
const service = new CopilotService({
|
|
92
28
|
logLevel,
|
|
93
29
|
logger,
|
|
94
30
|
cwd,
|
|
95
31
|
});
|
|
96
|
-
|
|
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...");
|
|
97
39
|
await service.start();
|
|
98
|
-
|
|
40
|
+
bootSpinner?.succeed("Copilot SDK started");
|
|
41
|
+
const authSpinner = quiet ? null : createSpinner("Authenticating...");
|
|
99
42
|
const auth = await service.getAuthStatus();
|
|
100
43
|
if (!auth.isAuthenticated) {
|
|
101
|
-
|
|
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.");
|
|
102
46
|
await service.stop();
|
|
103
47
|
process.exit(1);
|
|
104
48
|
}
|
|
105
|
-
|
|
106
|
-
const
|
|
49
|
+
const login = auth.login ?? "unknown";
|
|
50
|
+
const authType = auth.authType ?? "unknown";
|
|
51
|
+
authSpinner?.succeed(`Authenticated as ${bold(login)} ${dim(`(${authType})`)}`);
|
|
107
52
|
if (autoPatch) {
|
|
108
53
|
await patchSettings({ port, logger });
|
|
109
54
|
}
|
|
110
55
|
const ctx = { service, logger, config, port };
|
|
111
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";
|
|
112
60
|
await app.listen({ port, host: "127.0.0.1" });
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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}`);
|
|
117
79
|
const shutdown = async (signal) => {
|
|
118
80
|
logger.info(`Got ${signal}, shutting down...`);
|
|
119
81
|
if (autoPatch) {
|
|
@@ -135,10 +97,52 @@ async function main() {
|
|
|
135
97
|
await Promise.race([stopPromise, timeoutPromise]);
|
|
136
98
|
process.exit(0);
|
|
137
99
|
};
|
|
138
|
-
|
|
139
|
-
|
|
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 });
|
|
140
119
|
}
|
|
141
|
-
|
|
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) => {
|
|
142
146
|
console.error("Fatal error:", err);
|
|
143
147
|
process.exit(1);
|
|
144
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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"}
|
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.
|
|
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
|
},
|