plugin-updater 1.0.0
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 +56 -0
- package/index.js +92 -0
- package/package.json +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# plugin-updater
|
|
2
|
+
|
|
3
|
+
Plugin lifecycle manager for OpenCode and Claude Code launchers. Handles install, update, rebuild, downgrade, and uninstall operations for all plugins.
|
|
4
|
+
|
|
5
|
+
## Under-the-Hood Architecture
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
flowchart TD
|
|
9
|
+
%% Triggers
|
|
10
|
+
subgraph Execution_Triggers [Execution Triggers]
|
|
11
|
+
CLI_BOOT[CLI Startup (claude/oc)]
|
|
12
|
+
TUI_MENU[Launcher TUI Actions]
|
|
13
|
+
|
|
14
|
+
CLI_BOOT -->|Auto-runs hook on start| UPDATER_CORE
|
|
15
|
+
TUI_MENU -->|Manual rebuild/downgrade/uninstall| UPDATER_CORE
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
%% Core Logic
|
|
19
|
+
subgraph Plugin_Updater [Updater Core Logic]
|
|
20
|
+
UPDATER_CORE[Updater Engine]
|
|
21
|
+
API_LAYER[global.OpenCodeAPI Interop]
|
|
22
|
+
GIT_MGR[Git Operations Manager]
|
|
23
|
+
DEPLOYER[Plugin Deployer]
|
|
24
|
+
|
|
25
|
+
UPDATER_CORE <-->|Requests repo paths| API_LAYER
|
|
26
|
+
UPDATER_CORE -->|Trigger sync| GIT_MGR
|
|
27
|
+
UPDATER_CORE -->|Trigger deploy| DEPLOYER
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
%% External & Storage
|
|
31
|
+
subgraph Storage_and_Network [Storage & External]
|
|
32
|
+
GH_REPOS[GitHub (intisy/plugin-*)]
|
|
33
|
+
LOCAL_WORKSPACE[(.config/github/repos/intisy/)]
|
|
34
|
+
CC_PLUGINS[(.claude/plugin/)]
|
|
35
|
+
OC_PLUGINS[(.config/opencode/plugin/)]
|
|
36
|
+
|
|
37
|
+
GIT_MGR <-->|git clone/pull| GH_REPOS
|
|
38
|
+
GIT_MGR -->|Updates source| LOCAL_WORKSPACE
|
|
39
|
+
DEPLOYER -->|Copies compiled output| CC_PLUGINS
|
|
40
|
+
DEPLOYER -->|Copies compiled output| OC_PLUGINS
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
| Method | Description |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `rebuild(pluginItem)` | Pull latest and redeploy |
|
|
49
|
+
| `downgrade(pluginItem, commitHash)` | Checkout specific commit |
|
|
50
|
+
| `disable(pluginItem)` | Cleanup on disable |
|
|
51
|
+
| `uninstall(pluginItem)` | Remove repo and deployed files |
|
|
52
|
+
| `registerTests(testApi)` | Register sync verification tests |
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
MIT
|
package/index.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
const REPOS_DIR = path.join(require('os').homedir(), '.config', 'github');
|
|
6
|
+
|
|
7
|
+
function executeGit(cmd, dir) {
|
|
8
|
+
try {
|
|
9
|
+
return execSync(cmd, { cwd: dir, timeout: 60000, stdio: "ignore" });
|
|
10
|
+
} catch (e) {
|
|
11
|
+
console.error(`[Updater] Git command failed: ${cmd} in ${dir}`);
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
name: "plugin-updater",
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Called by the launcher (OpenCode/Claude Code) to sync a specific plugin
|
|
21
|
+
*/
|
|
22
|
+
updatePlugin: function(pluginName, gitUrl, branch = null, commitHash = null) {
|
|
23
|
+
const targetDir = path.join(REPOS_DIR, pluginName);
|
|
24
|
+
|
|
25
|
+
// 1. Ensure directory exists and clone or pull
|
|
26
|
+
if (!fs.existsSync(targetDir)) {
|
|
27
|
+
if (!fs.existsSync(REPOS_DIR)) fs.mkdirSync(REPOS_DIR, { recursive: true });
|
|
28
|
+
const branchFlag = branch ? `--branch ${branch}` : "";
|
|
29
|
+
executeGit(`git clone --recurse-submodules ${branchFlag} ${gitUrl} ${pluginName}`, REPOS_DIR);
|
|
30
|
+
} else {
|
|
31
|
+
executeGit("git fetch origin", targetDir);
|
|
32
|
+
if (commitHash) {
|
|
33
|
+
executeGit(`git checkout ${commitHash}`, targetDir);
|
|
34
|
+
} else if (branch) {
|
|
35
|
+
executeGit(`git checkout ${branch}`, targetDir);
|
|
36
|
+
executeGit(`git pull --ff-only origin ${branch}`, targetDir);
|
|
37
|
+
} else {
|
|
38
|
+
executeGit("git checkout main || git checkout master", targetDir);
|
|
39
|
+
executeGit("git pull --ff-only", targetDir);
|
|
40
|
+
}
|
|
41
|
+
executeGit("git submodule update --init --recursive", targetDir);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return true;
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Called to deploy the compiled output to the execution directory
|
|
49
|
+
*/
|
|
50
|
+
deployToExecutionDir: function(pluginName, executionPath) {
|
|
51
|
+
const sourceDir = path.join(REPOS_DIR, pluginName);
|
|
52
|
+
if (!fs.existsSync(sourceDir)) return false;
|
|
53
|
+
|
|
54
|
+
// Build if package.json exists
|
|
55
|
+
if (fs.existsSync(path.join(sourceDir, "package.json"))) {
|
|
56
|
+
try {
|
|
57
|
+
execSync("npm install", { cwd: sourceDir, stdio: "ignore" });
|
|
58
|
+
execSync("npm run build", { cwd: sourceDir, stdio: "ignore" });
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// Fallback or ignore if no build step
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Determine deployment source (prefer dist, fallback to root)
|
|
65
|
+
const distPath = path.join(sourceDir, "dist");
|
|
66
|
+
const deploySource = fs.existsSync(distPath) ? distPath : sourceDir;
|
|
67
|
+
|
|
68
|
+
// Copy to execution path
|
|
69
|
+
if (!fs.existsSync(executionPath)) {
|
|
70
|
+
fs.mkdirSync(executionPath, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
// Platform agnostic copy (using Node fs)
|
|
75
|
+
fs.cpSync(deploySource, executionPath, { recursive: true, force: true });
|
|
76
|
+
return true;
|
|
77
|
+
} catch (e) {
|
|
78
|
+
console.error(`[Updater] Deploy failed: ${e.message}`);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Specific logic to install/update the launcher itself
|
|
85
|
+
*/
|
|
86
|
+
installLauncher: function() {
|
|
87
|
+
// Logic to install opencode-hub / claude-hub if they are missing
|
|
88
|
+
this.updatePlugin("core-hub", "https://github.com/intisy/core-hub.git");
|
|
89
|
+
this.updatePlugin("opencode-hub", "https://github.com/intisy/opencode-hub.git");
|
|
90
|
+
this.updatePlugin("claude-hub", "https://github.com/intisy/claude-hub.git");
|
|
91
|
+
}
|
|
92
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "plugin-updater",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Plugin lifecycle manager for OpenCode and Claude Code launchers",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "intisy",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/intisy/plugin-updater.git"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["opencode", "claude", "plugin", "updater", "lifecycle"]
|
|
13
|
+
}
|