@jmylchreest/aide-plugin 0.0.19 → 0.0.22
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/package.json +13 -20
- package/src/cli/config.ts +150 -0
- package/{dist/cli/index.js → src/cli/index.ts} +38 -34
- package/src/cli/install.ts +71 -0
- package/src/cli/status.ts +46 -0
- package/src/cli/uninstall.ts +48 -0
- package/src/core/aide-client.ts +201 -0
- package/src/core/cleanup.ts +62 -0
- package/{dist/core/index.js → src/core/index.ts} +1 -1
- package/src/core/mcp-sync.ts +708 -0
- package/src/core/persistence-logic.ts +77 -0
- package/src/core/pre-compact-logic.ts +36 -0
- package/src/core/session-init.ts +411 -0
- package/src/core/session-summary-logic.ts +233 -0
- package/src/core/skill-matcher.ts +279 -0
- package/src/core/tool-enforcement.ts +130 -0
- package/src/core/tool-tracking.ts +112 -0
- package/src/core/types.ts +164 -0
- package/src/lib/aide-downloader.ts +557 -0
- package/src/lib/aide-memory.ts +400 -0
- package/src/lib/hook-utils.ts +185 -0
- package/src/lib/hud.ts +482 -0
- package/src/lib/logger.ts +379 -0
- package/src/lib/skills-registry.ts +333 -0
- package/src/lib/usage.ts +485 -0
- package/src/lib/worktree.ts +483 -0
- package/src/opencode/hooks.ts +708 -0
- package/{dist/opencode/index.d.ts → src/opencode/index.ts} +15 -6
- package/src/opencode/types.ts +107 -0
- package/dist/cli/config.d.ts +0 -58
- package/dist/cli/config.d.ts.map +0 -1
- package/dist/cli/config.js +0 -115
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/index.d.ts +0 -11
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/install.d.ts +0 -9
- package/dist/cli/install.d.ts.map +0 -1
- package/dist/cli/install.js +0 -49
- package/dist/cli/install.js.map +0 -1
- package/dist/cli/status.d.ts +0 -5
- package/dist/cli/status.d.ts.map +0 -1
- package/dist/cli/status.js +0 -34
- package/dist/cli/status.js.map +0 -1
- package/dist/cli/uninstall.d.ts +0 -8
- package/dist/cli/uninstall.d.ts.map +0 -1
- package/dist/cli/uninstall.js +0 -29
- package/dist/cli/uninstall.js.map +0 -1
- package/dist/core/aide-client.d.ts +0 -48
- package/dist/core/aide-client.d.ts.map +0 -1
- package/dist/core/aide-client.js +0 -171
- package/dist/core/aide-client.js.map +0 -1
- package/dist/core/cleanup.d.ts +0 -15
- package/dist/core/cleanup.d.ts.map +0 -1
- package/dist/core/cleanup.js +0 -48
- package/dist/core/cleanup.js.map +0 -1
- package/dist/core/index.d.ts +0 -18
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/mcp-sync.d.ts +0 -99
- package/dist/core/mcp-sync.d.ts.map +0 -1
- package/dist/core/mcp-sync.js +0 -524
- package/dist/core/mcp-sync.js.map +0 -1
- package/dist/core/persistence-logic.d.ts +0 -24
- package/dist/core/persistence-logic.d.ts.map +0 -1
- package/dist/core/persistence-logic.js +0 -61
- package/dist/core/persistence-logic.js.map +0 -1
- package/dist/core/pre-compact-logic.d.ts +0 -11
- package/dist/core/pre-compact-logic.d.ts.map +0 -1
- package/dist/core/pre-compact-logic.js +0 -29
- package/dist/core/pre-compact-logic.js.map +0 -1
- package/dist/core/session-init.d.ts +0 -54
- package/dist/core/session-init.d.ts.map +0 -1
- package/dist/core/session-init.js +0 -349
- package/dist/core/session-init.js.map +0 -1
- package/dist/core/session-summary-logic.d.ts +0 -29
- package/dist/core/session-summary-logic.d.ts.map +0 -1
- package/dist/core/session-summary-logic.js +0 -167
- package/dist/core/session-summary-logic.js.map +0 -1
- package/dist/core/skill-matcher.d.ts +0 -46
- package/dist/core/skill-matcher.d.ts.map +0 -1
- package/dist/core/skill-matcher.js +0 -242
- package/dist/core/skill-matcher.js.map +0 -1
- package/dist/core/tool-enforcement.d.ts +0 -44
- package/dist/core/tool-enforcement.d.ts.map +0 -1
- package/dist/core/tool-enforcement.js +0 -102
- package/dist/core/tool-enforcement.js.map +0 -1
- package/dist/core/tool-tracking.d.ts +0 -20
- package/dist/core/tool-tracking.d.ts.map +0 -1
- package/dist/core/tool-tracking.js +0 -81
- package/dist/core/tool-tracking.js.map +0 -1
- package/dist/core/types.d.ts +0 -109
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js +0 -31
- package/dist/core/types.js.map +0 -1
- package/dist/lib/aide-downloader.d.ts +0 -90
- package/dist/lib/aide-downloader.js +0 -471
- package/dist/lib/aide-downloader.js.map +0 -1
- package/dist/lib/hook-utils.d.ts +0 -45
- package/dist/lib/hook-utils.js +0 -170
- package/dist/lib/hook-utils.js.map +0 -1
- package/dist/opencode/hooks.d.ts +0 -32
- package/dist/opencode/hooks.d.ts.map +0 -1
- package/dist/opencode/hooks.js +0 -508
- package/dist/opencode/hooks.js.map +0 -1
- package/dist/opencode/index.d.ts.map +0 -1
- package/dist/opencode/index.js +0 -32
- package/dist/opencode/index.js.map +0 -1
- package/dist/opencode/types.d.ts +0 -129
- package/dist/opencode/types.d.ts.map +0 -1
- package/dist/opencode/types.js +0 -12
- package/dist/opencode/types.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,38 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmylchreest/aide-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "aide plugin for OpenCode — multi-agent orchestration, memory, skills, and persistence",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./
|
|
7
|
-
"types": "./dist/opencode/index.d.ts",
|
|
6
|
+
"main": "./src/opencode/index.ts",
|
|
8
7
|
"exports": {
|
|
9
8
|
".": {
|
|
10
|
-
"import": "./
|
|
11
|
-
"types": "./dist/opencode/index.d.ts"
|
|
9
|
+
"import": "./src/opencode/index.ts"
|
|
12
10
|
}
|
|
13
11
|
},
|
|
14
12
|
"files": [
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"dist/lib/aide-downloader.js.map",
|
|
20
|
-
"dist/lib/aide-downloader.d.ts",
|
|
21
|
-
"dist/lib/hook-utils.js",
|
|
22
|
-
"dist/lib/hook-utils.js.map",
|
|
23
|
-
"dist/lib/hook-utils.d.ts",
|
|
13
|
+
"src/opencode",
|
|
14
|
+
"src/core",
|
|
15
|
+
"src/cli",
|
|
16
|
+
"src/lib",
|
|
24
17
|
"bin",
|
|
25
18
|
"README.md"
|
|
26
19
|
],
|
|
27
20
|
"bin": {
|
|
28
|
-
"aide-plugin": "./
|
|
21
|
+
"aide-plugin": "./src/cli/index.ts",
|
|
29
22
|
"aide-wrapper": "./bin/aide-wrapper.sh"
|
|
30
23
|
},
|
|
31
24
|
"scripts": {
|
|
32
|
-
"prebuild": "npm run copy-
|
|
33
|
-
"build": "echo '
|
|
34
|
-
"copy-
|
|
35
|
-
"prepublishOnly": "npm run copy-
|
|
25
|
+
"prebuild": "npm run copy-src",
|
|
26
|
+
"build": "echo 'Ships TypeScript source — no compilation needed'",
|
|
27
|
+
"copy-src": "node scripts/copy-src.mjs",
|
|
28
|
+
"prepublishOnly": "npm run copy-src"
|
|
36
29
|
},
|
|
37
30
|
"keywords": [
|
|
38
31
|
"aide",
|
|
@@ -52,7 +45,7 @@
|
|
|
52
45
|
"directory": "packages/opencode-plugin"
|
|
53
46
|
},
|
|
54
47
|
"engines": {
|
|
55
|
-
"
|
|
48
|
+
"bun": ">=1.0.0"
|
|
56
49
|
},
|
|
57
50
|
"dependencies": {}
|
|
58
51
|
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode config file utilities.
|
|
3
|
+
*
|
|
4
|
+
* Handles reading, merging, and writing opencode.json at both
|
|
5
|
+
* global (~/.config/opencode/opencode.json) and project (./opencode.json) scopes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
9
|
+
import { dirname, join } from "path";
|
|
10
|
+
import { homedir } from "os";
|
|
11
|
+
|
|
12
|
+
export interface McpServerConfig {
|
|
13
|
+
type?: string;
|
|
14
|
+
command?: string[];
|
|
15
|
+
environment?: Record<string, string>;
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface OpenCodeConfig {
|
|
20
|
+
$schema?: string;
|
|
21
|
+
plugin?: string[];
|
|
22
|
+
mcp?: Record<string, McpServerConfig>;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const PLUGIN_NAME = "@jmylchreest/aide-plugin";
|
|
27
|
+
const MCP_SERVER_NAME = "aide";
|
|
28
|
+
const SCHEMA_URL = "https://opencode.ai/config.json";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the path to the global OpenCode config file.
|
|
32
|
+
*/
|
|
33
|
+
export function getGlobalConfigPath(): string {
|
|
34
|
+
return join(homedir(), ".config", "opencode", "opencode.json");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get the path to the project-level OpenCode config file.
|
|
39
|
+
*/
|
|
40
|
+
export function getProjectConfigPath(): string {
|
|
41
|
+
return join(process.cwd(), "opencode.json");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Read and parse an opencode.json file. Returns an empty config if
|
|
46
|
+
* the file doesn't exist or can't be parsed.
|
|
47
|
+
*/
|
|
48
|
+
export function readConfig(configPath: string): OpenCodeConfig {
|
|
49
|
+
if (!existsSync(configPath)) {
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
54
|
+
return JSON.parse(raw) as OpenCodeConfig;
|
|
55
|
+
} catch {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Write a config object to an opencode.json file, creating
|
|
62
|
+
* parent directories as needed.
|
|
63
|
+
*/
|
|
64
|
+
export function writeConfig(configPath: string, config: OpenCodeConfig): void {
|
|
65
|
+
const dir = dirname(configPath);
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Add the aide plugin and MCP server to a config object.
|
|
72
|
+
* Preserves all existing config keys.
|
|
73
|
+
*/
|
|
74
|
+
export function addAideToConfig(
|
|
75
|
+
config: OpenCodeConfig,
|
|
76
|
+
options: { noMcp?: boolean } = {},
|
|
77
|
+
): OpenCodeConfig {
|
|
78
|
+
const result = { ...config };
|
|
79
|
+
|
|
80
|
+
// Ensure schema
|
|
81
|
+
if (!result.$schema) {
|
|
82
|
+
result.$schema = SCHEMA_URL;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Add plugin to array (deduplicated)
|
|
86
|
+
const plugins = result.plugin ?? [];
|
|
87
|
+
if (!plugins.includes(PLUGIN_NAME)) {
|
|
88
|
+
plugins.push(PLUGIN_NAME);
|
|
89
|
+
}
|
|
90
|
+
result.plugin = plugins;
|
|
91
|
+
|
|
92
|
+
// Add MCP server config
|
|
93
|
+
if (!options.noMcp) {
|
|
94
|
+
const mcp = result.mcp ?? {};
|
|
95
|
+
if (!mcp[MCP_SERVER_NAME]) {
|
|
96
|
+
mcp[MCP_SERVER_NAME] = {
|
|
97
|
+
type: "local",
|
|
98
|
+
command: ["npx", "-y", "-p", PLUGIN_NAME, "aide-wrapper", "mcp"],
|
|
99
|
+
environment: {
|
|
100
|
+
AIDE_CODE_WATCH: "1",
|
|
101
|
+
AIDE_CODE_WATCH_DELAY: "30s",
|
|
102
|
+
},
|
|
103
|
+
enabled: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
result.mcp = mcp;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Remove the aide plugin and MCP server from a config object.
|
|
114
|
+
*/
|
|
115
|
+
export function removeAideFromConfig(config: OpenCodeConfig): OpenCodeConfig {
|
|
116
|
+
const result = { ...config };
|
|
117
|
+
|
|
118
|
+
// Remove plugin from array
|
|
119
|
+
if (result.plugin) {
|
|
120
|
+
result.plugin = result.plugin.filter((p) => p !== PLUGIN_NAME);
|
|
121
|
+
if (result.plugin.length === 0) {
|
|
122
|
+
delete result.plugin;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Remove MCP server
|
|
127
|
+
if (result.mcp) {
|
|
128
|
+
delete result.mcp[MCP_SERVER_NAME];
|
|
129
|
+
if (Object.keys(result.mcp).length === 0) {
|
|
130
|
+
delete result.mcp;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Check if aide is configured in a config object.
|
|
139
|
+
*/
|
|
140
|
+
export function isAideConfigured(config: OpenCodeConfig): {
|
|
141
|
+
plugin: boolean;
|
|
142
|
+
mcp: boolean;
|
|
143
|
+
} {
|
|
144
|
+
return {
|
|
145
|
+
plugin: config.plugin?.includes(PLUGIN_NAME) ?? false,
|
|
146
|
+
mcp: config.mcp?.[MCP_SERVER_NAME] != null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { PLUGIN_NAME, MCP_SERVER_NAME };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
3
|
* aide CLI — install/uninstall the aide plugin for OpenCode.
|
|
4
4
|
*
|
|
@@ -7,13 +7,16 @@
|
|
|
7
7
|
* bunx @jmylchreest/aide-plugin uninstall # Remove from OpenCode config
|
|
8
8
|
* bunx @jmylchreest/aide-plugin status # Show current installation status
|
|
9
9
|
*/
|
|
10
|
+
|
|
10
11
|
import { install } from "./install.js";
|
|
11
12
|
import { uninstall } from "./uninstall.js";
|
|
12
13
|
import { status } from "./status.js";
|
|
14
|
+
|
|
13
15
|
const args = process.argv.slice(2);
|
|
14
16
|
const command = args[0];
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
function printUsage(): void {
|
|
19
|
+
console.log(`aide - AI Development Environment plugin for OpenCode
|
|
17
20
|
|
|
18
21
|
Usage:
|
|
19
22
|
aide-plugin install Install aide plugin globally for OpenCode
|
|
@@ -27,39 +30,40 @@ Options:
|
|
|
27
30
|
|
|
28
31
|
Examples:
|
|
29
32
|
bunx @jmylchreest/aide-plugin install
|
|
30
|
-
npx @jmylchreest/aide-plugin install
|
|
31
33
|
aide-plugin install --project`);
|
|
32
34
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
35
|
+
|
|
36
|
+
async function main(): Promise<void> {
|
|
37
|
+
const flags = {
|
|
38
|
+
project: args.includes("--project"),
|
|
39
|
+
noMcp: args.includes("--no-mcp"),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
switch (command) {
|
|
43
|
+
case "install":
|
|
44
|
+
await install(flags);
|
|
45
|
+
break;
|
|
46
|
+
case "uninstall":
|
|
47
|
+
await uninstall(flags);
|
|
48
|
+
break;
|
|
49
|
+
case "status":
|
|
50
|
+
await status();
|
|
51
|
+
break;
|
|
52
|
+
case "--help":
|
|
53
|
+
case "-h":
|
|
54
|
+
case "help":
|
|
55
|
+
printUsage();
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
if (command) {
|
|
59
|
+
console.error(`Unknown command: ${command}\n`);
|
|
60
|
+
}
|
|
61
|
+
printUsage();
|
|
62
|
+
process.exit(command ? 1 : 0);
|
|
63
|
+
}
|
|
60
64
|
}
|
|
65
|
+
|
|
61
66
|
main().catch((err) => {
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
+
process.exit(1);
|
|
64
69
|
});
|
|
65
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install command — registers aide plugin and MCP server in OpenCode config.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
addAideToConfig,
|
|
7
|
+
getGlobalConfigPath,
|
|
8
|
+
getProjectConfigPath,
|
|
9
|
+
isAideConfigured,
|
|
10
|
+
readConfig,
|
|
11
|
+
writeConfig,
|
|
12
|
+
PLUGIN_NAME,
|
|
13
|
+
} from "./config.js";
|
|
14
|
+
|
|
15
|
+
export interface InstallFlags {
|
|
16
|
+
project?: boolean;
|
|
17
|
+
noMcp?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function install(flags: InstallFlags): Promise<void> {
|
|
21
|
+
const configPath = flags.project
|
|
22
|
+
? getProjectConfigPath()
|
|
23
|
+
: getGlobalConfigPath();
|
|
24
|
+
|
|
25
|
+
const scope = flags.project ? "project" : "global";
|
|
26
|
+
console.log(`Installing aide plugin (${scope})...\n`);
|
|
27
|
+
|
|
28
|
+
// Read existing config
|
|
29
|
+
const existing = readConfig(configPath);
|
|
30
|
+
const before = isAideConfigured(existing);
|
|
31
|
+
|
|
32
|
+
if (before.plugin && before.mcp) {
|
|
33
|
+
console.log(`aide is already configured in ${configPath}`);
|
|
34
|
+
console.log(" plugin: registered");
|
|
35
|
+
console.log(" mcp: registered");
|
|
36
|
+
console.log("\nNothing to do.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Apply changes
|
|
41
|
+
const updated = addAideToConfig(existing, { noMcp: flags.noMcp });
|
|
42
|
+
writeConfig(configPath, updated);
|
|
43
|
+
|
|
44
|
+
// Report what was done
|
|
45
|
+
const after = isAideConfigured(updated);
|
|
46
|
+
console.log(`Updated: ${configPath}\n`);
|
|
47
|
+
|
|
48
|
+
if (!before.plugin && after.plugin) {
|
|
49
|
+
console.log(` + Added "${PLUGIN_NAME}" to plugin array`);
|
|
50
|
+
} else if (before.plugin) {
|
|
51
|
+
console.log(` = Plugin already registered`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!flags.noMcp) {
|
|
55
|
+
if (!before.mcp && after.mcp) {
|
|
56
|
+
console.log(` + Added "aide" MCP server`);
|
|
57
|
+
} else if (before.mcp) {
|
|
58
|
+
console.log(` = MCP server already registered`);
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
console.log(` - Skipped MCP server registration (--no-mcp)`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log("\nInstallation complete. Start OpenCode to use aide.");
|
|
65
|
+
|
|
66
|
+
if (!flags.project) {
|
|
67
|
+
console.log(
|
|
68
|
+
"\nThe plugin is installed globally and will apply to all OpenCode projects.",
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status command — shows current aide installation status for OpenCode.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { existsSync } from "fs";
|
|
6
|
+
import {
|
|
7
|
+
getGlobalConfigPath,
|
|
8
|
+
getProjectConfigPath,
|
|
9
|
+
isAideConfigured,
|
|
10
|
+
readConfig,
|
|
11
|
+
} from "./config.js";
|
|
12
|
+
|
|
13
|
+
export async function status(): Promise<void> {
|
|
14
|
+
console.log("aide plugin status\n");
|
|
15
|
+
|
|
16
|
+
const globalPath = getGlobalConfigPath();
|
|
17
|
+
const projectPath = getProjectConfigPath();
|
|
18
|
+
|
|
19
|
+
// Global config
|
|
20
|
+
console.log(`Global config: ${globalPath}`);
|
|
21
|
+
if (existsSync(globalPath)) {
|
|
22
|
+
const globalConfig = readConfig(globalPath);
|
|
23
|
+
const globalStatus = isAideConfigured(globalConfig);
|
|
24
|
+
console.log(
|
|
25
|
+
` plugin: ${globalStatus.plugin ? "registered" : "not found"}`,
|
|
26
|
+
);
|
|
27
|
+
console.log(` mcp: ${globalStatus.mcp ? "registered" : "not found"}`);
|
|
28
|
+
} else {
|
|
29
|
+
console.log(" (file does not exist)");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log();
|
|
33
|
+
|
|
34
|
+
// Project config
|
|
35
|
+
console.log(`Project config: ${projectPath}`);
|
|
36
|
+
if (existsSync(projectPath)) {
|
|
37
|
+
const projectConfig = readConfig(projectPath);
|
|
38
|
+
const projectStatus = isAideConfigured(projectConfig);
|
|
39
|
+
console.log(
|
|
40
|
+
` plugin: ${projectStatus.plugin ? "registered" : "not found"}`,
|
|
41
|
+
);
|
|
42
|
+
console.log(` mcp: ${projectStatus.mcp ? "registered" : "not found"}`);
|
|
43
|
+
} else {
|
|
44
|
+
console.log(" (file does not exist)");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uninstall command — removes aide plugin and MCP server from OpenCode config.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getGlobalConfigPath,
|
|
7
|
+
getProjectConfigPath,
|
|
8
|
+
isAideConfigured,
|
|
9
|
+
readConfig,
|
|
10
|
+
removeAideFromConfig,
|
|
11
|
+
writeConfig,
|
|
12
|
+
} from "./config.js";
|
|
13
|
+
|
|
14
|
+
export interface UninstallFlags {
|
|
15
|
+
project?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function uninstall(flags: UninstallFlags): Promise<void> {
|
|
19
|
+
const configPath = flags.project
|
|
20
|
+
? getProjectConfigPath()
|
|
21
|
+
: getGlobalConfigPath();
|
|
22
|
+
|
|
23
|
+
const scope = flags.project ? "project" : "global";
|
|
24
|
+
console.log(`Uninstalling aide plugin (${scope})...\n`);
|
|
25
|
+
|
|
26
|
+
const existing = readConfig(configPath);
|
|
27
|
+
const before = isAideConfigured(existing);
|
|
28
|
+
|
|
29
|
+
if (!before.plugin && !before.mcp) {
|
|
30
|
+
console.log(`aide is not configured in ${configPath}`);
|
|
31
|
+
console.log("\nNothing to do.");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const updated = removeAideFromConfig(existing);
|
|
36
|
+
writeConfig(configPath, updated);
|
|
37
|
+
|
|
38
|
+
console.log(`Updated: ${configPath}\n`);
|
|
39
|
+
|
|
40
|
+
if (before.plugin) {
|
|
41
|
+
console.log(` - Removed aide plugin from plugin array`);
|
|
42
|
+
}
|
|
43
|
+
if (before.mcp) {
|
|
44
|
+
console.log(` - Removed aide MCP server`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log("\nUninstallation complete.");
|
|
48
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic aide binary discovery and state operations.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from src/lib/hook-utils.ts. Both Claude Code hooks and
|
|
5
|
+
* OpenCode plugin use this module for binary discovery and state management.
|
|
6
|
+
*
|
|
7
|
+
* Key difference from hook-utils.ts: accepts explicit binary path and
|
|
8
|
+
* platform-specific options instead of relying on CLAUDE_PLUGIN_ROOT.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { execSync, execFileSync } from "child_process";
|
|
12
|
+
import { existsSync, realpathSync } from "fs";
|
|
13
|
+
import { join } from "path";
|
|
14
|
+
import type { FindBinaryOptions } from "./types.js";
|
|
15
|
+
import { debug } from "../lib/logger.js";
|
|
16
|
+
|
|
17
|
+
const SOURCE = "aide-client";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Find the aide binary — platform-agnostic implementation.
|
|
21
|
+
*
|
|
22
|
+
* Search order:
|
|
23
|
+
* 1. pluginRoot/bin/aide (if pluginRoot provided)
|
|
24
|
+
* 2. cwd/.aide/bin/aide (project-local install)
|
|
25
|
+
* 3. Each path in additionalPaths
|
|
26
|
+
* 4. PATH fallback (system-wide install)
|
|
27
|
+
*/
|
|
28
|
+
export function findAideBinary(opts: FindBinaryOptions = {}): string | null {
|
|
29
|
+
const { cwd, additionalPaths = [] } = opts;
|
|
30
|
+
let { pluginRoot } = opts;
|
|
31
|
+
|
|
32
|
+
// Resolve symlinks on pluginRoot
|
|
33
|
+
if (pluginRoot) {
|
|
34
|
+
try {
|
|
35
|
+
pluginRoot = realpathSync(pluginRoot);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
debug(SOURCE, `realpath failed for pluginRoot ${pluginRoot}: ${err}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 1. Plugin root bin/
|
|
42
|
+
if (pluginRoot) {
|
|
43
|
+
const pluginBinary = join(pluginRoot, "bin", "aide");
|
|
44
|
+
if (existsSync(pluginBinary)) {
|
|
45
|
+
return pluginBinary;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 2. Project-local .aide/bin/
|
|
50
|
+
if (cwd) {
|
|
51
|
+
const projectBinary = join(cwd, ".aide", "bin", "aide");
|
|
52
|
+
if (existsSync(projectBinary)) {
|
|
53
|
+
return projectBinary;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 3. Additional paths
|
|
58
|
+
for (const searchPath of additionalPaths) {
|
|
59
|
+
const binary = join(searchPath, "aide");
|
|
60
|
+
if (existsSync(binary)) {
|
|
61
|
+
return binary;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 4. PATH fallback
|
|
66
|
+
try {
|
|
67
|
+
const result = execSync("which aide", { stdio: "pipe", timeout: 2000 })
|
|
68
|
+
.toString()
|
|
69
|
+
.trim();
|
|
70
|
+
if (result) return result;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
debug(SOURCE, `aide not found in PATH: ${err}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Run an aide command and return stdout, or null on failure.
|
|
80
|
+
*/
|
|
81
|
+
export function runAide(
|
|
82
|
+
binary: string,
|
|
83
|
+
cwd: string,
|
|
84
|
+
args: string[],
|
|
85
|
+
options?: { timeout?: number; env?: Record<string, string | undefined> },
|
|
86
|
+
): string | null {
|
|
87
|
+
try {
|
|
88
|
+
const env = options?.env ? { ...process.env, ...options.env } : process.env;
|
|
89
|
+
return execFileSync(binary, args, {
|
|
90
|
+
cwd,
|
|
91
|
+
encoding: "utf-8",
|
|
92
|
+
timeout: options?.timeout ?? 10000,
|
|
93
|
+
env,
|
|
94
|
+
});
|
|
95
|
+
} catch (err) {
|
|
96
|
+
debug(SOURCE, `runAide failed: ${args.join(" ")}: ${err}`);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Set state in aide (global or per-agent)
|
|
103
|
+
*/
|
|
104
|
+
export function setState(
|
|
105
|
+
binary: string,
|
|
106
|
+
cwd: string,
|
|
107
|
+
key: string,
|
|
108
|
+
value: string,
|
|
109
|
+
agentId?: string,
|
|
110
|
+
): boolean {
|
|
111
|
+
try {
|
|
112
|
+
const args = ["state", "set", key, value];
|
|
113
|
+
if (agentId) args.push(`--agent=${agentId}`);
|
|
114
|
+
execFileSync(binary, args, { cwd, stdio: "pipe", timeout: 5000 });
|
|
115
|
+
return true;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
debug(SOURCE, `setState failed for key=${key}: ${err}`);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get state from aide
|
|
124
|
+
*/
|
|
125
|
+
export function getState(
|
|
126
|
+
binary: string,
|
|
127
|
+
cwd: string,
|
|
128
|
+
key: string,
|
|
129
|
+
agentId?: string,
|
|
130
|
+
): string | null {
|
|
131
|
+
try {
|
|
132
|
+
const args = ["state", "get", key];
|
|
133
|
+
if (agentId) args.push(`--agent=${agentId}`);
|
|
134
|
+
const output = execFileSync(binary, args, {
|
|
135
|
+
cwd,
|
|
136
|
+
encoding: "utf-8",
|
|
137
|
+
timeout: 5000,
|
|
138
|
+
});
|
|
139
|
+
const match = output.match(/=\s*(.+)$/m);
|
|
140
|
+
return match ? match[1].trim() : null;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
debug(SOURCE, `getState failed for key=${key}: ${err}`);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Delete a state key from aide
|
|
149
|
+
*/
|
|
150
|
+
export function deleteState(
|
|
151
|
+
binary: string,
|
|
152
|
+
cwd: string,
|
|
153
|
+
key: string,
|
|
154
|
+
agentId?: string,
|
|
155
|
+
): boolean {
|
|
156
|
+
try {
|
|
157
|
+
const fullKey = agentId ? `agent:${agentId}:${key}` : key;
|
|
158
|
+
execFileSync(binary, ["state", "delete", fullKey], {
|
|
159
|
+
cwd,
|
|
160
|
+
stdio: "pipe",
|
|
161
|
+
});
|
|
162
|
+
return true;
|
|
163
|
+
} catch (err) {
|
|
164
|
+
debug(SOURCE, `deleteState failed for key=${key}: ${err}`);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Clear all state for an agent
|
|
171
|
+
*/
|
|
172
|
+
export function clearAgentState(
|
|
173
|
+
binary: string,
|
|
174
|
+
cwd: string,
|
|
175
|
+
agentId: string,
|
|
176
|
+
): boolean {
|
|
177
|
+
try {
|
|
178
|
+
execFileSync(binary, ["state", "clear", `--agent=${agentId}`], {
|
|
179
|
+
cwd,
|
|
180
|
+
stdio: "pipe",
|
|
181
|
+
});
|
|
182
|
+
return true;
|
|
183
|
+
} catch (err) {
|
|
184
|
+
debug(SOURCE, `clearAgentState failed for agent=${agentId}: ${err}`);
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Escape a string for safe shell usage (when shell is unavoidable)
|
|
191
|
+
*/
|
|
192
|
+
export function shellEscape(str: string): string {
|
|
193
|
+
return str
|
|
194
|
+
.replace(/\\/g, "\\\\")
|
|
195
|
+
.replace(/"/g, '\\"')
|
|
196
|
+
.replace(/\$/g, "\\$")
|
|
197
|
+
.replace(/`/g, "\\`")
|
|
198
|
+
.replace(/!/g, "\\!")
|
|
199
|
+
.replace(/\n/g, " ")
|
|
200
|
+
.slice(0, 1000);
|
|
201
|
+
}
|