opencode-idea 0.0.10 → 0.0.12
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 +151 -88
- package/package.json +1 -3
- package/src/ide-guidance.js +29 -4
- package/src/ide-launcher.js +58 -0
- package/src/mcp/idea.js +91 -17
- package/src/plugin.js +331 -166
- package/src/env.js +0 -39
- package/src/mcp/ide-env.js +0 -101
package/src/env.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// Merges environment sources and applies them to a shell `create.before`
|
|
2
|
-
// invocation.
|
|
3
|
-
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Merge env sources. Later sources win. `prependPath` entries are collected in
|
|
8
|
-
* order and applied ahead of the existing PATH.
|
|
9
|
-
*
|
|
10
|
-
* @param {Array<{ env?: Record<string, string>, prependPath?: string[] }>} sources
|
|
11
|
-
* @returns {{ env: Record<string, string>, prependPath: string[] }}
|
|
12
|
-
*/
|
|
13
|
-
export function mergeEnv(sources) {
|
|
14
|
-
const env = {};
|
|
15
|
-
const prependPath = [];
|
|
16
|
-
for (const source of sources) {
|
|
17
|
-
Object.assign(env, source.env ?? {});
|
|
18
|
-
prependPath.push(...(source.prependPath ?? []));
|
|
19
|
-
}
|
|
20
|
-
return { env, prependPath: [...new Set(prependPath)] };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Apply a merged env to a shell invocation's `env` in place.
|
|
25
|
-
*
|
|
26
|
-
* @param {{ env: Record<string, string | undefined> }} input
|
|
27
|
-
* @param {{ env: Record<string, string>, prependPath: string[] }} merged
|
|
28
|
-
* @param {{ pathKey?: string }} [options]
|
|
29
|
-
*/
|
|
30
|
-
export function applyEnv(input, merged, options = {}) {
|
|
31
|
-
const pathKey = options.pathKey ?? 'PATH';
|
|
32
|
-
for (const [key, value] of Object.entries(merged.env)) {
|
|
33
|
-
if (value !== undefined) input.env[key] = value;
|
|
34
|
-
}
|
|
35
|
-
if (merged.prependPath.length === 0) return;
|
|
36
|
-
const current = input.env[pathKey] ?? process.env[pathKey] ?? '';
|
|
37
|
-
const parts = [...merged.prependPath, ...current.split(path.delimiter).filter(Boolean)];
|
|
38
|
-
input.env[pathKey] = [...new Set(parts)].join(path.delimiter);
|
|
39
|
-
}
|
package/src/mcp/ide-env.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
// Reads the IDE terminal environment over MCP and extracts the SDK-related
|
|
2
|
-
// variables. The IDE terminal is the single source of truth for the environment
|
|
3
|
-
// the IDE actually runs with (version-managed Node, goenv Go, SDKMAN Java, ...).
|
|
4
|
-
|
|
5
|
-
import { callTool } from './idea.js';
|
|
6
|
-
|
|
7
|
-
/** SDK-related variables worth mirroring into OpenCode's shell environment. */
|
|
8
|
-
export const SDK_ENV_KEYS = [
|
|
9
|
-
'JAVA_HOME',
|
|
10
|
-
'JRE_HOME',
|
|
11
|
-
'JDK_HOME',
|
|
12
|
-
'VIRTUAL_ENV',
|
|
13
|
-
'PYTHONPATH',
|
|
14
|
-
'PYTHONHOME',
|
|
15
|
-
'GOROOT',
|
|
16
|
-
'GOPATH',
|
|
17
|
-
'GOBIN',
|
|
18
|
-
'NODE_PATH',
|
|
19
|
-
'NVM_BIN',
|
|
20
|
-
'NVM_DIR',
|
|
21
|
-
'MAVEN_HOME',
|
|
22
|
-
'M2_HOME',
|
|
23
|
-
'GRADLE_HOME',
|
|
24
|
-
'SDKMAN_DIR',
|
|
25
|
-
'CONDA_PREFIX',
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Read SDK env from the IDE integrated terminal via `execute_terminal_command`.
|
|
30
|
-
* Requires the IDE MCP to be reachable and Brave Mode enabled (else the IDE
|
|
31
|
-
* waits for a confirmation and this returns `{}`).
|
|
32
|
-
*
|
|
33
|
-
* @param {number} port
|
|
34
|
-
* @param {string} projectPath
|
|
35
|
-
* @param {typeof fetch} [fetchImpl]
|
|
36
|
-
* @returns {Promise<Record<string, string>>}
|
|
37
|
-
*/
|
|
38
|
-
export async function readIdeTerminalEnv(port, projectPath, fetchImpl = fetch) {
|
|
39
|
-
const result = await callTool(
|
|
40
|
-
port,
|
|
41
|
-
projectPath,
|
|
42
|
-
'execute_terminal_command',
|
|
43
|
-
{ command: 'printenv', executeInShell: true, timeout: 8000, maxLinesCount: 800 },
|
|
44
|
-
{ fetchImpl, timeoutMs: 15000 },
|
|
45
|
-
).catch(() => undefined);
|
|
46
|
-
if (!result || result.isError) return {};
|
|
47
|
-
const text = (result.content ?? [])
|
|
48
|
-
.filter((part) => part.type === 'text' && typeof part.text === 'string')
|
|
49
|
-
.map((part) => part.text)
|
|
50
|
-
.join('\n');
|
|
51
|
-
return extractSdkEnv(parseCommandOutput(text));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Parse the `execute_terminal_command` payload. It is JSON with a
|
|
56
|
-
* `command_output` field; fall back to treating the text as raw env output.
|
|
57
|
-
*
|
|
58
|
-
* @param {string} text
|
|
59
|
-
* @returns {Record<string, string>}
|
|
60
|
-
*/
|
|
61
|
-
export function parseCommandOutput(text) {
|
|
62
|
-
try {
|
|
63
|
-
const parsed = JSON.parse(text);
|
|
64
|
-
if (parsed && typeof parsed.command_output === 'string') return parsePrintenv(parsed.command_output);
|
|
65
|
-
} catch {
|
|
66
|
-
// not JSON — treat as raw printenv output
|
|
67
|
-
}
|
|
68
|
-
return parsePrintenv(text);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Parse `KEY=VALUE` lines (printenv output) into an object.
|
|
73
|
-
*
|
|
74
|
-
* @param {string} text
|
|
75
|
-
* @returns {Record<string, string>}
|
|
76
|
-
*/
|
|
77
|
-
export function parsePrintenv(text) {
|
|
78
|
-
const env = {};
|
|
79
|
-
for (const line of text.split('\n')) {
|
|
80
|
-
const index = line.indexOf('=');
|
|
81
|
-
if (index <= 0) continue;
|
|
82
|
-
const key = line.slice(0, index).trim();
|
|
83
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue;
|
|
84
|
-
env[key] = line.slice(index + 1);
|
|
85
|
-
}
|
|
86
|
-
return env;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Keep only the SDK-related variables.
|
|
91
|
-
*
|
|
92
|
-
* @param {Record<string, string>} env
|
|
93
|
-
* @returns {Record<string, string>}
|
|
94
|
-
*/
|
|
95
|
-
export function extractSdkEnv(env) {
|
|
96
|
-
const out = {};
|
|
97
|
-
for (const key of SDK_ENV_KEYS) {
|
|
98
|
-
if (env[key]) out[key] = env[key];
|
|
99
|
-
}
|
|
100
|
-
return out;
|
|
101
|
-
}
|