@yeaft/webchat-agent 0.1.243 → 0.1.245

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.
Files changed (2) hide show
  1. package/index.js +83 -5
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'dotenv/config';
2
2
  import { platform, homedir } from 'os';
3
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, cpSync } from 'fs';
4
4
  import { join, dirname } from 'path';
5
5
  import { exec } from 'child_process';
6
6
  import { promisify } from 'util';
@@ -141,21 +141,37 @@ async function ensureDependencies() {
141
141
  // 确保 yeaft-skills 插件已安装到 Claude CLI plugin 系统并注册为 marketplace
142
142
  async function ensureYeaftSkills() {
143
143
  const MARKETPLACE_NAME = 'yeaft-skills-dev';
144
+ const PLUGIN_NAME = 'yeaft-skills';
145
+ const PLUGIN_KEY = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
146
+ const PLUGIN_VERSION = '0.1.0';
144
147
  const REPO_URL = 'https://github.com/yeaft/yeaft-skills.git';
145
- const pluginsDir = join(homedir(), '.claude', 'plugins');
148
+ const claudeDir = join(homedir(), '.claude');
149
+ const pluginsDir = join(claudeDir, 'plugins');
146
150
  const marketplacesDir = join(pluginsDir, 'marketplaces');
147
151
  const installDir = join(marketplacesDir, MARKETPLACE_NAME);
148
152
  const knownFile = join(pluginsDir, 'known_marketplaces.json');
153
+ const installedFile = join(pluginsDir, 'installed_plugins.json');
154
+ const settingsFile = join(claudeDir, 'settings.json');
155
+ const cacheDir = join(pluginsDir, 'cache', MARKETPLACE_NAME, PLUGIN_NAME, PLUGIN_VERSION);
149
156
 
150
157
  try {
151
- // Clone or update the marketplace repo
158
+ // --- Layer 1: Clone or update the marketplace repo ---
159
+ let gitSha = '';
160
+ let needsCacheUpdate = false;
152
161
  if (!existsSync(installDir)) {
153
162
  console.log('[Startup] yeaft-skills not found, installing as marketplace plugin...');
154
163
  mkdirSync(marketplacesDir, { recursive: true });
155
164
  await execAsync(`git clone ${REPO_URL} "${installDir}"`, { timeout: 60000 });
165
+ needsCacheUpdate = true;
156
166
  console.log('[Startup] yeaft-skills installed');
157
167
  } else {
158
168
  console.log('[Startup] yeaft-skills found, checking for updates...');
169
+ // Record HEAD before pull to detect changes
170
+ let headBefore = '';
171
+ try {
172
+ const { stdout: h } = await execAsync('git rev-parse HEAD', { cwd: installDir, timeout: 5000 });
173
+ headBefore = h.trim();
174
+ } catch { /* ignore */ }
159
175
  const { stdout } = await execAsync('git pull --ff-only', {
160
176
  cwd: installDir,
161
177
  timeout: 30000
@@ -163,11 +179,24 @@ async function ensureYeaftSkills() {
163
179
  if (stdout.includes('Already up to date')) {
164
180
  console.log('[Startup] yeaft-skills is up to date');
165
181
  } else {
182
+ needsCacheUpdate = true;
166
183
  console.log('[Startup] yeaft-skills updated');
167
184
  }
185
+ // Double-check: compare HEAD after pull
186
+ if (!needsCacheUpdate && headBefore) {
187
+ try {
188
+ const { stdout: h2 } = await execAsync('git rev-parse HEAD', { cwd: installDir, timeout: 5000 });
189
+ if (h2.trim() !== headBefore) needsCacheUpdate = true;
190
+ } catch { /* ignore */ }
191
+ }
168
192
  }
193
+ // Get current commit SHA for installed_plugins.json
194
+ try {
195
+ const { stdout: sha } = await execAsync('git rev-parse HEAD', { cwd: installDir, timeout: 5000 });
196
+ gitSha = sha.trim();
197
+ } catch { /* non-critical */ }
169
198
 
170
- // Register in known_marketplaces.json (idempotent)
199
+ // --- Layer 2: Register in known_marketplaces.json (idempotent) ---
171
200
  let known = {};
172
201
  if (existsSync(knownFile)) {
173
202
  try {
@@ -183,11 +212,60 @@ async function ensureYeaftSkills() {
183
212
  writeFileSync(knownFile, JSON.stringify(known, null, 2));
184
213
  console.log('[Startup] yeaft-skills registered in known_marketplaces.json');
185
214
  } else {
186
- // Update lastUpdated timestamp
187
215
  known[MARKETPLACE_NAME].lastUpdated = new Date().toISOString();
188
216
  known[MARKETPLACE_NAME].installLocation = installDir;
189
217
  writeFileSync(knownFile, JSON.stringify(known, null, 2));
190
218
  }
219
+
220
+ // --- Layer 3: Copy to plugin cache (on first install or after update) ---
221
+ if (!existsSync(cacheDir) || needsCacheUpdate) {
222
+ mkdirSync(cacheDir, { recursive: true });
223
+ cpSync(installDir, cacheDir, { recursive: true });
224
+ console.log(`[Startup] yeaft-skills ${needsCacheUpdate ? 'updated in' : 'copied to'} plugin cache`);
225
+ }
226
+
227
+ // --- Layer 4: Register in installed_plugins.json ---
228
+ let installed = { version: 2, plugins: {} };
229
+ if (existsSync(installedFile)) {
230
+ try {
231
+ installed = JSON.parse(readFileSync(installedFile, 'utf-8'));
232
+ } catch { /* corrupted, will recreate */ }
233
+ }
234
+ if (!installed.plugins) installed.plugins = {};
235
+ if (!installed.plugins[PLUGIN_KEY]) {
236
+ const now = new Date().toISOString();
237
+ installed.plugins[PLUGIN_KEY] = [{
238
+ scope: 'user',
239
+ installPath: cacheDir,
240
+ version: PLUGIN_VERSION,
241
+ installedAt: now,
242
+ lastUpdated: now,
243
+ ...(gitSha ? { gitCommitSha: gitSha } : {})
244
+ }];
245
+ writeFileSync(installedFile, JSON.stringify(installed, null, 2));
246
+ console.log('[Startup] yeaft-skills registered in installed_plugins.json');
247
+ }
248
+
249
+ // --- Layer 5: Enable in settings.json ---
250
+ // Read existing settings; on parse failure skip to avoid losing user config
251
+ let settings = null;
252
+ if (existsSync(settingsFile)) {
253
+ try {
254
+ settings = JSON.parse(readFileSync(settingsFile, 'utf-8'));
255
+ } catch {
256
+ console.warn('[Startup] settings.json corrupted, skipping enabledPlugins write');
257
+ }
258
+ } else {
259
+ settings = {};
260
+ }
261
+ if (settings !== null) {
262
+ if (!settings.enabledPlugins) settings.enabledPlugins = {};
263
+ if (!settings.enabledPlugins[PLUGIN_KEY]) {
264
+ settings.enabledPlugins[PLUGIN_KEY] = true;
265
+ writeFileSync(settingsFile, JSON.stringify(settings, null, 2));
266
+ console.log('[Startup] yeaft-skills enabled in settings.json');
267
+ }
268
+ }
191
269
  } catch (e) {
192
270
  console.warn('[Startup] yeaft-skills sync failed (skills will be unavailable):', e.message);
193
271
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.243",
3
+ "version": "0.1.245",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",