mio-agent-runtime 0.5.7 → 0.5.9

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 CHANGED
@@ -53,6 +53,7 @@ Restart your agent after install. That's it.
53
53
  |---------|-------------|
54
54
  | `mio init` | Create `~/.mio-intelligence` and default config |
55
55
  | `mio install <host>` | Wire MCP + rules + observer into a host |
56
+ | `mio uninstall <host>` | Remove Mio MCP, rules, approvals, and observer from a host |
56
57
  | `mio mcp` | Start MCP server (stdio, for agent integration) |
57
58
  | `mio status` | Show runtime state, adapter status, observer PID |
58
59
  | `mio agents` | List installed hosts |
@@ -237,6 +238,7 @@ WorkBuddy ─┘ + Observer ......... automatic data collection
237
238
  | >= 0.3.6 | Passive observation + seamless read/write |
238
239
  | >= 0.5.0 | Idea generation + evolution suggestions |
239
240
  | >= 0.5.6 | Rewritten documentation |
241
+ | >= 0.5.9 | `mio uninstall <host>` command |
240
242
 
241
243
  ---
242
244
 
package/adapters/codex.js CHANGED
@@ -119,4 +119,16 @@ function install({ node, serverScript, home, workspace }) {
119
119
  }
120
120
  }
121
121
 
122
- module.exports = { configPath, isInstalled, install, restartWarningMessage }
122
+ function uninstall({ serverScript }) {
123
+ const target = configPath()
124
+ if (!fs.existsSync(target) || !fs.readFileSync(target, 'utf8').includes(SERVER_SECTION)) {
125
+ return { changed: false, configPath: target, message: 'Codex Mio MCP not installed.' }
126
+ }
127
+ const backup = target + '.bak-mio-' + Date.now()
128
+ fs.copyFileSync(target, backup)
129
+ const toml = stripMioSection(fs.readFileSync(target, 'utf8'))
130
+ fs.writeFileSync(target, toml, 'utf8')
131
+ return { changed: true, configPath: target, backup, message: 'Codex Mio MCP removed. Restart Codex to apply.' }
132
+ }
133
+
134
+ module.exports = { configPath, isInstalled, install, uninstall, restartWarningMessage }
@@ -119,4 +119,22 @@ function isHermesOnPath() {
119
119
  }
120
120
  }
121
121
 
122
- module.exports = { hermesBin, isInstalled, install }
122
+ function uninstall({ serverScript }) {
123
+ if (!hermesBin() && !isHermesOnPath()) {
124
+ return { changed: false, message: 'Hermes binary not found. Nothing to remove.', configPath: null }
125
+ }
126
+ if (!isInstalled()) {
127
+ return { changed: false, message: 'Hermes Mio MCP not installed.', configPath: null }
128
+ }
129
+ runHermes(['mcp', 'remove', SERVER_NAME])
130
+ const removed = !isInstalled()
131
+ return {
132
+ changed: removed,
133
+ configPath: null,
134
+ message: removed
135
+ ? 'Hermes Mio MCP removed. Start a new Hermes session to apply.'
136
+ : 'Hermes mcp remove returned but Mio is still present. Run `hermes mcp remove ' + SERVER_NAME + '` manually.'
137
+ }
138
+ }
139
+
140
+ module.exports = { hermesBin, isInstalled, install, uninstall }
@@ -173,4 +173,43 @@ function install({ node, serverScript, home, workspace, project }) {
173
173
  }
174
174
  }
175
175
 
