Skip to content

Commit 4d8b74a

Browse files
authored
fix: CLI handle plugin dependencies / trusdb (elizaOS#3737)
* lower logging * add json5 * bump lockfile for json5 * allow Plugin to store actual npm name * allow character file to be json5, adjust logging, handle improper/failed to load plugins better * remove wrongly added plugin * properly handle paths with spaces * audit fix * bump turbo * don't await on async returns, note * attempt ci typing fix * try what claude says to fix CI * try what claude says to fix CI * try what claude says to fix CI * claude ci fix * go back to any * cursor attempt * cursor attempt * clean up output * sync with the other concurrent build better * sync lockfile * pnpm (biome) format, mainly import type tweaks * favor local paths for consistency * move vitest * remove tsup/readline/ws, include @jest/globals because useESM is true in jest config * move tsup to dev deps * bump lockfile * handle dependencies/handle trustdb
1 parent 3be70e4 commit 4d8b74a

File tree

1 file changed

+86
-30
lines changed

1 file changed

+86
-30
lines changed

packages/cli/index.js

+86-30
Original file line numberDiff line numberDiff line change
@@ -79,40 +79,88 @@ pluginsCmd
7979

8080
// ensure prefix
8181
const pluginName = '@elizaos-plugins/' + plugin.replace(/^@elizaos-plugins\//, '')
82+
const namePart = pluginName.replace(/^@elizaos-plugins\//, '')
83+
const elizaOSroot = pathUtil.resolve(__dirname, '../..')
8284

83-
const repoData = plugins[pluginName]?.split(':')
84-
if (!repoData) {
85-
console.error('Plugin', plugin, 'not found')
86-
return
87-
}
88-
// repo type
89-
if (repoData[0] !== 'github') {
90-
console.error('Plugin', plugin, 'uses', repoData[0], ' but this utility currently only support github')
91-
return
85+
let repo = ''
86+
if (namePart === 'plugin-trustdb') {
87+
repo = 'elizaos-plugins/plugin-trustdb'
88+
} else {
89+
const repoData = plugins[pluginName]?.split(':')
90+
if (!repoData) {
91+
console.error('Plugin', plugin, 'not found')
92+
return
93+
}
94+
// repo type
95+
if (repoData[0] !== 'github') {
96+
console.error('Plugin', plugin, 'uses', repoData[0], ' but this utility only currently support github')
97+
return
98+
}
99+
repo = repoData[1]
92100
}
93-
const parts = repoData[1].split('/')
94-
const elizaOSroot = pathUtil.resolve(__dirname, '../..')
95-
const pkgPath = elizaOSroot + '/packages/' + parts[1]
101+
const pkgPath = elizaOSroot + '/packages/' + namePart
96102

97103
// add to packages
98-
if (!fs.existsSync(pkgPath)) {
104+
if (!fs.existsSync(pkgPath + '/package.json')) {
99105
// clone it
100-
console.log('cloning', parts[1], 'to', pkgPath)
101-
const gitOutput = execSync('git clone https://github.com/' + repoData[1] + ' "' + pkgPath + '"', { stdio: 'pipe' }).toString().trim();
106+
console.log('cloning', namePart, 'to', pkgPath)
107+
const gitOutput = execSync('git clone https://github.com/' + repo + ' "' + pkgPath + '"', { stdio: 'pipe' }).toString().trim();
108+
// submodule init & update?
102109
}
103110

104-
// add core to plugin
105-
// # pnpm add @elizaos/core@workspace:* --filter ./packages/client-twitter
106-
console.log('Making sure plugin has access to @elizaos/core')
107-
const pluginAddCoreOutput = execSync('pnpm add @elizaos/core@workspace:* --filter ./packages/' + parts[1], { cwd: elizaOSroot, stdio: 'pipe' }).toString().trim();
111+
// we need to check for dependencies
108112

109113
// Read the current package.json
110114
const packageJsonPath = pkgPath + '/package.json'
111115
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
112116

113-
if (packageJson.name !== '@elizaos-plugins/' + parts[1]) {
117+
const updateDependencies = (deps) => {
118+
if (!deps) return false
119+
let changed = false
120+
const okPackages = ['@elizaos/client-direct', '@elizaos/core', '@elizaos/plugin-bootstrap']
121+
for (const dep in deps) {
122+
if (okPackages.indexOf(dep) !== -1) continue // skip these, they're fine
123+
// do we want/need to perserve local packages like core?
124+
if (dep.startsWith("@elizaos/")) {
125+
const newDep = dep.replace("@elizaos/", "@elizaos-plugins/")
126+
deps[newDep] = deps[dep]
127+
delete deps[dep]
128+
changed = true
129+
}
130+
}
131+
return changed
132+
}
133+
134+
// normalize @elizaos => @elizaos-plugins
135+
if (updateDependencies(packageJson.dependencies)) {
136+
console.log('updating plugin\'s package.json to not use @elizos/ for dependencies')
137+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n")
138+
// I don't think will cause the lockfile from getting out of date
139+
}
140+
//console.log('packageJson', packageJson.dependencies)
141+
for(const d in packageJson.dependencies) {
142+
if (d.match(/@elizaos-plugins/)) {
143+
// do we have this plugin?
144+
console.log('attempting installation of dependency', d)
145+
try {
146+
const pluginAddDepOutput = execSync('npx elizaos plugins add ' + d, { cwd: elizaOSroot, stdio: 'pipe' }).toString().trim();
147+
//console.log('pluginAddDepOutput', pluginAddDepOutput)
148+
} catch (e) {
149+
console.error('pluginAddDepOutput error', e)
150+
}
151+
}
152+
}
153+
154+
// add core to plugin
155+
// # pnpm add @elizaos/core@workspace:* --filter ./packages/client-twitter
156+
157+
// ok this can be an issue if it's referencing a plugin it couldn't be
158+
console.log('Making sure plugin has access to @elizaos/core')
159+
const pluginAddCoreOutput = execSync('pnpm add @elizaos/core@workspace:* --filter ./packages/' + namePart, { cwd: elizaOSroot, stdio: 'pipe' }).toString().trim();
160+
161+
if (packageJson.name !== '@elizaos-plugins/' + namePart) {
114162
// Update the name field
115-
packageJson.name = '@elizaos-plugins/' + parts[1]
163+
packageJson.name = '@elizaos-plugins/' + namePart
116164
console.log('Updating plugins package.json name to', packageJson.name)
117165

118166
// Write the updated package.json back to disk
@@ -148,20 +196,28 @@ pluginsCmd
148196
.action(async (plugin, opts) => {
149197
// ensure prefix
150198
const pluginName = '@elizaos-plugins/' + plugin.replace(/^@elizaos-plugins\//, '')
199+
const namePart = pluginName.replace(/^@elizaos-plugins\//, '')
200+
const elizaOSroot = pathUtil.resolve(__dirname, '../..')
201+
const pkgPath = elizaOSroot + '/packages/' + namePart
151202
const plugins = await getPlugins()
152-
//console.log('loaded', plugins.length, plugins)
153-
const repoData = plugins[pluginName]?.split(':')
154-
if (!repoData) {
155-
console.error('Plugin', pluginName, 'not found')
156-
return
203+
204+
let repo = ''
205+
if (namePart === 'plugin-trustdb') {
206+
repo = 'elizaos-plugins/plugin-trustdb'
207+
} else {
208+
//console.log('loaded', plugins.length, plugins)
209+
const repoData = plugins[pluginName]?.split(':')
210+
if (!repoData) {
211+
console.error('Plugin', pluginName, 'not found')
212+
return
213+
}
214+
const parts = repoData[1].split('/')
215+
repo = parts[1]
157216
}
158-
const parts = repoData[1].split('/')
159-
const elizaOSroot = pathUtil.resolve(__dirname, '../..')
160-
const pkgPath = elizaOSroot + '/packages/' + parts[1]
161217

162218
// remove from agent: pnpm remove some-plugin --filter ./agent
163219
try {
164-
console.log('Removing plugin from agent')
220+
console.log('Removing', pluginName, 'from agent')
165221
const pluginRemoveAgentOutput = execSync('pnpm remove ' + pluginName + ' --filter ./agent', { cwd: elizaOSroot, stdio: 'pipe' }).toString().trim();
166222
} catch (e) {
167223
console.error('removal from agent, error', e)

0 commit comments

Comments
 (0)