aicq-chat-plugin 2.5.0 → 2.5.1

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/cli.js CHANGED
@@ -3,14 +3,18 @@
3
3
  * AICQ Chat Plugin — CLI Entry Point
4
4
  *
5
5
  * Usage:
6
- * aicq-plugin Start the plugin server (default port 6109)
7
- * aicq-plugin start Start the plugin server
8
- * aicq-plugin status Check plugin status
9
- * aicq-plugin --port Specify port (default 6109)
10
- * aicq-plugin --help Show help
6
+ * npx aicq-chat-plugin Start plugin + auto-install to OpenClaw
7
+ * aicq-plugin Same as above
8
+ * aicq-plugin start Start the plugin server
9
+ * aicq-plugin install Install plugin to OpenClaw only
10
+ * aicq-plugin status Check plugin status
11
+ * aicq-plugin --port <port> Specify port (default 6109)
12
+ * aicq-plugin --help Show help
11
13
  */
12
- const { spawn } = require('child_process');
14
+ const { spawn, execSync } = require('child_process');
15
+ const fs = require('fs');
13
16
  const path = require('path');
17
+ const os = require('os');
14
18
 
15
19
  const args = process.argv.slice(2);
16
20
  const command = args[0] || 'start';
@@ -30,15 +34,137 @@ for (let i = 0; i < args.length; i++) {
30
34
  }
31
35
  }
32
36
 
37
+ // ── Find OpenClaw installation ──────────────────────────────────────
38
+ function findOpenClawDir() {
39
+ const candidates = [
40
+ path.join(os.homedir(), '.openclaw'),
41
+ path.join(os.homedir(), 'openclaw'),
42
+ path.join(os.homedir(), '.config', 'openclaw'),
43
+ ];
44
+ if (process.env.OPENCLAW_HOME) {
45
+ candidates.unshift(process.env.OPENCLAW_HOME);
46
+ }
47
+ for (const dir of candidates) {
48
+ if (fs.existsSync(dir)) return dir;
49
+ }
50
+ return null;
51
+ }
52
+
53
+ // ── Copy plugin files to OpenClaw plugins directory ─────────────────
54
+ function installToOpenClaw() {
55
+ const openclawDir = findOpenClawDir();
56
+ if (!openclawDir) {
57
+ console.log('[AICQ] OpenClaw not found, skipping auto-install.');
58
+ console.log('[AICQ] If you have OpenClaw installed, set OPENCLAW_HOME environment variable.');
59
+ return false;
60
+ }
61
+
62
+ const PLUGIN_ID = 'aicq-chat';
63
+ const pluginsDir = path.join(openclawDir, 'plugins');
64
+ const targetDir = path.join(pluginsDir, PLUGIN_ID);
65
+ const sourceDir = path.resolve(__dirname);
66
+
67
+ // Check if already installed and up-to-date
68
+ const targetPluginJson = path.join(targetDir, 'openclaw.plugin.json');
69
+ if (fs.existsSync(targetPluginJson)) {
70
+ try {
71
+ const existing = JSON.parse(fs.readFileSync(targetPluginJson, 'utf8'));
72
+ const current = JSON.parse(fs.readFileSync(path.join(sourceDir, 'openclaw.plugin.json'), 'utf8'));
73
+ if (existing.version === current.version) {
74
+ console.log(`[AICQ] Plugin already installed at ${targetDir} (v${current.version})`);
75
+ return true;
76
+ }
77
+ } catch (e) {}
78
+ }
79
+
80
+ console.log(`[AICQ] Found OpenClaw at: ${openclawDir}`);
81
+ console.log(`[AICQ] Installing plugin to ${targetDir}...`);
82
+
83
+ // Create plugins directory if needed
84
+ if (!fs.existsSync(pluginsDir)) {
85
+ fs.mkdirSync(pluginsDir, { recursive: true });
86
+ }
87
+
88
+ // Files and dirs to copy
89
+ const filesToCopy = [
90
+ 'index.js', 'cli.js', 'postinstall.js',
91
+ 'openclaw.plugin.json', 'package.json', 'README.md',
92
+ ];
93
+ const dirsToCopy = ['lib', 'public'];
94
+
95
+ // Create target directory
96
+ if (!fs.existsSync(targetDir)) {
97
+ fs.mkdirSync(targetDir, { recursive: true });
98
+ }
99
+
100
+ // Copy files
101
+ for (const file of filesToCopy) {
102
+ const src = path.join(sourceDir, file);
103
+ const dest = path.join(targetDir, file);
104
+ if (fs.existsSync(src)) {
105
+ fs.copyFileSync(src, dest);
106
+ }
107
+ }
108
+
109
+ // Copy directories
110
+ for (const dir of dirsToCopy) {
111
+ const src = path.join(sourceDir, dir);
112
+ const dest = path.join(targetDir, dir);
113
+ if (fs.existsSync(src)) {
114
+ if (fs.existsSync(dest)) {
115
+ fs.rmSync(dest, { recursive: true, force: true });
116
+ }
117
+ copyDirRecursive(src, dest);
118
+ }
119
+ }
120
+
121
+ // Install npm dependencies in target
122
+ console.log('[AICQ] Installing plugin dependencies...');
123
+ try {
124
+ execSync('npm install --production', {
125
+ cwd: targetDir,
126
+ stdio: 'pipe',
127
+ timeout: 120000,
128
+ });
129
+ console.log('[AICQ] Dependencies installed.');
130
+ } catch (e) {
131
+ console.log('[AICQ] Warning: npm install failed. You may need to run manually:');
132
+ console.log(` cd ${targetDir} && npm install`);
133
+ }
134
+
135
+ console.log(`[AICQ] Plugin installed to: ${targetDir}`);
136
+ console.log('[AICQ] Restart OpenClaw to activate the plugin.');
137
+ return true;
138
+ }
139
+
140
+ // ── Recursively copy a directory ────────────────────────────────────
141
+ function copyDirRecursive(src, dest) {
142
+ fs.mkdirSync(dest, { recursive: true });
143
+ const entries = fs.readdirSync(src, { withFileTypes: true });
144
+ for (const entry of entries) {
145
+ const srcPath = path.join(src, entry.name);
146
+ const destPath = path.join(dest, entry.name);
147
+ if (entry.isDirectory()) {
148
+ if (entry.name === 'node_modules') continue;
149
+ copyDirRecursive(srcPath, destPath);
150
+ } else {
151
+ fs.copyFileSync(srcPath, destPath);
152
+ }
153
+ }
154
+ }
155
+
156
+ // ── Help ────────────────────────────────────────────────────────────
33
157
  if (command === '--help' || command === '-h') {
34
158
  console.log(`
35
159
  AICQ Chat Plugin — End-to-End Encrypted Chat for OpenClaw
36
160
 
37
161
  Usage:
162
+ npx aicq-chat-plugin Start plugin + auto-install to OpenClaw
38
163
  aicq-plugin [command] [options]
39
164
 
40
165
  Commands:
41
- start Start the plugin server (default)
166
+ start Install to OpenClaw (if needed) and start plugin server (default)
167
+ install Install plugin to OpenClaw only (don't start server)
42
168
  status Check if the plugin is running
43
169
 
44
170
  Options:
@@ -50,15 +176,19 @@ Environment Variables:
50
176
  AICQ_PORT Plugin server port
51
177
  AICQ_SERVER_URL AICQ server URL
52
178
  AICQ_DATA_DIR Data directory (default: ~/.aicq-plugin)
179
+ OPENCLAW_HOME OpenClaw installation directory
53
180
 
54
181
  Examples:
55
- aicq-plugin # Start on default port
56
- aicq-plugin --port 8080 # Start on port 8080
57
- aicq-plugin -s http://localhost # Connect to local server
182
+ npx aicq-chat-plugin # Install + start
183
+ aicq-plugin # Start on default port
184
+ aicq-plugin install # Install to OpenClaw only
185
+ aicq-plugin --port 8080 # Start on port 8080
186
+ aicq-plugin -s http://localhost # Connect to local server
58
187
  `);
59
188
  process.exit(0);
60
189
  }