176
- module.exports = { configPath, globalInstructionsPath, isInstalled, install, configNeedsRepair, restartWarningMessage }
176
+ function removeGlobalInstructions() {
177
+ const target = globalInstructionsPath()
178
+ if (!fs.existsSync(target)) return { changed: false, target, backup: null }
179
+ const content = fs.readFileSync(target, 'utf8')
180
+ const start = content.indexOf(INSTRUCTIONS_BEGIN)
181
+ if (start === -1) return { changed: false, target, backup: null }
182
+ const end = content.indexOf(INSTRUCTIONS_END, start)
183
+ let next = end === -1 ? content.slice(0, start) : content.slice(0, start) + content.slice(end + INSTRUCTIONS_END.length)
184
+ next = next.trimEnd() + '\n'
185
+ const backup = target + '.bak-mio-' + Date.now()
186
+ fs.copyFileSync(target, backup)
187
+ fs.writeFileSync(target, next, 'utf8')
188
+ return { changed: true, target, backup }
189
+ }
190
+
191
+ function uninstall({ serverScript }) {
192
+ const target = configPath()
193
+ const config = readConfig()
194
+ const hadMcp = Boolean(config && config.mcp && config.mcp['mio-intelligence'])
195
+ let configChanged = false
196
+ let backup = null
197
+ if (hadMcp) {
198
+ backup = target + '.bak-mio-' + Date.now()
199
+ if (fs.existsSync(target)) fs.copyFileSync(target, backup)
200
+ delete config.mcp['mio-intelligence']
201
+ if (Object.keys(config.mcp).length === 0) delete config.mcp
202
+ fs.mkdirSync(path.dirname(target), { recursive: true })
203
+ fs.writeFileSync(target, JSON.stringify(config, null, 2) + '\n', 'utf8')
204
+ configChanged = true
205
+ }
206
+ const instr = removeGlobalInstructions()
207
+ const changed = configChanged || instr.changed
208
+ if (!changed) return { changed: false, configPath: target, message: 'OpenCode Mio MCP not installed.' }
209
+ let message = 'OpenCode Mio MCP removed'
210
+ const restartHint = restartWarningMessage()
211
+ if (restartHint) message += '. ' + restartHint
212
+ return { changed: true, configPath: target, globalInstructionsPath: instr.target, backup, message }
213
+ }
214
+
215
+ module.exports = { configPath, globalInstructionsPath, isInstalled, install, uninstall, configNeedsRepair, restartWarningMessage }
@@ -193,4 +193,50 @@ function install({ node, serverScript, home, workspace, project }) {
193
193
  }
194
194
  }
195
195
 
196
- module.exports = { configDir, configPath, approvalsPath, memoryRulesPath, projectInstructionsPath, approvalKey, isInstalled, install }
196
+ function removeBlock(target) {
197
+ if (!fs.existsSync(target)) return { changed: false, target, backup: null }
198
+ const content = fs.readFileSync(target, 'utf8')
199
+ const start = content.indexOf(MEMORY_BEGIN)
200
+ if (start === -1) return { changed: false, target, backup: null }
201
+ const end = content.indexOf(MEMORY_END, start)
202
+ let next = end === -1 ? content.slice(0, start) : content.slice(0, start) + content.slice(end + MEMORY_END.length)
203
+ next = next.trimEnd() + '\n'
204
+ const backup = target + '.bak-mio-' + Date.now()
205
+ fs.copyFileSync(target, backup)
206
+ fs.writeFileSync(target, next, 'utf8')
207
+ return { changed: true, target, backup }
208
+ }
209
+
210
+ function uninstall({ serverScript, workspace }) {
211
+ const target = configPath()
212
+ const config = readJson(target)
213
+ const entry = config && config.mcpServers && config.mcpServers['mio-intelligence']
214
+ if (!entry) return { changed: false, configPath: target, message: 'WorkBuddy Mio MCP not installed.' }
215
+ const backup = target + '.bak-mio-' + Date.now()
216
+ if (fs.existsSync(target)) fs.copyFileSync(target, backup)
217
+ delete config.mcpServers['mio-intelligence']
218
+ fs.mkdirSync(path.dirname(target), { recursive: true })
219
+ fs.writeFileSync(target, JSON.stringify(config, null, 2) + '\n', 'utf8')
220
+ const approvalsTarget = approvalsPath()
221
+ const approvals = readJson(approvalsTarget) || {}
222
+ const key = approvalKey('mio-intelligence', entry)
223
+ if (approvals[key]) {
224
+ delete approvals[key]
225
+ fs.writeFileSync(approvalsTarget, JSON.stringify(approvals, null, 2) + '\n', 'utf8')
226
+ }
227
+ const userRules = removeBlock(memoryRulesPath())
228
+ let projectRules = null
229
+ const workspaceDir = workspace || process.cwd()
230
+ if (workspaceDir && path.isAbsolute(workspaceDir)) projectRules = removeBlock(projectInstructionsPath(workspaceDir))
231
+ const changed = userRules.changed || Boolean(projectRules && projectRules.changed)
232
+ return {
233
+ changed: true,
234
+ configPath: target,
235
+ approvalsPath: approvalsTarget,
236
+ memoryRulesPath: userRules.target,
237
+ projectInstructionsPath: projectRules ? projectRules.target : null,
238
+ message: 'WorkBuddy Mio MCP removed, approval revoked, and Mio rules stripped from CODEBUDDY.md and workspace AGENTS.md. Restart WorkBuddy to apply.'
239
+ }
240
+ }
241
+
242
+ module.exports = { configDir, configPath, approvalsPath, memoryRulesPath, projectInstructionsPath, approvalKey, isInstalled, install, uninstall }
package/bin/mio.js CHANGED
@@ -45,6 +45,11 @@ function jsonOrText(payload, useJson) {
45
45
  return payload
46
46
  }
