mio-agent-runtime 0.5.15 → 0.5.17
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 +144 -236
- package/adapters/codex.js +122 -134
- package/adapters/hermes.js +122 -140
- package/adapters/host-utils.js +61 -61
- package/adapters/opencode.js +176 -215
- package/adapters/workbuddy.js +196 -242
- package/bin/mio.js +423 -424
- package/observe/observer.js +1326 -1335
- package/package.json +38 -25
- package/scripts/verify-packed-runtime.js +371 -0
- package/server/creativity-engine.js +397 -0
- package/server/evolution-cutover.js +119 -0
- package/server/host-capabilities.js +50 -0
- package/server/mio-intelligence-mcp/README.md +184 -173
- package/server/mio-intelligence-mcp/index.js +621 -300
- package/server/mio-intelligence-mcp/package.json +17 -17
- package/server/mio-intelligence-mcp/phase0.js +381 -381
- package/server/runtime-modules.js +111 -0
- package/server/mio-intelligence-mcp/dashboard-server.js +0 -171
package/adapters/opencode.js
CHANGED
|
@@ -1,215 +1,176 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const fs = require('fs')
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const os = require('os')
|
|
6
|
-
const { restartWarning } = require('./host-utils')
|
|
7
|
-
|
|
8
|
-
const INSTRUCTIONS_BEGIN = '<!-- MIO_INTELLIGENCE_BEGIN -->'
|
|
9
|
-
const INSTRUCTIONS_END = '<!-- MIO_INTELLIGENCE_END -->'
|
|
10
|
-
const INSTRUCTIONS_BLOCK = `${INSTRUCTIONS_BEGIN}
|
|
11
|
-
## Mio Intelligence Layer
|
|
12
|
-
|
|
13
|
-
Mio MCP tools are available. Treat these as mandatory runtime rules for every workspace.
|
|
14
|
-
|
|
15
|
-
- Before designing or implementing a solution, or when unsure about prior decisions, call \`mio-intelligence_mio_memory_query\` first. Omit \`project\` unless a specific project is required; Mio derives it from the current Git repository.
|
|
16
|
-
- After a decision affecting architecture, deployment, dependencies, or long-term behavior, call \`mio-intelligence_mio_memory_record\` with \`kind\`: \`decision\`, \`context\`, \`problem\`, or \`note\`.
|
|
17
|
-
- When a tool call fails, retries, or returns an error, call \`mio-intelligence_mio_observer_ingest\` with a stable \`trace_id\`, relevant \`event_type\`, \`payload\`, and \`outcome\`.
|
|
18
|
-
- Before a high-risk operation such as deletion, migration, credential change, or production change, call \`mio-intelligence_mio_policy_check\` and follow its suggestion when available.
|
|
19
|
-
- At the end of every task, before producing the final answer, call \`mio-intelligence_mio_observer_ingest\` with \`event_type\` = \`task_outcome\`, a stable \`trace_id\`, \`outcome\` = \`success\` / \`failure\` / \`aborted\`, and a brief non-sensitive \`payload\`. If Mio is unavailable, do not block the final answer.
|
|
20
|
-
- When you reuse a prior decision or experience returned by \`mio-intelligence_mio_memory_query\` and it changes your approach or outcome, call \`mio-intelligence_mio_experience_reuse\` with \`sourceAgent\`, \`targetAgent\`, \`experienceId\`, \`reuse\`, \`behaviorChanged\`, and \`outcomeImproved\`.
|
|
21
|
-
- If Mio MCP is unavailable, do not block the task. Continue normally and note the missed memory or observation.
|
|
22
|
-
- Do not store secrets, credentials, or raw sensitive content in Mio memory.
|
|
23
|
-
${INSTRUCTIONS_END}`
|
|
24
|
-
|
|
25
|
-
function configPath() {
|
|
26
|
-
return path.join(os.homedir(), '.config', 'opencode', 'opencode.json')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function globalInstructionsPath() {
|
|
30
|
-
return path.join(os.homedir(), '.config', 'opencode', 'AGENTS.md')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function readConfig() {
|
|
34
|
-
const target = configPath()
|
|
35
|
-
if (!fs.existsSync(target)) return null
|
|
36
|
-
try {
|
|
37
|
-
return JSON.parse(fs.readFileSync(target, 'utf8'))
|
|
38
|
-
} catch (_) {
|
|
39
|
-
return null
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function readGlobalInstructions() {
|
|
44
|
-
const target = globalInstructionsPath()
|
|
45
|
-
if (!fs.existsSync(target)) return ''
|
|
46
|
-
try {
|
|
47
|
-
return fs.readFileSync(target, 'utf8')
|
|
48
|
-
} catch (_) {
|
|
49
|
-
return ''
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function ensureGlobalInstructions() {
|
|
54
|
-
const target = globalInstructionsPath()
|
|
55
|
-
let content = readGlobalInstructions()
|
|
56
|
-
const original = content
|
|
57
|
-
const start = content.indexOf(INSTRUCTIONS_BEGIN)
|
|
58
|
-
if (start !== -1) {
|
|
59
|
-
const end = content.indexOf(INSTRUCTIONS_END, start)
|
|
60
|
-
content = end === -1 ? content.slice(0, start) : content.slice(0, start) + content.slice(end + INSTRUCTIONS_END.length)
|
|
61
|
-
content = content.trimEnd()
|
|
62
|
-
}
|
|
63
|
-
if (content) content += '\n\n'
|
|
64
|
-
content += INSTRUCTIONS_BLOCK + '\n'
|
|
65
|
-
if (content === original) {
|
|
66
|
-
return { changed: false, target, backup: null }
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const backup = `${target}.bak-mio-${Date.now()}`
|
|
70
|
-
if (fs.existsSync(target)) {
|
|
71
|
-
fs.copyFileSync(target, backup)
|
|
72
|
-
}
|
|
73
|
-
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
74
|
-
fs.writeFileSync(target, content, 'utf8')
|
|
75
|
-
return { changed: true, target, backup }
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function configNeedsRepair(serverScript) {
|
|
79
|
-
const config = readConfig()
|
|
80
|
-
const mcp = config && config.mcp && config.mcp['mio-intelligence']
|
|
81
|
-
if (!mcp) return false
|
|
82
|
-
const command = mcp.command
|
|
83
|
-
if (!Array.isArray(command) || command.length < 2) return true
|
|
84
|
-
const configured = String(command[1]).replace(/\\/g, '/').toLowerCase()
|
|
85
|
-
const needle = String(serverScript).replace(/\\/g, '/').toLowerCase()
|
|
86
|
-
return configured !== needle
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function restartWarningMessage() {
|
|
90
|
-
return restartWarning({
|
|
91
|
-
hostLabel: 'OpenCode Desktop',
|
|
92
|
-
exeName: 'OpenCode.exe',
|
|
93
|
-
exePathFragment: '@opencode-aidesktop',
|
|
94
|
-
configPath: configPath(),
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function isInstalled() {
|
|
99
|
-
const config = readConfig()
|
|
100
|
-
if (!config || !config.mcp || !config.mcp['mio-intelligence']) return false
|
|
101
|
-
const instructions = readGlobalInstructions()
|
|
102
|
-
return instructions.includes(INSTRUCTIONS_BEGIN) && instructions.includes(INSTRUCTIONS_END)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function install({ node, serverScript, home, workspace, project }) {
|
|
106
|
-
const target = configPath()
|
|
107
|
-
const config = readConfig() || {}
|
|
108
|
-
const configInstalled = Boolean(config.mcp && config.mcp['mio-intelligence'])
|
|
109
|
-
const needsRepair = configInstalled && configNeedsRepair(serverScript)
|
|
110
|
-
|
|
111
|
-
let configChanged = false
|
|
112
|
-
let backup = null
|
|
113
|
-
|
|
114
|
-
if (!configInstalled || needsRepair) {
|
|
115
|
-
backup = `${target}.bak-mio-${Date.now()}`
|
|
116
|
-
if (fs.existsSync(target)) {
|
|
117
|
-
fs.copyFileSync(target, backup)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const existingMcp = config.mcp && typeof config.mcp === 'object' ? config.mcp : {}
|
|
121
|
-
const context = JSON.stringify({
|
|
122
|
-
agentId: 'opencode',
|
|
123
|
-
project: project || path.basename(workspace || process.cwd()),
|
|
124
|
-
workspace: workspace || process.cwd(),
|
|
125
|
-
sessionId: 'opencode-session',
|
|
126
|
-
})
|
|
127
|
-
const next = {
|
|
128
|
-
...config,
|
|
129
|
-
mcp: {
|
|
130
|
-
...existingMcp,
|
|
131
|
-
'mio-intelligence': {
|
|
132
|
-
enabled: true,
|
|
133
|
-
type: 'local',
|
|
134
|
-
command: [node, serverScript],
|
|
135
|
-
environment: {
|
|
136
|
-
MIO_DATA_DIR: home,
|
|
137
|
-
MIO_CONTEXT: context,
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
144
|
-
fs.writeFileSync(target, `${JSON.stringify(next, null, 2)}\n`, 'utf8')
|
|
145
|
-
configChanged = true
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const instructionsResult = ensureGlobalInstructions()
|
|
149
|
-
const changed = configChanged || instructionsResult.changed
|
|
150
|
-
|
|
151
|
-
let message
|
|
152
|
-
if (configChanged && instructionsResult.changed) {
|
|
153
|
-
message = 'OpenCode Mio MCP installed and global Mio rules injected into AGENTS.md. Restart OpenCode to load them.'
|
|
154
|
-
} else if (needsRepair && !instructionsResult.changed) {
|
|
155
|
-
message = 'OpenCode Mio MCP repaired (server path updated). Restart OpenCode to load it.'
|
|
156
|
-
} else if (instructionsResult.changed) {
|
|
157
|
-
message = 'OpenCode Mio MCP already installed. Injected global Mio rules into AGENTS.md. Restart OpenCode to load them.'
|
|
158
|
-
} else {
|
|
159
|
-
message = 'OpenCode Mio MCP already installed.'
|
|
160
|
-
}
|
|
161
|
-
const restartHint = restartWarningMessage()
|
|
162
|
-
if (restartHint) message += ' ' + restartHint
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
changed,
|
|
166
|
-
configPath: target,
|
|
167
|
-
globalInstructionsPath: instructionsResult.target,
|
|
168
|
-
configChanged,
|
|
169
|
-
instructionsChanged: instructionsResult.changed,
|
|
170
|
-
backup,
|
|
171
|
-
backupInstructions: instructionsResult.backup,
|
|
172
|
-
message,
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
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 }
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const os = require('os')
|
|
6
|
+
const { restartWarning } = require('./host-utils')
|
|
7
|
+
|
|
8
|
+
const INSTRUCTIONS_BEGIN = '<!-- MIO_INTELLIGENCE_BEGIN -->'
|
|
9
|
+
const INSTRUCTIONS_END = '<!-- MIO_INTELLIGENCE_END -->'
|
|
10
|
+
const INSTRUCTIONS_BLOCK = `${INSTRUCTIONS_BEGIN}
|
|
11
|
+
## Mio Intelligence Layer
|
|
12
|
+
|
|
13
|
+
Mio MCP tools are available. Treat these as mandatory runtime rules for every workspace.
|
|
14
|
+
|
|
15
|
+
- Before designing or implementing a solution, or when unsure about prior decisions, call \`mio-intelligence_mio_memory_query\` first. Omit \`project\` unless a specific project is required; Mio derives it from the current Git repository.
|
|
16
|
+
- After a decision affecting architecture, deployment, dependencies, or long-term behavior, call \`mio-intelligence_mio_memory_record\` with \`kind\`: \`decision\`, \`context\`, \`problem\`, or \`note\`.
|
|
17
|
+
- When a tool call fails, retries, or returns an error, call \`mio-intelligence_mio_observer_ingest\` with a stable \`trace_id\`, relevant \`event_type\`, \`payload\`, and \`outcome\`.
|
|
18
|
+
- Before a high-risk operation such as deletion, migration, credential change, or production change, call \`mio-intelligence_mio_policy_check\` and follow its suggestion when available.
|
|
19
|
+
- At the end of every task, before producing the final answer, call \`mio-intelligence_mio_observer_ingest\` with \`event_type\` = \`task_outcome\`, a stable \`trace_id\`, \`outcome\` = \`success\` / \`failure\` / \`aborted\`, and a brief non-sensitive \`payload\`. If Mio is unavailable, do not block the final answer.
|
|
20
|
+
- When you reuse a prior decision or experience returned by \`mio-intelligence_mio_memory_query\` and it changes your approach or outcome, call \`mio-intelligence_mio_experience_reuse\` with \`sourceAgent\`, \`targetAgent\`, \`experienceId\`, \`reuse\`, \`behaviorChanged\`, and \`outcomeImproved\`.
|
|
21
|
+
- If Mio MCP is unavailable, do not block the task. Continue normally and note the missed memory or observation.
|
|
22
|
+
- Do not store secrets, credentials, or raw sensitive content in Mio memory.
|
|
23
|
+
${INSTRUCTIONS_END}`
|
|
24
|
+
|
|
25
|
+
function configPath() {
|
|
26
|
+
return path.join(os.homedir(), '.config', 'opencode', 'opencode.json')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function globalInstructionsPath() {
|
|
30
|
+
return path.join(os.homedir(), '.config', 'opencode', 'AGENTS.md')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function readConfig() {
|
|
34
|
+
const target = configPath()
|
|
35
|
+
if (!fs.existsSync(target)) return null
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(fs.readFileSync(target, 'utf8'))
|
|
38
|
+
} catch (_) {
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function readGlobalInstructions() {
|
|
44
|
+
const target = globalInstructionsPath()
|
|
45
|
+
if (!fs.existsSync(target)) return ''
|
|
46
|
+
try {
|
|
47
|
+
return fs.readFileSync(target, 'utf8')
|
|
48
|
+
} catch (_) {
|
|
49
|
+
return ''
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ensureGlobalInstructions() {
|
|
54
|
+
const target = globalInstructionsPath()
|
|
55
|
+
let content = readGlobalInstructions()
|
|
56
|
+
const original = content
|
|
57
|
+
const start = content.indexOf(INSTRUCTIONS_BEGIN)
|
|
58
|
+
if (start !== -1) {
|
|
59
|
+
const end = content.indexOf(INSTRUCTIONS_END, start)
|
|
60
|
+
content = end === -1 ? content.slice(0, start) : content.slice(0, start) + content.slice(end + INSTRUCTIONS_END.length)
|
|
61
|
+
content = content.trimEnd()
|
|
62
|
+
}
|
|
63
|
+
if (content) content += '\n\n'
|
|
64
|
+
content += INSTRUCTIONS_BLOCK + '\n'
|
|
65
|
+
if (content === original) {
|
|
66
|
+
return { changed: false, target, backup: null }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const backup = `${target}.bak-mio-${Date.now()}`
|
|
70
|
+
if (fs.existsSync(target)) {
|
|
71
|
+
fs.copyFileSync(target, backup)
|
|
72
|
+
}
|
|
73
|
+
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
74
|
+
fs.writeFileSync(target, content, 'utf8')
|
|
75
|
+
return { changed: true, target, backup }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function configNeedsRepair(serverScript) {
|
|
79
|
+
const config = readConfig()
|
|
80
|
+
const mcp = config && config.mcp && config.mcp['mio-intelligence']
|
|
81
|
+
if (!mcp) return false
|
|
82
|
+
const command = mcp.command
|
|
83
|
+
if (!Array.isArray(command) || command.length < 2) return true
|
|
84
|
+
const configured = String(command[1]).replace(/\\/g, '/').toLowerCase()
|
|
85
|
+
const needle = String(serverScript).replace(/\\/g, '/').toLowerCase()
|
|
86
|
+
return configured !== needle
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function restartWarningMessage() {
|
|
90
|
+
return restartWarning({
|
|
91
|
+
hostLabel: 'OpenCode Desktop',
|
|
92
|
+
exeName: 'OpenCode.exe',
|
|
93
|
+
exePathFragment: '@opencode-aidesktop',
|
|
94
|
+
configPath: configPath(),
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isInstalled() {
|
|
99
|
+
const config = readConfig()
|
|
100
|
+
if (!config || !config.mcp || !config.mcp['mio-intelligence']) return false
|
|
101
|
+
const instructions = readGlobalInstructions()
|
|
102
|
+
return instructions.includes(INSTRUCTIONS_BEGIN) && instructions.includes(INSTRUCTIONS_END)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function install({ node, serverScript, home, workspace, project }) {
|
|
106
|
+
const target = configPath()
|
|
107
|
+
const config = readConfig() || {}
|
|
108
|
+
const configInstalled = Boolean(config.mcp && config.mcp['mio-intelligence'])
|
|
109
|
+
const needsRepair = configInstalled && configNeedsRepair(serverScript)
|
|
110
|
+
|
|
111
|
+
let configChanged = false
|
|
112
|
+
let backup = null
|
|
113
|
+
|
|
114
|
+
if (!configInstalled || needsRepair) {
|
|
115
|
+
backup = `${target}.bak-mio-${Date.now()}`
|
|
116
|
+
if (fs.existsSync(target)) {
|
|
117
|
+
fs.copyFileSync(target, backup)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const existingMcp = config.mcp && typeof config.mcp === 'object' ? config.mcp : {}
|
|
121
|
+
const context = JSON.stringify({
|
|
122
|
+
agentId: 'opencode',
|
|
123
|
+
project: project || path.basename(workspace || process.cwd()),
|
|
124
|
+
workspace: workspace || process.cwd(),
|
|
125
|
+
sessionId: 'opencode-session',
|
|
126
|
+
})
|
|
127
|
+
const next = {
|
|
128
|
+
...config,
|
|
129
|
+
mcp: {
|
|
130
|
+
...existingMcp,
|
|
131
|
+
'mio-intelligence': {
|
|
132
|
+
enabled: true,
|
|
133
|
+
type: 'local',
|
|
134
|
+
command: [node, serverScript],
|
|
135
|
+
environment: {
|
|
136
|
+
MIO_DATA_DIR: home,
|
|
137
|
+
MIO_CONTEXT: context,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fs.mkdirSync(path.dirname(target), { recursive: true })
|
|
144
|
+
fs.writeFileSync(target, `${JSON.stringify(next, null, 2)}\n`, 'utf8')
|
|
145
|
+
configChanged = true
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const instructionsResult = ensureGlobalInstructions()
|
|
149
|
+
const changed = configChanged || instructionsResult.changed
|
|
150
|
+
|
|
151
|
+
let message
|
|
152
|
+
if (configChanged && instructionsResult.changed) {
|
|
153
|
+
message = 'OpenCode Mio MCP installed and global Mio rules injected into AGENTS.md. Restart OpenCode to load them.'
|
|
154
|
+
} else if (needsRepair && !instructionsResult.changed) {
|
|
155
|
+
message = 'OpenCode Mio MCP repaired (server path updated). Restart OpenCode to load it.'
|
|
156
|
+
} else if (instructionsResult.changed) {
|
|
157
|
+
message = 'OpenCode Mio MCP already installed. Injected global Mio rules into AGENTS.md. Restart OpenCode to load them.'
|
|
158
|
+
} else {
|
|
159
|
+
message = 'OpenCode Mio MCP already installed.'
|
|
160
|
+
}
|
|
161
|
+
const restartHint = restartWarningMessage()
|
|
162
|
+
if (restartHint) message += ' ' + restartHint
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
changed,
|
|
166
|
+
configPath: target,
|
|
167
|
+
globalInstructionsPath: instructionsResult.target,
|
|
168
|
+
configChanged,
|
|
169
|
+
instructionsChanged: instructionsResult.changed,
|
|
170
|
+
backup,
|
|
171
|
+
backupInstructions: instructionsResult.backup,
|
|
172
|
+
message,
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
module.exports = { configPath, globalInstructionsPath, isInstalled, install, configNeedsRepair, restartWarningMessage }
|