61
190
 
191
+ // ── Status ──────────────────────────────────────────────────────────
62
192
  if (command === 'status') {
63
193
  const http = require('http');
64
194
  const req = http.get(`http://localhost:${port}/api/status`, (res) => {
@@ -80,7 +210,7 @@ if (command === 'status') {
80
210
  });
81
211
  req.on('error', () => {
82
212
  console.log(`AICQ Plugin is not running on port ${port}.`);
83
- console.log(`Start it with: aicq-plugin --port ${port}`);
213
+ console.log(`Start it with: npx aicq-chat-plugin`);
84
214
  });
85
215
  req.setTimeout(3000, () => {
86
216
  req.destroy();
@@ -89,7 +219,15 @@ if (command === 'status') {
89
219
  process.exit(0);
90
220
  }
91
221
 
92
- // Start the plugin server
222
+ // ── Install only ────────────────────────────────────────────────────
223
+ if (command === 'install') {
224
+ installToOpenClaw();
225
+ process.exit(0);
226
+ }
227
+
228
+ // ── Start (default) — auto-install then run ─────────────────────────
229
+ installToOpenClaw();
230
+
93
231
  console.log(`[AICQ] Starting plugin on port ${port}`);
94
232
  console.log(`[AICQ] Server: ${serverUrl}`);
95
233
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "aicq-chat",
3
3
  "name": "AICQ Encrypted Chat",
4
- "version": "2.5.0",
4
+ "version": "2.5.1",
5
5
  "description": "End-to-end encrypted chat plugin for OpenClaw agents — Node.js implementation with full UI",
6
6
  "entry": "index.js",
7
7
  "activation": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicq-chat-plugin",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "AICQ End-to-end Encrypted Chat Plugin for OpenClaw — Full UI with friend management, group chat, file transfer, and AI agent communication",
5
5
  "main": "index.js",
6
6
  "bin": {