47
47
 
48
+ function versionCommand() {
49
+ const pkg = require(path.resolve(__dirname, '..', 'package.json'))
50
+ console.log(pkg.version)
51
+ }
52
+
48
53
  function initCommand() {
49
54
  ensureHome()
50
55
  const config = readConfig()
@@ -214,13 +219,58 @@ function observeCommand(args) {
214
219
  observer.startForeground(MIO_HOME)
215
220
  }
216
221
 
222
+ function uninstallCommand(host, useJson) {
223
+ if (!host) {
224
+ console.error('Usage: mio uninstall <codex|opencode|workbuddy|hermes>')
225
+ process.exitCode = 1
226
+ return
227
+ }
228
+ const adapter = adapters[host]
229
+ if (!adapter) {
230
+ console.error(`Unknown host: ${host}`)
231
+ process.exitCode = 1
232
+ return
233
+ }
234
+ let result
235
+ try {
236
+ result = adapter.uninstall({
237
+ node: process.execPath,
238
+ serverScript: SERVER_SCRIPT,
239
+ home: MIO_HOME,
240
+ workspace: process.cwd(),
241
+ })
242
+ } catch (error) {
243
+ console.error(`Failed to uninstall ${host}: ${error.message || error}`)
244
+ process.exitCode = 1
245
+ return
246
+ }
247
+ if (result.changed) {
248
+ const config = readConfig()
249
+ if (config.agents && config.agents[host]) {
250
+ delete config.agents[host]
251
+ writeConfig(config)
252
+ }
253
+ const remaining = Object.keys(config.agents || {}).length
254
+ if (remaining === 0 && observer.isRunning(MIO_HOME)) {
255
+ observer.stopBackground(MIO_HOME)
256
+ }
257
+ }
258
+ if (useJson) {
259
+ jsonOrText(result, true)
260
+ return
261
+ }
262
+ console.log(result.message || `${host} adapter removed.`)
263
+ }
264
+
217
265
  function help() {
218
266
  console.log(`Mio Agent Runtime CLI
219
267
 
220
268
  Usage:
269
+ mio version Show installed Mio version
221
270
  mio init Initialize MIO_HOME
222
271
  mio mcp Start Mio MCP server (stdio)
223
272
  mio install <host> Install Mio into a host (codex|opencode|workbuddy|hermes)
273
+ mio uninstall <host> Remove Mio from a host
224
274
  mio status Show runtime and adapter status
225
275
  mio agents List installed agents
226
276
  mio observe Watch WorkBuddy transcripts and auto-ingest task outcomes
@@ -238,12 +288,17 @@ function main() {
238
288
  const command = args[0] || 'help'
239
289
 
240
290
  switch (command) {
291
+ case 'version':
292
+ case '--version':
293
+ return versionCommand()
241
294
  case 'init':
242
295
  return initCommand()
243
296
  case 'mcp':
244
297
  return mcpCommand()
245
298
  case 'install':
246
299
  return installCommand(args[1], useJson)
300
+ case 'uninstall':
301
+ return uninstallCommand(args[1], useJson)
247
302
  case 'status':
248
303
  return statusCommand(useJson)
249
304
  case 'agents':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mio-agent-runtime",
3
- "version": "0.5.7",
3
+ "version": "0.5.9",
4
4
  "description": "Mio Agent Runtime installer and MCP intelligence layer",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",