codexapp 0.1.57 → 0.1.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Codex Web Local</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-6_XI7mdm.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DDedrRjM.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body class="bg-slate-950">
|
|
11
11
|
<div id="app"></div>
|
package/dist-cli/index.js
CHANGED
|
@@ -430,6 +430,8 @@ var SKILLS_SYNC_MANIFEST_PATH = "installed-skills.json";
|
|
|
430
430
|
var SYNC_UPSTREAM_SKILLS_OWNER = "OpenClawAndroid";
|
|
431
431
|
var SYNC_UPSTREAM_SKILLS_REPO = "skills";
|
|
432
432
|
var PRIVATE_SYNC_BRANCH = "main";
|
|
433
|
+
var PUBLIC_UPSTREAM_BRANCH_ANDROID = "android";
|
|
434
|
+
var PUBLIC_UPSTREAM_BRANCH_DEFAULT = "main";
|
|
433
435
|
var HUB_SKILLS_OWNER = "openclaw";
|
|
434
436
|
var HUB_SKILLS_REPO = "skills";
|
|
435
437
|
var startupSkillsSyncInitialized = false;
|
|
@@ -559,7 +561,7 @@ function isAndroidLikeRuntime() {
|
|
|
559
561
|
return proot.length > 0;
|
|
560
562
|
}
|
|
561
563
|
function getPreferredPublicUpstreamBranch() {
|
|
562
|
-
return isAndroidLikeRuntime() ?
|
|
564
|
+
return isAndroidLikeRuntime() ? PUBLIC_UPSTREAM_BRANCH_ANDROID : PUBLIC_UPSTREAM_BRANCH_DEFAULT;
|
|
563
565
|
}
|
|
564
566
|
function isUpstreamSkillsRepo(repoOwner, repoName) {
|
|
565
567
|
return repoOwner.toLowerCase() === SYNC_UPSTREAM_SKILLS_OWNER.toLowerCase() && repoName.toLowerCase() === SYNC_UPSTREAM_SKILLS_REPO.toLowerCase();
|
|
@@ -824,25 +826,50 @@ async function syncInstalledSkillsFolderToRepo(token, repoOwner, repoName, _inst
|
|
|
824
826
|
async function pushWithNonFastForwardRetry(repoDir2, branch2) {
|
|
825
827
|
const maxAttempts = 3;
|
|
826
828
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
829
|
+
await runCommand("git", ["fetch", "origin"], { cwd: repoDir2 });
|
|
830
|
+
let hasLatestRemote = false;
|
|
831
|
+
try {
|
|
832
|
+
await runCommand("git", ["merge-base", "--is-ancestor", `origin/${branch2}`, "HEAD"], { cwd: repoDir2 });
|
|
833
|
+
hasLatestRemote = true;
|
|
834
|
+
} catch {
|
|
835
|
+
hasLatestRemote = false;
|
|
836
|
+
}
|
|
837
|
+
if (!hasLatestRemote) {
|
|
838
|
+
try {
|
|
839
|
+
await runCommand("git", ["pull", "--no-rebase", "--no-ff", "origin", branch2], { cwd: repoDir2 });
|
|
840
|
+
} catch {
|
|
841
|
+
await resolveMergeConflictsByNewerCommit(repoDir2, branch2);
|
|
842
|
+
}
|
|
843
|
+
await runCommand("git", ["add", "."], { cwd: repoDir2 });
|
|
844
|
+
const statusAfterReconcile = (await runCommandWithOutput("git", ["status", "--porcelain"], { cwd: repoDir2 })).trim();
|
|
845
|
+
if (statusAfterReconcile) {
|
|
846
|
+
await runCommand("git", ["commit", "-m", "Reconcile skills sync before push retry"], { cwd: repoDir2 });
|
|
847
|
+
}
|
|
848
|
+
}
|
|
827
849
|
try {
|
|
828
850
|
await runCommand("git", ["push", "origin", `HEAD:${branch2}`], { cwd: repoDir2 });
|
|
851
|
+
const state = await readSkillsSyncState();
|
|
852
|
+
const pushedHead = await runCommandWithOutput("git", ["rev-parse", "HEAD"], { cwd: repoDir2 });
|
|
853
|
+
await writeSkillsSyncState({
|
|
854
|
+
...state,
|
|
855
|
+
lastPushCommitSha: pushedHead.trim(),
|
|
856
|
+
lastSyncAttemptCount: attempt,
|
|
857
|
+
lastSyncError: "",
|
|
858
|
+
lastSyncAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
859
|
+
});
|
|
829
860
|
return;
|
|
830
861
|
} catch (error) {
|
|
831
862
|
if (!isNonFastForwardPushError(error) || attempt >= maxAttempts) {
|
|
863
|
+
const state = await readSkillsSyncState();
|
|
864
|
+
await writeSkillsSyncState({
|
|
865
|
+
...state,
|
|
866
|
+
lastSyncAttemptCount: attempt,
|
|
867
|
+
lastSyncError: getErrorMessage(error, "push failed"),
|
|
868
|
+
lastSyncAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
869
|
+
});
|
|
832
870
|
throw error;
|
|
833
871
|
}
|
|
834
872
|
}
|
|
835
|
-
await runCommand("git", ["fetch", "origin"], { cwd: repoDir2 });
|
|
836
|
-
try {
|
|
837
|
-
await runCommand("git", ["pull", "--no-rebase", "--no-ff", "origin", branch2], { cwd: repoDir2 });
|
|
838
|
-
} catch {
|
|
839
|
-
await resolveMergeConflictsByNewerCommit(repoDir2, branch2);
|
|
840
|
-
}
|
|
841
|
-
await runCommand("git", ["add", "."], { cwd: repoDir2 });
|
|
842
|
-
const statusAfterReconcile = (await runCommandWithOutput("git", ["status", "--porcelain"], { cwd: repoDir2 })).trim();
|
|
843
|
-
if (statusAfterReconcile) {
|
|
844
|
-
await runCommand("git", ["commit", "-m", "Reconcile skills sync before push retry"], { cwd: repoDir2 });
|
|
845
|
-
}
|
|
846
873
|
}
|
|
847
874
|
throw new Error("Failed to push after non-fast-forward retries");
|
|
848
875
|
}
|
|
@@ -963,9 +990,8 @@ async function ensureCodexAgentsSymlinkToSkillsAgents() {
|
|
|
963
990
|
}
|
|
964
991
|
await symlink(relativeTarget, codexAgentsPath);
|
|
965
992
|
}
|
|
966
|
-
async function
|
|
967
|
-
if (
|
|
968
|
-
startupSkillsSyncInitialized = true;
|
|
993
|
+
async function runSkillsSyncStartup(appServer) {
|
|
994
|
+
if (startupSyncStatus.inProgress) return;
|
|
969
995
|
startupSyncStatus.inProgress = true;
|
|
970
996
|
startupSyncStatus.lastRunAtIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
971
997
|
startupSyncStatus.lastError = "";
|
|
@@ -1016,6 +1042,11 @@ async function initializeSkillsSyncOnStartup(appServer) {
|
|
|
1016
1042
|
startupSyncStatus.inProgress = false;
|
|
1017
1043
|
}
|
|
1018
1044
|
}
|
|
1045
|
+
async function initializeSkillsSyncOnStartup(appServer) {
|
|
1046
|
+
if (startupSkillsSyncInitialized) return;
|
|
1047
|
+
startupSkillsSyncInitialized = true;
|
|
1048
|
+
await runSkillsSyncStartup(appServer);
|
|
1049
|
+
}
|
|
1019
1050
|
async function finalizeGithubLoginAndSync(token, username, appServer) {
|
|
1020
1051
|
const repoName = DEFAULT_SKILLS_SYNC_REPO_NAME;
|
|
1021
1052
|
await ensurePrivateForkFromUpstream(token, username, repoName);
|
|
@@ -1106,6 +1137,13 @@ async function handleSkillsRoutes(req, res, url, context) {
|
|
|
1106
1137
|
repoOwner: state.repoOwner ?? "",
|
|
1107
1138
|
repoName: state.repoName ?? "",
|
|
1108
1139
|
configured: Boolean(state.githubToken && state.repoOwner && state.repoName),
|
|
1140
|
+
telemetry: {
|
|
1141
|
+
lastPullCommitSha: state.lastPullCommitSha ?? "",
|
|
1142
|
+
lastPushCommitSha: state.lastPushCommitSha ?? "",
|
|
1143
|
+
lastSyncAttemptCount: state.lastSyncAttemptCount ?? 0,
|
|
1144
|
+
lastSyncError: state.lastSyncError ?? "",
|
|
1145
|
+
lastSyncAtIso: state.lastSyncAtIso ?? ""
|
|
1146
|
+
},
|
|
1109
1147
|
startup: {
|
|
1110
1148
|
inProgress: startupSyncStatus.inProgress,
|
|
1111
1149
|
mode: startupSyncStatus.mode,
|
|
@@ -1203,6 +1241,15 @@ async function handleSkillsRoutes(req, res, url, context) {
|
|
|
1203
1241
|
}
|
|
1204
1242
|
return true;
|
|
1205
1243
|
}
|
|
1244
|
+
if (req.method === "POST" && url.pathname === "/codex-api/skills-sync/startup-sync") {
|
|
1245
|
+
try {
|
|
1246
|
+
await runSkillsSyncStartup(appServer);
|
|
1247
|
+
setJson(res, 200, { ok: true });
|
|
1248
|
+
} catch (error) {
|
|
1249
|
+
setJson(res, 502, { error: getErrorMessage(error, "Failed to run startup sync") });
|
|
1250
|
+
}
|
|
1251
|
+
return true;
|
|
1252
|
+
}
|
|
1206
1253
|
if (req.method === "POST" && url.pathname === "/codex-api/skills-sync/pull") {
|
|
1207
1254
|
try {
|
|
1208
1255
|
const state = await readSkillsSyncState();
|
|
@@ -1234,15 +1281,20 @@ async function handleSkillsRoutes(req, res, url, context) {
|
|
|
1234
1281
|
const localDir = await detectUserSkillsDir(appServer);
|
|
1235
1282
|
await pullInstalledSkillsFolderFromRepo(state.githubToken, state.repoOwner, state.repoName);
|
|
1236
1283
|
const localSkills = await scanInstalledSkillsFromDisk();
|
|
1284
|
+
const missingAfterPull = [];
|
|
1237
1285
|
for (const skill of remote) {
|
|
1238
1286
|
const owner = skill.owner || uniqueOwnerByName.get(skill.name) || "";
|
|
1239
1287
|
if (!owner) continue;
|
|
1240
1288
|
if (!localSkills.has(skill.name)) {
|
|
1289
|
+
missingAfterPull.push(`${owner}/${skill.name}`);
|
|
1241
1290
|
continue;
|
|
1242
1291
|
}
|
|
1243
1292
|
const skillPath = join2(localDir, skill.name);
|
|
1244
1293
|
await appServer.rpc("skills/config/write", { path: skillPath, enabled: skill.enabled });
|
|
1245
1294
|
}
|
|
1295
|
+
if (missingAfterPull.length > 0) {
|
|
1296
|
+
throw new Error(`Missing skill folders after pull: ${missingAfterPull.join(", ")}`);
|
|
1297
|
+
}
|
|
1246
1298
|
const remoteNames = new Set(remote.map((row) => row.name));
|
|
1247
1299
|
for (const [name, localInfo] of localSkills.entries()) {
|
|
1248
1300
|
if (!remoteNames.has(name)) {
|
|
@@ -1254,7 +1306,15 @@ async function handleSkillsRoutes(req, res, url, context) {
|
|
|
1254
1306
|
const owner = item.owner || uniqueOwnerByName.get(item.name) || "";
|
|
1255
1307
|
if (owner) nextOwners[item.name] = owner;
|
|
1256
1308
|
}
|
|
1257
|
-
await
|
|
1309
|
+
const pulledHead = await runCommandWithOutput("git", ["rev-parse", "HEAD"], { cwd: getSkillsInstallDir() }).catch(() => "");
|
|
1310
|
+
await writeSkillsSyncState({
|
|
1311
|
+
...state,
|
|
1312
|
+
installedOwners: nextOwners,
|
|
1313
|
+
lastPullCommitSha: pulledHead.trim(),
|
|
1314
|
+
lastSyncAttemptCount: 1,
|
|
1315
|
+
lastSyncError: "",
|
|
1316
|
+
lastSyncAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
1317
|
+
});
|
|
1258
1318
|
try {
|
|
1259
1319
|
await appServer.rpc("skills/list", { forceReload: true });
|
|
1260
1320
|
} catch {
|