codex-copilot-dx 0.6.21 → 0.7.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 +123 -326
- package/bin/cli.mjs +13 -129
- package/package.json +2 -8
- package/scripts/benchmark.mjs +0 -114
- package/src/adapter.mjs +19 -106
- package/src/auth-profile.mjs +18 -130
- package/src/cli-auth.mjs +44 -398
- package/src/cli-models.mjs +21 -49
- package/src/cli-options.mjs +45 -75
- package/src/cli-status.mjs +6 -23
- package/src/config.mjs +2 -8
- package/src/copilot.mjs +2 -2
- package/src/doctor.mjs +44 -291
- package/src/model-cache.mjs +4 -11
- package/src/models.mjs +0 -184
- package/src/observability.mjs +1 -38
- package/src/profile-model-runtime.mjs +61 -189
- package/src/profile-routing.mjs +2 -102
- package/src/profile-runtime.mjs +15 -68
- package/src/responses-handler.mjs +1 -1
- package/src/responses-proxy.mjs +1 -1
- package/src/running-adapter.mjs +2 -4
- package/src/stream-errors.mjs +3 -6
- package/src/stream-performance.mjs +1 -1
- package/src/usage.mjs +0 -31
- package/src/anthropic-handler.mjs +0 -195
- package/src/anthropic.mjs +0 -387
- package/src/claude-config.mjs +0 -57
- package/src/claude-desktop-config.mjs +0 -317
- package/src/cli-error.mjs +0 -50
- package/src/pm-studio-asar.mjs +0 -1244
- package/src/pm-studio-bundle-content.mjs +0 -165
- package/src/pm-studio-relay.mjs +0 -563
- package/src/pm-studio-setup-lock.mjs +0 -336
- package/src/pm-studio-setup.mjs +0 -1581
- package/src/pm-studio-status.mjs +0 -369
- package/src/token-counter-service.mjs +0 -211
- package/src/token-counter-worker.mjs +0 -16
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import { sha256Hex } from "./pm-studio-asar.mjs";
|
|
5
|
-
|
|
6
|
-
const BUNDLE_CONTENT_SCHEME = "ccdx-bundle-content-v2";
|
|
7
|
-
|
|
8
|
-
function setupError(code, message, details) {
|
|
9
|
-
const error = new Error(message);
|
|
10
|
-
error.code = code;
|
|
11
|
-
if (details !== undefined) error.details = details;
|
|
12
|
-
return error;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function hashRegularFile(filePath, expected, readBuffer) {
|
|
16
|
-
const hash = createHash("sha256");
|
|
17
|
-
const file = fs.openSync(filePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0));
|
|
18
|
-
const buffer = readBuffer || Buffer.allocUnsafe(1024 * 1024);
|
|
19
|
-
try {
|
|
20
|
-
const before = fs.fstatSync(file, { bigint: true });
|
|
21
|
-
if (before.dev !== BigInt(expected.dev)
|
|
22
|
-
|| before.ino !== BigInt(expected.ino)
|
|
23
|
-
|| before.size !== BigInt(expected.size)) {
|
|
24
|
-
throw setupError("PM_STUDIO_BUNDLE_CHANGED", `PM Studio bundle changed while reading ${filePath}`);
|
|
25
|
-
}
|
|
26
|
-
for (;;) {
|
|
27
|
-
const length = fs.readSync(file, buffer, 0, buffer.length, null);
|
|
28
|
-
if (length === 0) break;
|
|
29
|
-
hash.update(buffer.subarray(0, length));
|
|
30
|
-
}
|
|
31
|
-
const after = fs.fstatSync(file, { bigint: true });
|
|
32
|
-
if (before.dev !== after.dev
|
|
33
|
-
|| before.ino !== after.ino
|
|
34
|
-
|| before.size !== after.size
|
|
35
|
-
|| before.mtimeNs !== after.mtimeNs
|
|
36
|
-
|| before.ctimeNs !== after.ctimeNs) {
|
|
37
|
-
throw setupError("PM_STUDIO_BUNDLE_CHANGED", `PM Studio bundle changed while hashing ${filePath}`);
|
|
38
|
-
}
|
|
39
|
-
} finally {
|
|
40
|
-
fs.closeSync(file);
|
|
41
|
-
}
|
|
42
|
-
return hash.digest("hex");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function parseXattrHex(output, root, ignoredXattrs) {
|
|
46
|
-
const records = [];
|
|
47
|
-
const ignored = new Set(ignoredXattrs);
|
|
48
|
-
const seen = new Set();
|
|
49
|
-
let current = null;
|
|
50
|
-
const flush = () => {
|
|
51
|
-
if (!current) return;
|
|
52
|
-
if (!ignored.has(current.name)) {
|
|
53
|
-
const key = `${current.path}\0${current.name}`;
|
|
54
|
-
if (seen.has(key)) throw setupError("PM_STUDIO_XATTR_INVALID", `Duplicate extended attribute ${current.name}`);
|
|
55
|
-
seen.add(key);
|
|
56
|
-
const value = Buffer.from(current.hex.join(""), "hex");
|
|
57
|
-
records.push(["xattr", current.path, current.name, value.length, sha256Hex(value)]);
|
|
58
|
-
}
|
|
59
|
-
current = null;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
for (const line of String(output || "").split(/\r?\n/)) {
|
|
63
|
-
if (!line) continue;
|
|
64
|
-
const separator = line.lastIndexOf(": ");
|
|
65
|
-
if ((line === `${root}:` || line.startsWith(`${root}: `) || line.startsWith(`${root}${path.sep}`))
|
|
66
|
-
&& separator >= root.length && line.endsWith(":")) {
|
|
67
|
-
flush();
|
|
68
|
-
const target = line.slice(0, separator);
|
|
69
|
-
const relative = target === root ? "." : path.relative(root, target).split(path.sep).join("/");
|
|
70
|
-
if (!relative || relative === ".." || relative.startsWith("../") || path.isAbsolute(relative)) {
|
|
71
|
-
throw setupError("PM_STUDIO_XATTR_INVALID", `Extended attribute path escapes PM Studio: ${target}`);
|
|
72
|
-
}
|
|
73
|
-
current = { path: relative, name: line.slice(separator + 2, -1), hex: [] };
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
if (!current) throw setupError("PM_STUDIO_XATTR_INVALID", "Could not parse PM Studio extended attributes");
|
|
77
|
-
const data = line.includes(" |") ? line.slice(0, line.indexOf(" |")) : line;
|
|
78
|
-
const tokens = data.trim().split(/\s+/);
|
|
79
|
-
if (!/^[0-9a-f]{8}$/i.test(tokens[0]) || tokens.slice(1).some((token) => !/^[0-9a-f]{2}$/i.test(token))) {
|
|
80
|
-
throw setupError("PM_STUDIO_XATTR_INVALID", "Could not parse PM Studio extended attribute bytes");
|
|
81
|
-
}
|
|
82
|
-
current.hex.push(...tokens.slice(1));
|
|
83
|
-
}
|
|
84
|
-
flush();
|
|
85
|
-
return records.sort((left, right) => Buffer.compare(
|
|
86
|
-
Buffer.from(`${left[1]}\0${left[2]}`),
|
|
87
|
-
Buffer.from(`${right[1]}\0${right[2]}`),
|
|
88
|
-
));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function inspectBundleContent(appPath, {
|
|
92
|
-
xattrOutput = "",
|
|
93
|
-
ignoredXattrs = [],
|
|
94
|
-
readBuffer,
|
|
95
|
-
} = {}) {
|
|
96
|
-
const root = path.resolve(appPath);
|
|
97
|
-
const rootStat = fs.lstatSync(root);
|
|
98
|
-
if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) {
|
|
99
|
-
throw setupError("PM_STUDIO_APP_INVALID", `PM Studio path is not a regular app bundle: ${appPath}`);
|
|
100
|
-
}
|
|
101
|
-
const records = [];
|
|
102
|
-
const normalizedPaths = new Map();
|
|
103
|
-
let regularFileCount = 0;
|
|
104
|
-
let regularBytes = 0;
|
|
105
|
-
let symlinkCount = 0;
|
|
106
|
-
|
|
107
|
-
const rememberPath = (relative) => {
|
|
108
|
-
const normalized = relative.normalize("NFC");
|
|
109
|
-
const existing = normalizedPaths.get(normalized);
|
|
110
|
-
if (existing && existing !== relative) {
|
|
111
|
-
throw setupError("PM_STUDIO_BUNDLE_PATH_COLLISION", `PM Studio contains colliding paths: ${existing} and ${relative}`);
|
|
112
|
-
}
|
|
113
|
-
normalizedPaths.set(normalized, relative);
|
|
114
|
-
};
|
|
115
|
-
rememberPath(".");
|
|
116
|
-
records.push(["directory", ".", rootStat.mode & 0o7777]);
|
|
117
|
-
const visit = (directory) => {
|
|
118
|
-
const names = fs.readdirSync(directory).sort((left, right) =>
|
|
119
|
-
Buffer.compare(Buffer.from(left), Buffer.from(right)));
|
|
120
|
-
for (const name of names) {
|
|
121
|
-
const fullPath = path.join(directory, name);
|
|
122
|
-
const stat = fs.lstatSync(fullPath);
|
|
123
|
-
const relative = path.relative(root, fullPath).split(path.sep).join("/");
|
|
124
|
-
const mode = stat.mode & 0o7777;
|
|
125
|
-
rememberPath(relative);
|
|
126
|
-
if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
|
127
|
-
records.push(["directory", relative, mode]);
|
|
128
|
-
visit(fullPath);
|
|
129
|
-
} else if (stat.isSymbolicLink()) {
|
|
130
|
-
const target = fs.readlinkSync(fullPath);
|
|
131
|
-
const resolved = path.resolve(path.dirname(fullPath), target);
|
|
132
|
-
if (path.isAbsolute(target)
|
|
133
|
-
|| (resolved !== root && !resolved.startsWith(`${root}${path.sep}`))
|
|
134
|
-
|| !fs.existsSync(resolved)) {
|
|
135
|
-
throw setupError("PM_STUDIO_BUNDLE_SYMLINK_INVALID", `PM Studio contains an unsafe symlink: ${relative}`);
|
|
136
|
-
}
|
|
137
|
-
symlinkCount += 1;
|
|
138
|
-
records.push(["symlink", relative, mode, target]);
|
|
139
|
-
} else if (stat.isFile()) {
|
|
140
|
-
if (stat.nlink !== 1) {
|
|
141
|
-
throw setupError("PM_STUDIO_BUNDLE_HARDLINK_INVALID", `PM Studio contains a hard-linked file: ${relative}`);
|
|
142
|
-
}
|
|
143
|
-
regularFileCount += 1;
|
|
144
|
-
regularBytes += stat.size;
|
|
145
|
-
records.push(["file", relative, mode, stat.size, hashRegularFile(fullPath, stat, readBuffer)]);
|
|
146
|
-
} else {
|
|
147
|
-
throw setupError("PM_STUDIO_BUNDLE_ENTRY_INVALID", `PM Studio contains an unsupported entry: ${relative}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
visit(root);
|
|
152
|
-
|
|
153
|
-
const xattrRecords = parseXattrHex(xattrOutput, root, ignoredXattrs);
|
|
154
|
-
const hash = createHash("sha256");
|
|
155
|
-
for (const record of [...records, ...xattrRecords]) hash.update(`${JSON.stringify(record)}\n`);
|
|
156
|
-
return {
|
|
157
|
-
scheme: BUNDLE_CONTENT_SCHEME,
|
|
158
|
-
sha256: hash.digest("hex"),
|
|
159
|
-
entryCount: records.length,
|
|
160
|
-
regularFileCount,
|
|
161
|
-
regularBytes,
|
|
162
|
-
symlinkCount,
|
|
163
|
-
xattrCount: xattrRecords.length,
|
|
164
|
-
};
|
|
165
|
-
}
|