mio-agent-runtime 0.3.12 → 0.3.14
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/adapters/codex.js +105 -61
- package/adapters/opencode.js +16 -2
- package/package.json +1 -1
package/adapters/codex.js
CHANGED
|
@@ -1,62 +1,106 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const fs = require('fs')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const os = require('os')
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const os = require('os')
|
|
6
|
+
|
|
7
|
+
const SERVER_SECTION = '[mcp_servers.mio-intelligence]'
|
|
8
|
+
const ENV_SECTION = '[mcp_servers.mio-intelligence.env]'
|
|
9
|
+
|
|
10
|
+
function configPath() {
|
|
11
|
+
return path.join(os.homedir(), '.codex', 'config.toml')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isInstalled() {
|
|
15
|
+
const target = configPath()
|
|
16
|
+
if (!fs.existsSync(target)) return false
|
|
17
|
+
return fs.readFileSync(target, 'utf8').includes(SERVER_SECTION)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Legacy installs pointed args at the worktree copy of the server
|
|
21
|
+
// (server/mio-intelligence-mcp/index.js) instead of this package's copy
|
|
22
|
+
// (server/mio-intelligence-mcp/index.js). Detect staleness by comparing the
|
|
23
|
+
// configured args path with the server path this package ships.
|
|
24
|
+
function configNeedsRepair(serverScript) {
|
|
25
|
+
const target = configPath()
|
|
26
|
+
if (!fs.existsSync(target)) return false
|
|
27
|
+
try {
|
|
28
|
+
const src = fs.readFileSync(target, 'utf8')
|
|
29
|
+
if (!src.includes(SERVER_SECTION)) return false
|
|
30
|
+
const needle = serverScript.replace(/\\/g, '/').toLowerCase()
|
|
31
|
+
return !src.replace(/\\/g, '/').toLowerCase().includes(needle)
|
|
32
|
+
} catch (_) {
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function stripMioSection(toml) {
|
|
38
|
+
const lines = toml.replace(/\r\n/g, '\n').split('\n')
|
|
39
|
+
const out = []
|
|
40
|
+
let skipping = false
|
|
41
|
+
for (const line of lines) {
|
|
42
|
+
const trimmed = line.trim()
|
|
43
|
+
if (trimmed === SERVER_SECTION || trimmed === ENV_SECTION) {
|
|
44
|
+
skipping = true
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
if (skipping && /^\[.*\]$/.test(trimmed)) {
|
|
48
|
+
skipping = false
|
|
49
|
+
}
|
|
50
|
+
if (!skipping) out.push(line)
|
|
51
|
+
}
|
|
52
|
+
return out.join('\n').replace(/\n{3,}/g, '\n\n').trimEnd() + '\n'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function install({ node, serverScript, home, workspace }) {
|
|
56
|
+
const target = configPath()
|
|
57
|
+
const backup = `${target}.bak-mio-${Date.now()}`
|
|
58
|
+
const installed = isInstalled()
|
|
59
|
+
if (installed && !configNeedsRepair(serverScript)) {
|
|
60
|
+
return {
|
|
61
|
+
changed: false,
|
|
62
|
+
configPath: target,
|
|
63
|
+
message: 'Codex Mio MCP already installed.',
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (fs.existsSync(target)) {
|
|
68
|
+
fs.copyFileSync(target, backup)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const context = JSON.stringify({
|
|
72
|
+
agentId: 'codex',
|
|
73
|
+
workspace: workspace || process.cwd(),
|
|
74
|
+
sessionId: 'codex-session',
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
78
|
+
let toml = fs.existsSync(target) ? fs.readFileSync(target, 'utf8') : ''
|
|
79
|
+
toml = stripMioSection(toml)
|
|
80
|
+
toml = toml.replace(/\n{3,}/g, '\n\n')
|
|
81
|
+
if (!toml.endsWith('\n')) toml += '\n'
|
|
82
|
+
const section = [
|
|
83
|
+
'',
|
|
84
|
+
SERVER_SECTION,
|
|
85
|
+
`command = '${node}'`,
|
|
86
|
+
`args = ['${serverScript}']`,
|
|
87
|
+
'startup_timeout_sec = 30',
|
|
88
|
+
'',
|
|
89
|
+
ENV_SECTION,
|
|
90
|
+
`MIO_DATA_DIR = '${home}'`,
|
|
91
|
+
`MIO_CONTEXT = '${context}'`,
|
|
92
|
+
'',
|
|
93
|
+
].join('\n')
|
|
94
|
+
fs.writeFileSync(target, `${toml}${section}\n`, 'utf8')
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
changed: true,
|
|
98
|
+
configPath: target,
|
|
99
|
+
backup,
|
|
100
|
+
message: installed
|
|
101
|
+
? 'Codex Mio MCP repaired (server path updated). Restart Codex to load it.'
|
|
102
|
+
: 'Codex Mio MCP installed. Restart Codex to load it.',
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
62
106
|
module.exports = { configPath, isInstalled, install }
|
package/adapters/opencode.js
CHANGED
|
@@ -74,6 +74,17 @@ function ensureGlobalInstructions() {
|
|
|
74
74
|
return { changed: true, target, backup }
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
function configNeedsRepair(serverScript) {
|
|
78
|
+
const config = readConfig()
|
|
79
|
+
const mcp = config && config.mcp && config.mcp['mio-intelligence']
|
|
80
|
+
if (!mcp) return false
|
|
81
|
+
const command = mcp.command
|
|
82
|
+
if (!Array.isArray(command) || command.length < 2) return true
|
|
83
|
+
const configured = String(command[1]).replace(/\\/g, '/').toLowerCase()
|
|
84
|
+
const needle = String(serverScript).replace(/\\/g, '/').toLowerCase()
|
|
85
|
+
return configured !== needle
|
|
86
|
+
}
|
|
87
|
+
|
|
77
88
|
function isInstalled() {
|
|
78
89
|
const config = readConfig()
|
|
79
90
|
if (!config || !config.mcp || !config.mcp['mio-intelligence']) return false
|
|
@@ -85,11 +96,12 @@ function install({ node, serverScript, home, workspace, project }) {
|
|
|
85
96
|
const target = configPath()
|
|
86
97
|
const config = readConfig() || {}
|
|
87
98
|
const configInstalled = Boolean(config.mcp && config.mcp['mio-intelligence'])
|
|
99
|
+
const needsRepair = configInstalled && configNeedsRepair(serverScript)
|
|
88
100
|
|
|
89
101
|
let configChanged = false
|
|
90
102
|
let backup = null
|
|
91
103
|
|
|
92
|
-
if (!configInstalled) {
|
|
104
|
+
if (!configInstalled || needsRepair) {
|
|
93
105
|
backup = `${target}.bak-mio-${Date.now()}`
|
|
94
106
|
if (fs.existsSync(target)) {
|
|
95
107
|
fs.copyFileSync(target, backup)
|
|
@@ -129,6 +141,8 @@ function install({ node, serverScript, home, workspace, project }) {
|
|
|
129
141
|
let message
|
|
130
142
|
if (configChanged && instructionsResult.changed) {
|
|
131
143
|
message = 'OpenCode Mio MCP installed and global Mio rules injected into AGENTS.md. Restart OpenCode to load them.'
|
|
144
|
+
} else if (needsRepair && !instructionsResult.changed) {
|
|
145
|
+
message = 'OpenCode Mio MCP repaired (server path updated). Restart OpenCode to load it.'
|
|
132
146
|
} else if (instructionsResult.changed) {
|
|
133
147
|
message = 'OpenCode Mio MCP already installed. Injected global Mio rules into AGENTS.md. Restart OpenCode to load them.'
|
|
134
148
|
} else {
|
|
@@ -147,4 +161,4 @@ function install({ node, serverScript, home, workspace, project }) {
|
|
|
147
161
|
}
|
|
148
162
|
}
|
|
149
163
|
|
|
150
|
-
module.exports = { configPath, globalInstructionsPath, isInstalled, install }
|
|
164
|
+
module.exports = { configPath, globalInstructionsPath, isInstalled, install, configNeedsRepair }
|