mio-agent-runtime 0.3.12 → 0.3.13
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/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 }
|