@ian2018cs/agenthub 0.1.17 → 0.1.18
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/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -1135,6 +1135,15 @@ function handleCodexConnection(ws, userData) {
|
|
|
1135
1135
|
codexEnv.OPENAI_BASE_URL = process.env.OPENAI_BASE_URL;
|
|
1136
1136
|
}
|
|
1137
1137
|
|
|
1138
|
+
// Sync skills before starting codex (mirrors .claude/skills/ into .codex/skills/)
|
|
1139
|
+
if (userUuid) {
|
|
1140
|
+
try {
|
|
1141
|
+
await initCodexDirectories(userUuid);
|
|
1142
|
+
} catch (err) {
|
|
1143
|
+
console.error('[WARN] Failed to sync codex skills:', err.message);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1138
1147
|
codexProcess = pty.spawn(shell, shellArgs, {
|
|
1139
1148
|
name: 'xterm-256color',
|
|
1140
1149
|
cols: termCols,
|
|
@@ -42,6 +42,7 @@ export function getPublicPaths() {
|
|
|
42
42
|
/**
|
|
43
43
|
* Initialize codex home directory and config files for a user.
|
|
44
44
|
* Safe to call multiple times - only creates files that don't already exist.
|
|
45
|
+
* Note: skillsDir must exist before calling this function (created in initUserDirectories).
|
|
45
46
|
*/
|
|
46
47
|
export async function initCodexDirectories(userUuid) {
|
|
47
48
|
validateUuid(userUuid);
|
|
@@ -73,6 +74,56 @@ base_url = "${baseUrl}"
|
|
|
73
74
|
await fs.writeFile(authJsonPath, authJson, 'utf8');
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
// Sync skills symlinks into .codex/skills/:
|
|
78
|
+
// Mirror each enabled skill from .claude/skills/ into .codex/skills/<skill> (symlink).
|
|
79
|
+
// The .codex/skills/.system/ directory (Codex built-in skills) is preserved unchanged.
|
|
80
|
+
const codexSkillsDir = path.join(codexDir, 'skills');
|
|
81
|
+
await fs.mkdir(codexSkillsDir, { recursive: true });
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// Add symlinks for newly enabled skills
|
|
85
|
+
let claudeSkills = [];
|
|
86
|
+
try {
|
|
87
|
+
claudeSkills = await fs.readdir(paths.skillsDir);
|
|
88
|
+
} catch {
|
|
89
|
+
// skillsDir doesn't exist yet - nothing to sync
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const skillName of claudeSkills) {
|
|
93
|
+
const claudeSkillPath = path.join(paths.skillsDir, skillName);
|
|
94
|
+
const codexSkillLink = path.join(codexSkillsDir, skillName);
|
|
95
|
+
try {
|
|
96
|
+
await fs.lstat(codexSkillLink);
|
|
97
|
+
// Already exists - skip
|
|
98
|
+
} catch {
|
|
99
|
+
await fs.symlink(claudeSkillPath, codexSkillLink);
|
|
100
|
+
console.log(`[Codex] Synced skill: ${skillName}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Remove stale symlinks (skills removed from .claude/skills/)
|
|
105
|
+
const codexSkills = await fs.readdir(codexSkillsDir);
|
|
106
|
+
for (const skillName of codexSkills) {
|
|
107
|
+
if (skillName.startsWith('.')) continue; // preserve .system and other hidden dirs
|
|
108
|
+
const codexSkillLink = path.join(codexSkillsDir, skillName);
|
|
109
|
+
const claudeSkillPath = path.join(paths.skillsDir, skillName);
|
|
110
|
+
try {
|
|
111
|
+
await fs.access(claudeSkillPath);
|
|
112
|
+
} catch {
|
|
113
|
+
// No longer in .claude/skills/ - remove if it's a symlink
|
|
114
|
+
try {
|
|
115
|
+
const stat = await fs.lstat(codexSkillLink);
|
|
116
|
+
if (stat.isSymbolicLink()) {
|
|
117
|
+
await fs.unlink(codexSkillLink);
|
|
118
|
+
console.log(`[Codex] Removed stale skill symlink: ${skillName}`);
|
|
119
|
+
}
|
|
120
|
+
} catch {}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.log(`[Codex] Skills sync warning: ${err.message}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
76
127
|
console.log(`[Codex] Initialized codex directories for user ${userUuid}`);
|
|
77
128
|
return codexDir;
|
|
78
129
|
}
|
|
@@ -88,18 +139,18 @@ export async function initUserDirectories(userUuid) {
|
|
|
88
139
|
await fs.mkdir(paths.claudeDir, { recursive: true });
|
|
89
140
|
await fs.mkdir(paths.projectsDir, { recursive: true });
|
|
90
141
|
|
|
91
|
-
// Initialize codex home directory with config files
|
|
92
|
-
await initCodexDirectories(userUuid);
|
|
93
|
-
|
|
94
142
|
// Create projects directory for Claude session files
|
|
95
143
|
const projectsDir = path.join(paths.claudeDir, 'projects');
|
|
96
144
|
await fs.mkdir(projectsDir, { recursive: true });
|
|
97
145
|
|
|
98
|
-
// Create skills directories
|
|
146
|
+
// Create skills directories (must be before initCodexDirectories to allow skills symlink)
|
|
99
147
|
await fs.mkdir(paths.skillsDir, { recursive: true });
|
|
100
148
|
await fs.mkdir(paths.skillsImportDir, { recursive: true });
|
|
101
149
|
await fs.mkdir(paths.skillsRepoDir, { recursive: true });
|
|
102
150
|
|
|
151
|
+
// Initialize codex home directory with config files (after skillsDir exists for symlink)
|
|
152
|
+
await initCodexDirectories(userUuid);
|
|
153
|
+
|
|
103
154
|
// Create .claude.json with hasCompletedOnboarding=true
|
|
104
155
|
const claudeJsonPath = path.join(paths.claudeDir, '.claude.json');
|
|
105
156
|
const claudeConfig = {
|