@karlorz/codexhost-cli-win32-x64 0.13.3-0 → 0.13.3-3
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 +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-web.js +64 -0
- package/app/host-runtime.mjs +100 -184
- package/app/plugins/grok/plugin.mjs +315 -181
- package/app/renderer-extension.js +211 -5
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -3227,7 +3227,7 @@ var require_stream = __commonJS({
|
|
|
3227
3227
|
};
|
|
3228
3228
|
duplex._final = function(callback) {
|
|
3229
3229
|
if (ws.readyState === ws.CONNECTING) {
|
|
3230
|
-
ws.once("open", function
|
|
3230
|
+
ws.once("open", function open12() {
|
|
3231
3231
|
duplex._final(callback);
|
|
3232
3232
|
});
|
|
3233
3233
|
return;
|
|
@@ -3248,7 +3248,7 @@ var require_stream = __commonJS({
|
|
|
3248
3248
|
};
|
|
3249
3249
|
duplex._write = function(chunk, encoding, callback) {
|
|
3250
3250
|
if (ws.readyState === ws.CONNECTING) {
|
|
3251
|
-
ws.once("open", function
|
|
3251
|
+
ws.once("open", function open12() {
|
|
3252
3252
|
duplex._write(chunk, encoding, callback);
|
|
3253
3253
|
});
|
|
3254
3254
|
return;
|
|
@@ -21781,7 +21781,7 @@ function isLocalPageUrl(value2) {
|
|
|
21781
21781
|
return false;
|
|
21782
21782
|
}
|
|
21783
21783
|
}
|
|
21784
|
-
async function serveLocalPage(socket, url2,
|
|
21784
|
+
async function serveLocalPage(socket, url2, open12) {
|
|
21785
21785
|
let page;
|
|
21786
21786
|
let buffer = "";
|
|
21787
21787
|
let operation = Promise.resolve();
|
|
@@ -21815,7 +21815,7 @@ async function serveLocalPage(socket, url2, open13) {
|
|
|
21815
21815
|
}
|
|
21816
21816
|
};
|
|
21817
21817
|
try {
|
|
21818
|
-
page = await
|
|
21818
|
+
page = await open12(url2);
|
|
21819
21819
|
if (socket.destroyed)
|
|
21820
21820
|
return;
|
|
21821
21821
|
socket.on("data", receive);
|
|
@@ -26022,7 +26022,7 @@ async function atomicWrite(filePath, content) {
|
|
|
26022
26022
|
}
|
|
26023
26023
|
async function installDelegationSkills(input = {}) {
|
|
26024
26024
|
const home = input.homeDirectory ?? os6.homedir();
|
|
26025
|
-
const
|
|
26025
|
+
const destinations2 = [
|
|
26026
26026
|
path17.join(home, ".agents", SKILL_RELATIVE_PATH),
|
|
26027
26027
|
path17.join(home, ".claude", SKILL_RELATIVE_PATH)
|
|
26028
26028
|
];
|
|
@@ -26032,7 +26032,7 @@ async function installDelegationSkills(input = {}) {
|
|
|
26032
26032
|
...input.previousManagedDigests ?? []
|
|
26033
26033
|
]);
|
|
26034
26034
|
const results = [];
|
|
26035
|
-
for (const destination of
|
|
26035
|
+
for (const destination of destinations2) {
|
|
26036
26036
|
const current = await readOptional(destination);
|
|
26037
26037
|
if (current === CODEXHOST_DELEGATION_SKILL) {
|
|
26038
26038
|
results.push({
|
|
@@ -29339,6 +29339,18 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
29339
29339
|
changes: projectFileChanges(item.changes),
|
|
29340
29340
|
status: itemStatus(outcome)
|
|
29341
29341
|
};
|
|
29342
|
+
case "generatedImage":
|
|
29343
|
+
return {
|
|
29344
|
+
id: item.itemId,
|
|
29345
|
+
type: "imageGeneration",
|
|
29346
|
+
status: itemStatus(outcome),
|
|
29347
|
+
savedPath: item.savedPath,
|
|
29348
|
+
result: "",
|
|
29349
|
+
revisedPrompt: item.revisedPrompt ?? null,
|
|
29350
|
+
inputImages: [],
|
|
29351
|
+
failure: null,
|
|
29352
|
+
transparentBackground: null
|
|
29353
|
+
};
|
|
29342
29354
|
case "subagentDelegation": {
|
|
29343
29355
|
const primary = item.subagents[0];
|
|
29344
29356
|
const sameConfiguration = item.subagents.every((subagent) => subagent.model === primary?.model && subagent.reasoningEffort === primary?.reasoningEffort);
|
|
@@ -42448,9 +42460,9 @@ var AppServerHost = class {
|
|
|
42448
42460
|
*/
|
|
42449
42461
|
#withOpenBackgroundCommands(thread, turns) {
|
|
42450
42462
|
return turns.map((turn) => {
|
|
42451
|
-
const
|
|
42452
|
-
if (!
|
|
42453
|
-
const remaining = new Map(
|
|
42463
|
+
const open12 = thread.projectedTurns.get(turn.id)?.projector.openDetachedWireItems();
|
|
42464
|
+
if (!open12 || open12.size === 0) return turn;
|
|
42465
|
+
const remaining = new Map(open12);
|
|
42454
42466
|
const items = turn.items.map((item) => {
|
|
42455
42467
|
const id2 = item.id;
|
|
42456
42468
|
const live = remaining.get(id2);
|
|
@@ -45430,62 +45442,24 @@ async function startDelegationControlServer(input) {
|
|
|
45430
45442
|
}
|
|
45431
45443
|
|
|
45432
45444
|
// packages/host-runtime/src/codexhost-desktop-rule.ts
|
|
45433
|
-
import { createHash as createHash11
|
|
45434
|
-
import {
|
|
45445
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
45446
|
+
import { readFile as readFile18, rm as rm14 } from "node:fs/promises";
|
|
45435
45447
|
import os10 from "node:os";
|
|
45436
45448
|
import path33 from "node:path";
|
|
45437
|
-
var RULE_VERSION = 3;
|
|
45438
45449
|
var RULE_FILE = "codexhost-desktop.md";
|
|
45439
|
-
var
|
|
45450
|
+
var MANAGED_DIGESTS = [
|
|
45440
45451
|
"5add2d2c7ea03ecbb3552b94e47da7a755909e63f30714878a5609a4e272526f",
|
|
45441
|
-
"9d8d2762b5f90e6f10a6571651b3461dec882bd45b40f0f0debc432f4833301b"
|
|
45452
|
+
"9d8d2762b5f90e6f10a6571651b3461dec882bd45b40f0f0debc432f4833301b",
|
|
45453
|
+
"4658e68f312686e2134cd282abd9ce434d2583b0a1d23c7c3eb8bd7ec9b76cf3"
|
|
45442
45454
|
];
|
|
45443
|
-
var CODEXHOST_DESKTOP_RULE = `<!-- codexhost-desktop-rule: ${RULE_VERSION} -->
|
|
45444
|
-
# Codex Desktop / CodexHost
|
|
45445
|
-
|
|
45446
|
-
CodexHost installs this file into Grok home rules. Orca and Grok TUI sessions may also load it.
|
|
45447
|
-
|
|
45448
|
-
At the first user turn, if you have a shell, run this once and print only \`set\` or \`unset\`:
|
|
45449
|
-
|
|
45450
|
-
\`\`\`sh
|
|
45451
|
-
if test -n "\${CODEXHOST_THREAD_ID-}"; then echo set; else echo unset; fi
|
|
45452
|
-
\`\`\`
|
|
45453
|
-
|
|
45454
|
-
- \`set\`: this is a CodexHost external Thread, including Codex Desktop. Apply the session rules even when cwd is a real repository such as \`codex-host\` or the wiki.
|
|
45455
|
-
- Working directory is a Playground folder named \`realtime-voice-chat\` or \`realtime-voice-chat-*\`: apply the session rules and ask the user to start a new Thread in the real repo.
|
|
45456
|
-
- \`unset\` and not a Playground voice cwd: leave the session rules inactive.
|
|
45457
|
-
|
|
45458
|
-
Never print \`CODEXHOST_THREAD_ID\`, \`CODEXHOST_RUNTIME_TOKEN\`, \`CODEXHOST_RUNTIME_ENDPOINT\`, or other runtime descriptors. Do not invent other host signals.
|
|
45459
|
-
|
|
45460
|
-
## Session rules
|
|
45461
|
-
|
|
45462
|
-
1. **Model.** The Desktop composer Model is this Harness's Model. Pick that Harness's real Model before starting voice. For Grok, that is grok-4.6 or grok-4.7. \`flash-max\` is a Gemini Flash Model.
|
|
45463
|
-
|
|
45464
|
-
2. **Working directory.** Start the chat in the real repository (\`codex-host\` or the wiki). A Playground \`realtime-voice-chat*\` folder is a scratch cwd. Ask the user to start a new Thread in the real repo.
|
|
45465
|
-
|
|
45466
|
-
3. **Voice vs tools.** Desktop voice is gpt-live speech plus delegated Harness tasks on this same Thread. Do wiki, MCP, and file-heavy work as text in this Thread.
|
|
45467
|
-
|
|
45468
|
-
4. **Harness-owned tools.** This session's MCP servers and skills belong to this Harness. SkillWiki on Grok is Grok's config, not Claude, Pi, or Codex.
|
|
45469
|
-
|
|
45470
|
-
5. **Desktop chrome.** The window is Codex Desktop. Markdown View preview is a Codex file tab (View preview vs View source). \`file://\` browser tabs stay raw.
|
|
45471
|
-
|
|
45472
|
-
6. **Voice routes.** Official Codex live voice (New API/CPA) is a separate route from Host-owned external \`thread/realtime/*\`. This external Thread uses the Host-owned route.
|
|
45473
|
-
|
|
45474
|
-
Keep Grok Build tools, MCP, and rules inside the native session. An \`AGENT_TOOLS_AND_RULES.md\` dump in the cwd is unnecessary.
|
|
45475
|
-
`;
|
|
45476
|
-
var CURRENT_DIGEST2 = createHash11("sha256").update(CODEXHOST_DESKTOP_RULE).digest("hex");
|
|
45477
45455
|
function digest2(value2) {
|
|
45478
45456
|
return createHash11("sha256").update(value2).digest("hex");
|
|
45479
45457
|
}
|
|
45480
|
-
function
|
|
45481
|
-
|
|
45482
|
-
|
|
45483
|
-
|
|
45484
|
-
|
|
45485
|
-
return path33.join(home, ".grok", "rules", RULE_FILE);
|
|
45486
|
-
}
|
|
45487
|
-
function claudeDestination(home) {
|
|
45488
|
-
return path33.join(home, ".claude", "rules", RULE_FILE);
|
|
45458
|
+
function destinations(home) {
|
|
45459
|
+
return [
|
|
45460
|
+
path33.join(home, ".grok", "rules", RULE_FILE),
|
|
45461
|
+
path33.join(home, ".claude", "rules", RULE_FILE)
|
|
45462
|
+
];
|
|
45489
45463
|
}
|
|
45490
45464
|
async function readOptional2(filePath) {
|
|
45491
45465
|
try {
|
|
@@ -45495,81 +45469,23 @@ async function readOptional2(filePath) {
|
|
|
45495
45469
|
throw error51;
|
|
45496
45470
|
}
|
|
45497
45471
|
}
|
|
45498
|
-
async function
|
|
45499
|
-
await mkdir15(path33.dirname(filePath), { recursive: true, mode: 448 });
|
|
45500
|
-
const temporaryPath = path33.join(path33.dirname(filePath), `.${RULE_FILE}.${randomUUID18()}.tmp`);
|
|
45501
|
-
const handle = await open10(temporaryPath, "wx", 384);
|
|
45502
|
-
try {
|
|
45503
|
-
await handle.writeFile(content, "utf8");
|
|
45504
|
-
await handle.sync();
|
|
45505
|
-
} finally {
|
|
45506
|
-
await handle.close();
|
|
45507
|
-
}
|
|
45508
|
-
try {
|
|
45509
|
-
await rename12(temporaryPath, filePath);
|
|
45510
|
-
} finally {
|
|
45511
|
-
await rm14(temporaryPath, { force: true });
|
|
45512
|
-
}
|
|
45513
|
-
}
|
|
45514
|
-
async function installCodexhostDesktopRules(input = {}) {
|
|
45472
|
+
async function retireCodexhostDesktopRules(input = {}) {
|
|
45515
45473
|
const home = input.homeDirectory ?? os10.homedir();
|
|
45516
|
-
const knownDigests = /* @__PURE__ */ new Set([
|
|
45517
|
-
CURRENT_DIGEST2,
|
|
45518
|
-
...PREVIOUS_MANAGED_DIGESTS2,
|
|
45519
|
-
...input.previousManagedDigests ?? []
|
|
45520
|
-
]);
|
|
45474
|
+
const knownDigests = /* @__PURE__ */ new Set([...MANAGED_DIGESTS, ...input.previousManagedDigests ?? []]);
|
|
45521
45475
|
const results = [];
|
|
45522
|
-
const destination
|
|
45523
|
-
|
|
45524
|
-
|
|
45525
|
-
|
|
45526
|
-
|
|
45527
|
-
|
|
45528
|
-
version: RULE_VERSION,
|
|
45529
|
-
digest: CURRENT_DIGEST2
|
|
45530
|
-
});
|
|
45531
|
-
} else if (current !== null) {
|
|
45476
|
+
for (const destination of destinations(home)) {
|
|
45477
|
+
const current = await readOptional2(destination);
|
|
45478
|
+
if (current === null) {
|
|
45479
|
+
results.push({ path: destination, status: "absent", digest: null });
|
|
45480
|
+
continue;
|
|
45481
|
+
}
|
|
45532
45482
|
const currentDigest = digest2(current);
|
|
45533
|
-
const version2 = managedVersion2(current);
|
|
45534
45483
|
if (!knownDigests.has(currentDigest)) {
|
|
45535
|
-
results.push({ path: destination, status: "conflict",
|
|
45536
|
-
|
|
45537
|
-
await atomicWrite2(destination, CODEXHOST_DESKTOP_RULE);
|
|
45538
|
-
results.push({
|
|
45539
|
-
path: destination,
|
|
45540
|
-
status: "updated",
|
|
45541
|
-
version: RULE_VERSION,
|
|
45542
|
-
digest: CURRENT_DIGEST2
|
|
45543
|
-
});
|
|
45544
|
-
}
|
|
45545
|
-
} else {
|
|
45546
|
-
await atomicWrite2(destination, CODEXHOST_DESKTOP_RULE);
|
|
45547
|
-
results.push({
|
|
45548
|
-
path: destination,
|
|
45549
|
-
status: "installed",
|
|
45550
|
-
version: RULE_VERSION,
|
|
45551
|
-
digest: CURRENT_DIGEST2
|
|
45552
|
-
});
|
|
45553
|
-
}
|
|
45554
|
-
const claude = claudeDestination(home);
|
|
45555
|
-
const claudeCurrent = await readOptional2(claude);
|
|
45556
|
-
if (claudeCurrent !== null) {
|
|
45557
|
-
const claudeDigest = digest2(claudeCurrent);
|
|
45558
|
-
const version2 = managedVersion2(claudeCurrent);
|
|
45559
|
-
if (knownDigests.has(claudeDigest) || claudeCurrent === CODEXHOST_DESKTOP_RULE) {
|
|
45560
|
-
await rm14(claude, { force: true });
|
|
45561
|
-
results.push({ path: claude, status: "removed", version: version2, digest: claudeDigest });
|
|
45562
|
-
} else {
|
|
45563
|
-
results.push({ path: claude, status: "conflict", version: version2, digest: claudeDigest });
|
|
45564
|
-
}
|
|
45565
|
-
}
|
|
45566
|
-
for (const result of results) {
|
|
45567
|
-
if (result.status === "conflict" || result.status === "removed") continue;
|
|
45568
|
-
const source = await readFile18(result.path, "utf8");
|
|
45569
|
-
const metadata = await stat8(result.path);
|
|
45570
|
-
if (!metadata.isFile() || source !== CODEXHOST_DESKTOP_RULE) {
|
|
45571
|
-
throw new Error(`Codex Desktop rule verification failed: ${result.path}`);
|
|
45484
|
+
results.push({ path: destination, status: "conflict", digest: currentDigest });
|
|
45485
|
+
continue;
|
|
45572
45486
|
}
|
|
45487
|
+
await rm14(destination, { force: true });
|
|
45488
|
+
results.push({ path: destination, status: "removed", digest: currentDigest });
|
|
45573
45489
|
}
|
|
45574
45490
|
return results;
|
|
45575
45491
|
}
|
|
@@ -45621,11 +45537,11 @@ async function readRemoteDelegationThread(environment, input) {
|
|
|
45621
45537
|
}
|
|
45622
45538
|
|
|
45623
45539
|
// packages/host-runtime/src/shared-thread-owner.ts
|
|
45624
|
-
import { randomUUID as
|
|
45540
|
+
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
45625
45541
|
import { PassThrough as PassThrough3 } from "node:stream";
|
|
45626
45542
|
|
|
45627
45543
|
// packages/host-runtime/src/shared-thread-peer.ts
|
|
45628
|
-
import { randomUUID as
|
|
45544
|
+
import { randomUUID as randomUUID18 } from "node:crypto";
|
|
45629
45545
|
function object7(value2) {
|
|
45630
45546
|
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
45631
45547
|
}
|
|
@@ -45639,7 +45555,7 @@ var StreamThreadPeer = class {
|
|
|
45639
45555
|
input;
|
|
45640
45556
|
output;
|
|
45641
45557
|
stop;
|
|
45642
|
-
#prefix = `shared:${
|
|
45558
|
+
#prefix = `shared:${randomUUID18()}:`;
|
|
45643
45559
|
#pending = /* @__PURE__ */ new Map();
|
|
45644
45560
|
#listeners = /* @__PURE__ */ new Set();
|
|
45645
45561
|
#ended = Promise.withResolvers();
|
|
@@ -45717,7 +45633,7 @@ var SharedThreadOwner = class {
|
|
|
45717
45633
|
input = new PassThrough3();
|
|
45718
45634
|
output = new PassThrough3();
|
|
45719
45635
|
#peer = new StreamThreadPeer(this.output, this.input, () => this.input.end());
|
|
45720
|
-
#prefix = `shared-interaction:${
|
|
45636
|
+
#prefix = `shared-interaction:${randomUUID19()}:`;
|
|
45721
45637
|
#interactions = /* @__PURE__ */ new Map();
|
|
45722
45638
|
#listeners = /* @__PURE__ */ new Set();
|
|
45723
45639
|
#receipts = /* @__PURE__ */ new Map();
|
|
@@ -46027,8 +45943,8 @@ var SharedThreadBridge = class {
|
|
|
46027
45943
|
};
|
|
46028
45944
|
|
|
46029
45945
|
// packages/host-runtime/src/remote-control-app-server.ts
|
|
46030
|
-
import { randomUUID as
|
|
46031
|
-
import { mkdir as
|
|
45946
|
+
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
45947
|
+
import { mkdir as mkdir15, open as open10, rename as rename12, rm as rm15 } from "node:fs/promises";
|
|
46032
45948
|
import path35 from "node:path";
|
|
46033
45949
|
var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
|
|
46034
45950
|
var REMOTE_CONTROL_BRIDGE_NODE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_NODE_PATH";
|
|
@@ -46048,7 +45964,7 @@ function nodeCompatibleWindowsPath(value2) {
|
|
|
46048
45964
|
if (value2.startsWith("\\\\?\\")) return value2.slice(4);
|
|
46049
45965
|
return value2;
|
|
46050
45966
|
}
|
|
46051
|
-
function remoteControlBridgePipePath(processId = process.pid, instanceId =
|
|
45967
|
+
function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID20()) {
|
|
46052
45968
|
const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
|
|
46053
45969
|
if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
|
|
46054
45970
|
return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
|
|
@@ -46060,12 +45976,12 @@ function remoteControlBridgeDescriptorPath(environment) {
|
|
|
46060
45976
|
}
|
|
46061
45977
|
async function publishRemoteControlAppServerDescriptor(plan) {
|
|
46062
45978
|
const directory = path35.dirname(plan.descriptorPath);
|
|
46063
|
-
await
|
|
45979
|
+
await mkdir15(directory, { recursive: true, mode: 448 });
|
|
46064
45980
|
const temporaryPath = path35.join(
|
|
46065
45981
|
directory,
|
|
46066
|
-
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${
|
|
45982
|
+
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID20()}.tmp`
|
|
46067
45983
|
);
|
|
46068
|
-
const handle = await
|
|
45984
|
+
const handle = await open10(temporaryPath, "wx", 384);
|
|
46069
45985
|
try {
|
|
46070
45986
|
await handle.writeFile(`${JSON.stringify(plan.descriptor)}
|
|
46071
45987
|
`, "utf8");
|
|
@@ -46074,7 +45990,7 @@ async function publishRemoteControlAppServerDescriptor(plan) {
|
|
|
46074
45990
|
await handle.close();
|
|
46075
45991
|
}
|
|
46076
45992
|
try {
|
|
46077
|
-
await
|
|
45993
|
+
await rename12(temporaryPath, plan.descriptorPath);
|
|
46078
45994
|
} finally {
|
|
46079
45995
|
await rm15(temporaryPath, { force: true });
|
|
46080
45996
|
}
|
|
@@ -46188,7 +46104,7 @@ function watchRemoteListenerSupervisor(options2) {
|
|
|
46188
46104
|
|
|
46189
46105
|
// packages/host-runtime/src/console-control-server.ts
|
|
46190
46106
|
import { randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
|
|
46191
|
-
import { mkdir as
|
|
46107
|
+
import { mkdir as mkdir16, rename as rename13, rm as rm16, writeFile as writeFile9 } from "node:fs/promises";
|
|
46192
46108
|
import { createServer as createServer4 } from "node:http";
|
|
46193
46109
|
import os11 from "node:os";
|
|
46194
46110
|
import path36 from "node:path";
|
|
@@ -46226,12 +46142,12 @@ function reply(response, status2, value2) {
|
|
|
46226
46142
|
response.end(body);
|
|
46227
46143
|
}
|
|
46228
46144
|
async function writePrivateJson2(filePath, value2) {
|
|
46229
|
-
await
|
|
46145
|
+
await mkdir16(path36.dirname(filePath), { recursive: true, mode: 448 });
|
|
46230
46146
|
const temporary = `${filePath}.${randomBytes3(6).toString("hex")}.tmp`;
|
|
46231
46147
|
try {
|
|
46232
46148
|
await writeFile9(temporary, `${JSON.stringify(value2)}
|
|
46233
46149
|
`, { mode: 384, flag: "wx" });
|
|
46234
|
-
await
|
|
46150
|
+
await rename13(temporary, filePath);
|
|
46235
46151
|
} finally {
|
|
46236
46152
|
await rm16(temporary, { force: true });
|
|
46237
46153
|
}
|
|
@@ -46585,8 +46501,8 @@ function createHostUpdateCoordinator(options2) {
|
|
|
46585
46501
|
}
|
|
46586
46502
|
|
|
46587
46503
|
// packages/host-runtime/src/usage-statistics.ts
|
|
46588
|
-
import { randomUUID as
|
|
46589
|
-
import { mkdir as
|
|
46504
|
+
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
46505
|
+
import { mkdir as mkdir17, readFile as readFile19, readdir as readdir6, rename as rename14, rm as rm17, writeFile as writeFile10 } from "node:fs/promises";
|
|
46590
46506
|
import path38 from "node:path";
|
|
46591
46507
|
import { setImmediate as yieldToEventLoop } from "node:timers/promises";
|
|
46592
46508
|
|
|
@@ -47028,16 +46944,16 @@ var UsageStatistics = class {
|
|
|
47028
46944
|
async #persist(harness2, cache) {
|
|
47029
46945
|
if (!cache.dirty || this.#now() - cache.persistedAtMs < PERSIST_INTERVAL_MS) return;
|
|
47030
46946
|
const file2 = this.#file(harness2);
|
|
47031
|
-
const temporary = `${file2}.${
|
|
46947
|
+
const temporary = `${file2}.${randomUUID21()}.tmp`;
|
|
47032
46948
|
try {
|
|
47033
|
-
await
|
|
46949
|
+
await mkdir17(this.#directory, { recursive: true });
|
|
47034
46950
|
const sources = [...cache.sources].map(([id2, source]) => [
|
|
47035
46951
|
id2,
|
|
47036
46952
|
source.fingerprint,
|
|
47037
46953
|
source.entries.map(compact)
|
|
47038
46954
|
]);
|
|
47039
46955
|
await writeFile10(temporary, JSON.stringify({ version: CACHE_VERSION, sources }));
|
|
47040
|
-
await
|
|
46956
|
+
await rename14(temporary, file2);
|
|
47041
46957
|
cache.dirty = false;
|
|
47042
46958
|
cache.persistedAtMs = this.#now();
|
|
47043
46959
|
} catch (error51) {
|
|
@@ -47334,7 +47250,7 @@ async function prepareDelegationRuntime(input) {
|
|
|
47334
47250
|
[DELEGATION_RUNTIME_TOKEN_ENV]: token
|
|
47335
47251
|
};
|
|
47336
47252
|
await installManagedHomeFiles(installDelegationSkills, "delegation Skill");
|
|
47337
|
-
await installManagedHomeFiles(
|
|
47253
|
+
await installManagedHomeFiles(retireCodexhostDesktopRules, "Desktop rule retirement");
|
|
47338
47254
|
try {
|
|
47339
47255
|
return await input.createHost(environment, (value2) => registry2.register(value2), registry2);
|
|
47340
47256
|
} finally {
|
|
@@ -47649,19 +47565,19 @@ async function runHostRuntime(input) {
|
|
|
47649
47565
|
}
|
|
47650
47566
|
|
|
47651
47567
|
// packages/host-runtime/src/remote-host-install.ts
|
|
47652
|
-
import { createHash as createHash12, randomUUID as
|
|
47568
|
+
import { createHash as createHash12, randomUUID as randomUUID22 } from "node:crypto";
|
|
47653
47569
|
import { constants as fsConstants } from "node:fs";
|
|
47654
47570
|
import {
|
|
47655
47571
|
access as access3,
|
|
47656
47572
|
chmod as chmod5,
|
|
47657
47573
|
copyFile as copyFile4,
|
|
47658
47574
|
lstat as lstat9,
|
|
47659
|
-
mkdir as
|
|
47575
|
+
mkdir as mkdir18,
|
|
47660
47576
|
readFile as readFile20,
|
|
47661
|
-
rename as
|
|
47577
|
+
rename as rename15,
|
|
47662
47578
|
rm as rm18,
|
|
47663
47579
|
rmdir,
|
|
47664
|
-
stat as
|
|
47580
|
+
stat as stat8,
|
|
47665
47581
|
writeFile as writeFile11
|
|
47666
47582
|
} from "node:fs/promises";
|
|
47667
47583
|
import path40 from "node:path";
|
|
@@ -47714,7 +47630,7 @@ async function fileSha256(filePath) {
|
|
|
47714
47630
|
async function executable(filePath, label) {
|
|
47715
47631
|
const absolute = path40.resolve(filePath);
|
|
47716
47632
|
try {
|
|
47717
|
-
if (!(await
|
|
47633
|
+
if (!(await stat8(absolute)).isFile()) throw new Error("not a regular file");
|
|
47718
47634
|
await access3(absolute, fsConstants.X_OK);
|
|
47719
47635
|
} catch {
|
|
47720
47636
|
throw new Error(`${label} is not an executable file: ${absolute}`);
|
|
@@ -47724,7 +47640,7 @@ async function executable(filePath, label) {
|
|
|
47724
47640
|
async function existingFile(filePath, label) {
|
|
47725
47641
|
const absolute = path40.resolve(filePath);
|
|
47726
47642
|
try {
|
|
47727
|
-
const metadata = await
|
|
47643
|
+
const metadata = await stat8(absolute);
|
|
47728
47644
|
if (!metadata.isFile()) throw new Error("not a regular file");
|
|
47729
47645
|
} catch {
|
|
47730
47646
|
throw new Error(`${label} is not a regular file: ${absolute}`);
|
|
@@ -47745,10 +47661,10 @@ async function discoverExecutable(name, environment) {
|
|
|
47745
47661
|
return null;
|
|
47746
47662
|
}
|
|
47747
47663
|
async function writeAtomic(filePath, contents, mode) {
|
|
47748
|
-
await
|
|
47664
|
+
await mkdir18(path40.dirname(filePath), { recursive: true, mode: 448 });
|
|
47749
47665
|
const temporary = path40.join(
|
|
47750
47666
|
path40.dirname(filePath),
|
|
47751
|
-
`.${path40.basename(filePath)}.${process.pid}.${
|
|
47667
|
+
`.${path40.basename(filePath)}.${process.pid}.${randomUUID22()}.tmp`
|
|
47752
47668
|
);
|
|
47753
47669
|
try {
|
|
47754
47670
|
if (typeof contents === "string") {
|
|
@@ -47758,31 +47674,31 @@ async function writeAtomic(filePath, contents, mode) {
|
|
|
47758
47674
|
}
|
|
47759
47675
|
await chmod5(temporary, mode);
|
|
47760
47676
|
try {
|
|
47761
|
-
await
|
|
47677
|
+
await rename15(temporary, filePath);
|
|
47762
47678
|
} catch (error51) {
|
|
47763
47679
|
if (process.platform !== "win32") throw error51;
|
|
47764
47680
|
await rm18(filePath, { force: true });
|
|
47765
|
-
await
|
|
47681
|
+
await rename15(temporary, filePath);
|
|
47766
47682
|
}
|
|
47767
47683
|
} finally {
|
|
47768
47684
|
await rm18(temporary, { force: true });
|
|
47769
47685
|
}
|
|
47770
47686
|
}
|
|
47771
47687
|
async function writeAtomicExecutable(filePath, sourcePath) {
|
|
47772
|
-
await
|
|
47688
|
+
await mkdir18(path40.dirname(filePath), { recursive: true, mode: 448 });
|
|
47773
47689
|
const temporary = path40.join(
|
|
47774
47690
|
path40.dirname(filePath),
|
|
47775
|
-
`.${path40.basename(filePath)}.${process.pid}.${
|
|
47691
|
+
`.${path40.basename(filePath)}.${process.pid}.${randomUUID22()}.tmp`
|
|
47776
47692
|
);
|
|
47777
47693
|
try {
|
|
47778
47694
|
await copyFile4(sourcePath, temporary);
|
|
47779
47695
|
await chmod5(temporary, 448);
|
|
47780
47696
|
try {
|
|
47781
|
-
await
|
|
47697
|
+
await rename15(temporary, filePath);
|
|
47782
47698
|
} catch (error51) {
|
|
47783
47699
|
if (process.platform !== "win32") throw error51;
|
|
47784
47700
|
await rm18(filePath, { force: true });
|
|
47785
|
-
await
|
|
47701
|
+
await rename15(temporary, filePath);
|
|
47786
47702
|
}
|
|
47787
47703
|
} finally {
|
|
47788
47704
|
await rm18(temporary, { force: true });
|
|
@@ -47906,7 +47822,7 @@ async function readManifest(filePath) {
|
|
|
47906
47822
|
async function backupProfile(profilePath, contents, action) {
|
|
47907
47823
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(/[-:.TZ]/gu, "");
|
|
47908
47824
|
const backupPath = `${profilePath}.codexhost-${action}-${timestamp}.bak`;
|
|
47909
|
-
const metadata = await
|
|
47825
|
+
const metadata = await stat8(profilePath).catch(() => null);
|
|
47910
47826
|
await writeAtomic(backupPath, contents, metadata?.mode ?? 384);
|
|
47911
47827
|
return backupPath;
|
|
47912
47828
|
}
|
|
@@ -47920,7 +47836,7 @@ async function installRemoteHost(options2) {
|
|
|
47920
47836
|
const previousManifest = await readManifest(paths.manifestPath);
|
|
47921
47837
|
const previousManifestFile = previousManifest ? {
|
|
47922
47838
|
contents: await readFile20(paths.manifestPath),
|
|
47923
|
-
mode: (await
|
|
47839
|
+
mode: (await stat8(paths.manifestPath)).mode & 511
|
|
47924
47840
|
} : null;
|
|
47925
47841
|
const existingEntrypoint = await lstat9(paths.wrapperPath).catch(
|
|
47926
47842
|
(error51) => {
|
|
@@ -47976,14 +47892,14 @@ async function installRemoteHost(options2) {
|
|
|
47976
47892
|
const existingProfile = existingProfileSource ?? "";
|
|
47977
47893
|
const nextProfile = installManagedProfileBlock(existingProfile, manifest);
|
|
47978
47894
|
const profileChanged = nextProfile !== existingProfile;
|
|
47979
|
-
const profileMetadata = await
|
|
47895
|
+
const profileMetadata = await stat8(profilePath).catch(() => null);
|
|
47980
47896
|
try {
|
|
47981
47897
|
if (profileChanged) {
|
|
47982
47898
|
const profileBackupPath = await backupProfile(profilePath, existingProfile, "install");
|
|
47983
47899
|
manifest = { ...manifest, profileBackupPath };
|
|
47984
47900
|
await writeAtomic(profilePath, nextProfile, profileMetadata?.mode ?? 384);
|
|
47985
47901
|
}
|
|
47986
|
-
await
|
|
47902
|
+
await mkdir18(paths.dataDirectory, { recursive: true, mode: 448 });
|
|
47987
47903
|
await chmod5(paths.dataDirectory, 448);
|
|
47988
47904
|
await writeAtomicExecutable(paths.wrapperPath, manifest.shimPath);
|
|
47989
47905
|
manifest = { ...manifest, entrypointSha256: await fileSha256(paths.wrapperPath) };
|
|
@@ -48067,7 +47983,7 @@ async function inspectRemoteHostInstallation(options2) {
|
|
|
48067
47983
|
if (!profileMatches && profileIssue === null)
|
|
48068
47984
|
profileIssue = "shell profile does not configure the managed native entrypoint";
|
|
48069
47985
|
if (profileIssue !== null) issues.push(profileIssue);
|
|
48070
|
-
const dataDirectory = await
|
|
47986
|
+
const dataDirectory = await stat8(manifest.dataDirectory).catch(() => null);
|
|
48071
47987
|
if (!dataDirectory?.isDirectory()) issues.push("remote Host data directory is unavailable");
|
|
48072
47988
|
for (const [label, filePath, requiresExecutable] of [
|
|
48073
47989
|
["stock Codex", manifest.stockCodexPath, true],
|
|
@@ -48077,7 +47993,7 @@ async function inspectRemoteHostInstallation(options2) {
|
|
|
48077
47993
|
]) {
|
|
48078
47994
|
try {
|
|
48079
47995
|
if (requiresExecutable) await executable(filePath, label);
|
|
48080
|
-
else if (!(await
|
|
47996
|
+
else if (!(await stat8(filePath)).isFile()) throw new Error("not a regular file");
|
|
48081
47997
|
} catch {
|
|
48082
47998
|
issues.push(`${label} is unavailable`);
|
|
48083
47999
|
}
|
|
@@ -48106,7 +48022,7 @@ async function uninstallRemoteHost(options2) {
|
|
|
48106
48022
|
const nextProfile = removeManagedProfileBlock(profile);
|
|
48107
48023
|
if (nextProfile !== profile) {
|
|
48108
48024
|
await backupProfile(manifest.profilePath, profile, "uninstall");
|
|
48109
|
-
const metadata = await
|
|
48025
|
+
const metadata = await stat8(manifest.profilePath).catch(() => null);
|
|
48110
48026
|
await writeAtomic(manifest.profilePath, nextProfile, metadata?.mode ?? 384);
|
|
48111
48027
|
}
|
|
48112
48028
|
await rm18(manifest.wrapperPath, { force: true });
|
|
@@ -48121,7 +48037,7 @@ async function uninstallRemoteHost(options2) {
|
|
|
48121
48037
|
|
|
48122
48038
|
// packages/host-runtime/src/remote-host-lifecycle.ts
|
|
48123
48039
|
import { spawn as spawn8 } from "node:child_process";
|
|
48124
|
-
import { stat as
|
|
48040
|
+
import { stat as stat9 } from "node:fs/promises";
|
|
48125
48041
|
import net3 from "node:net";
|
|
48126
48042
|
import path41 from "node:path";
|
|
48127
48043
|
import { Duplex } from "node:stream";
|
|
@@ -48147,7 +48063,7 @@ function socketPathFor(environment) {
|
|
|
48147
48063
|
return path41.join(codexHome, "app-server-control", "app-server-control.sock");
|
|
48148
48064
|
}
|
|
48149
48065
|
async function defaultSocketExists(socketPath) {
|
|
48150
|
-
const metadata = await
|
|
48066
|
+
const metadata = await stat9(socketPath).catch((error51) => {
|
|
48151
48067
|
if (error51.code === "ENOENT") return null;
|
|
48152
48068
|
throw error51;
|
|
48153
48069
|
});
|
|
@@ -48854,8 +48770,8 @@ var harnessOutputSchema = external_exports.custom((value2) => {
|
|
|
48854
48770
|
});
|
|
48855
48771
|
|
|
48856
48772
|
// packages/harness-broker/dist/server.js
|
|
48857
|
-
import { randomBytes as randomBytes5, randomUUID as
|
|
48858
|
-
import { chmod as chmod6, lstat as lstat10, mkdir as
|
|
48773
|
+
import { randomBytes as randomBytes5, randomUUID as randomUUID23 } from "node:crypto";
|
|
48774
|
+
import { chmod as chmod6, lstat as lstat10, mkdir as mkdir19, open as open11, readFile as readFile21, rename as rename16, rm as rm19 } from "node:fs/promises";
|
|
48859
48775
|
import net4, {} from "node:net";
|
|
48860
48776
|
import path43 from "node:path";
|
|
48861
48777
|
function harnessError(message2, retryable = true) {
|
|
@@ -48868,7 +48784,7 @@ function nativeWriterKey(nativeSessionId) {
|
|
|
48868
48784
|
return nativeSessionId;
|
|
48869
48785
|
}
|
|
48870
48786
|
async function privateDirectory(directory) {
|
|
48871
|
-
await
|
|
48787
|
+
await mkdir19(directory, { recursive: true, mode: 448 });
|
|
48872
48788
|
if (process.platform === "win32")
|
|
48873
48789
|
return;
|
|
48874
48790
|
const metadata = await lstat10(directory);
|
|
@@ -48913,8 +48829,8 @@ async function assertNoLiveDescriptor(descriptorPath) {
|
|
|
48913
48829
|
}
|
|
48914
48830
|
}
|
|
48915
48831
|
async function publishDescriptor(descriptorPath, descriptor) {
|
|
48916
|
-
const temporary = `${descriptorPath}.${process.pid}.${
|
|
48917
|
-
const handle = await
|
|
48832
|
+
const temporary = `${descriptorPath}.${process.pid}.${randomUUID23()}.tmp`;
|
|
48833
|
+
const handle = await open11(temporary, "wx", 384);
|
|
48918
48834
|
try {
|
|
48919
48835
|
await handle.writeFile(`${JSON.stringify(descriptor)}
|
|
48920
48836
|
`, "utf8");
|
|
@@ -48922,7 +48838,7 @@ async function publishDescriptor(descriptorPath, descriptor) {
|
|
|
48922
48838
|
} finally {
|
|
48923
48839
|
await handle.close();
|
|
48924
48840
|
}
|
|
48925
|
-
await
|
|
48841
|
+
await rename16(temporary, descriptorPath);
|
|
48926
48842
|
if (process.platform !== "win32")
|
|
48927
48843
|
await chmod6(descriptorPath, 384);
|
|
48928
48844
|
}
|
|
@@ -48990,7 +48906,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
48990
48906
|
await assertNoLiveDescriptor(input.descriptorPath);
|
|
48991
48907
|
if (process.platform !== "win32")
|
|
48992
48908
|
await prepareUnixSocketPath(input.socketPath);
|
|
48993
|
-
const generation = input.generation ??
|
|
48909
|
+
const generation = input.generation ?? randomUUID23();
|
|
48994
48910
|
const token = input.token ?? randomBytes5(32).toString("hex");
|
|
48995
48911
|
const descriptor = {
|
|
48996
48912
|
schemaVersion: 1,
|
|
@@ -49031,7 +48947,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
49031
48947
|
};
|
|
49032
48948
|
const server = net4.createServer((socket) => {
|
|
49033
48949
|
const state = {
|
|
49034
|
-
id:
|
|
48950
|
+
id: randomUUID23(),
|
|
49035
48951
|
socket,
|
|
49036
48952
|
authenticated: false,
|
|
49037
48953
|
inputSequence: 0,
|
|
@@ -49269,7 +49185,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
49269
49185
|
}
|
|
49270
49186
|
};
|
|
49271
49187
|
}
|
|
49272
|
-
const openReservation =
|
|
49188
|
+
const openReservation = randomUUID23();
|
|
49273
49189
|
if (sourceKey)
|
|
49274
49190
|
nativeWriters.set(sourceKey, openReservation);
|
|
49275
49191
|
const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
|
|
@@ -49570,7 +49486,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
49570
49486
|
}
|
|
49571
49487
|
state.authenticated = true;
|
|
49572
49488
|
state.inputSequence = 1;
|
|
49573
|
-
await send({ kind: "response", id:
|
|
49489
|
+
await send({ kind: "response", id: randomUUID23(), ok: true, value: { ready: true } });
|
|
49574
49490
|
return;
|
|
49575
49491
|
}
|
|
49576
49492
|
const parsed2 = harnessBrokerRequestSchema.safeParse(raw);
|
|
@@ -49826,7 +49742,7 @@ function installRuntimeLog(input) {
|
|
|
49826
49742
|
let descriptor;
|
|
49827
49743
|
let size = 0;
|
|
49828
49744
|
let atLineStart = true;
|
|
49829
|
-
const
|
|
49745
|
+
const open12 = () => {
|
|
49830
49746
|
descriptor = openSync(filePath, "a", 384);
|
|
49831
49747
|
chmodSync(filePath, 384);
|
|
49832
49748
|
size = fstatSync(descriptor).size;
|
|
@@ -49842,7 +49758,7 @@ function installRuntimeLog(input) {
|
|
|
49842
49758
|
try {
|
|
49843
49759
|
mkdirSync(logDirectory, { recursive: true, mode: 448 });
|
|
49844
49760
|
chmodSync(logDirectory, 448);
|
|
49845
|
-
|
|
49761
|
+
open12();
|
|
49846
49762
|
try {
|
|
49847
49763
|
chmodSync(`${filePath}.1`, 384);
|
|
49848
49764
|
} catch (error51) {
|
|
@@ -49862,12 +49778,12 @@ function installRuntimeLog(input) {
|
|
|
49862
49778
|
while (start < bytes.length && (bytes.readUInt8(start) & 192) === 128) start += 1;
|
|
49863
49779
|
bytes = bytes.subarray(start);
|
|
49864
49780
|
}
|
|
49865
|
-
if (descriptor === void 0)
|
|
49781
|
+
if (descriptor === void 0) open12();
|
|
49866
49782
|
if (size > 0 && size + bytes.length > maxBytes) {
|
|
49867
49783
|
close();
|
|
49868
49784
|
rmSync(`${filePath}.1`, { force: true });
|
|
49869
49785
|
renameSync(filePath, `${filePath}.1`);
|
|
49870
|
-
|
|
49786
|
+
open12();
|
|
49871
49787
|
prune();
|
|
49872
49788
|
}
|
|
49873
49789
|
if (descriptor === void 0) return;
|