wave-agent-sdk 0.14.0 → 0.14.2
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/builtin/skills/settings/HOOKS.md +69 -0
- package/builtin/skills/settings/PLUGINS.md +171 -0
- package/builtin/skills/settings/SKILL.md +8 -3
- package/dist/agent.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +12 -3
- package/dist/core/plugin.d.ts +2 -2
- package/dist/core/plugin.d.ts.map +1 -1
- package/dist/core/plugin.js +7 -7
- package/dist/managers/aiManager.d.ts +6 -6
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +122 -59
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +28 -30
- package/dist/managers/hookManager.d.ts +16 -1
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +97 -8
- package/dist/managers/messageManager.d.ts +19 -4
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +63 -18
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +1 -1
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +1 -1
- package/dist/services/MarketplaceService.d.ts +42 -12
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +225 -105
- package/dist/services/aiService.d.ts +3 -3
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +7 -7
- package/dist/services/configurationService.d.ts +17 -1
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +104 -0
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +15 -0
- package/dist/services/initializationService.d.ts.map +1 -1
- package/dist/services/initializationService.js +24 -1
- package/dist/services/interactionService.js +1 -1
- package/dist/services/pluginLoader.d.ts.map +1 -1
- package/dist/services/pluginLoader.js +7 -1
- package/dist/services/session.d.ts +1 -1
- package/dist/services/session.js +7 -7
- package/dist/services/taskManager.d.ts +1 -1
- package/dist/services/taskManager.js +1 -1
- package/dist/types/configuration.d.ts +7 -0
- package/dist/types/configuration.d.ts.map +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +9 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +2 -0
- package/dist/types/marketplace.d.ts +2 -0
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/messaging.d.ts +3 -3
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.d.ts +1 -1
- package/dist/utils/convertMessagesForAPI.js +7 -7
- package/dist/utils/groupMessagesByApiRound.d.ts +1 -1
- package/dist/utils/groupMessagesByApiRound.js +6 -6
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +3 -3
- package/package.json +1 -1
- package/src/agent.ts +16 -3
- package/src/core/plugin.ts +13 -7
- package/src/managers/aiManager.ts +142 -63
- package/src/managers/backgroundTaskManager.ts +33 -42
- package/src/managers/hookManager.ts +125 -10
- package/src/managers/messageManager.ts +76 -22
- package/src/managers/pluginManager.ts +4 -1
- package/src/prompts/index.ts +1 -1
- package/src/services/MarketplaceService.ts +301 -111
- package/src/services/aiService.ts +11 -11
- package/src/services/configurationService.ts +131 -0
- package/src/services/hook.ts +17 -0
- package/src/services/initializationService.ts +33 -1
- package/src/services/interactionService.ts +1 -1
- package/src/services/pluginLoader.ts +7 -1
- package/src/services/session.ts +7 -7
- package/src/services/taskManager.ts +1 -1
- package/src/types/configuration.ts +8 -0
- package/src/types/core.ts +1 -1
- package/src/types/hooks.ts +16 -2
- package/src/types/marketplace.ts +2 -0
- package/src/types/messaging.ts +3 -3
- package/src/utils/convertMessagesForAPI.ts +8 -8
- package/src/utils/groupMessagesByApiRound.ts +6 -6
- package/src/utils/messageOperations.ts +3 -5
|
@@ -3,14 +3,21 @@ import * as path from "path";
|
|
|
3
3
|
import * as crypto from "crypto";
|
|
4
4
|
import { getPluginsDir } from "../utils/configPaths.js";
|
|
5
5
|
import { GitService } from "./GitService.js";
|
|
6
|
+
import { ConfigurationService } from "./configurationService.js";
|
|
7
|
+
import { logger } from "../utils/globalLogger.js";
|
|
6
8
|
/**
|
|
7
9
|
* Marketplace Service
|
|
8
10
|
*
|
|
9
11
|
* Handles local plugin marketplace registration, plugin installation,
|
|
10
12
|
* and state management for installed plugins.
|
|
13
|
+
*
|
|
14
|
+
* Marketplace declarations are now scoped (user/project/local) via settings files.
|
|
15
|
+
* known_marketplaces.json is kept as a cache for installLocation/lastUpdated metadata.
|
|
11
16
|
*/
|
|
12
17
|
export class MarketplaceService {
|
|
13
|
-
constructor() {
|
|
18
|
+
constructor(workdir = process.cwd(), configurationService = new ConfigurationService()) {
|
|
19
|
+
this.workdir = workdir;
|
|
20
|
+
this.configurationService = configurationService;
|
|
14
21
|
this.pluginsDir = getPluginsDir();
|
|
15
22
|
this.knownMarketplacesPath = path.join(this.pluginsDir, "known_marketplaces.json");
|
|
16
23
|
this.installedPluginsPath = path.join(this.pluginsDir, "installed_plugins.json");
|
|
@@ -20,6 +27,7 @@ export class MarketplaceService {
|
|
|
20
27
|
this.marketplacesDir = path.join(this.pluginsDir, "marketplaces");
|
|
21
28
|
this.gitService = new GitService();
|
|
22
29
|
this.ensureDirectoryStructure();
|
|
30
|
+
this.runMigration();
|
|
23
31
|
}
|
|
24
32
|
/**
|
|
25
33
|
* Ensures the required directory structure exists in ~/.wave/plugins
|
|
@@ -31,6 +39,32 @@ export class MarketplaceService {
|
|
|
31
39
|
}
|
|
32
40
|
});
|
|
33
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Backwards compatibility migration: migrate entries from known_marketplaces.json
|
|
44
|
+
* to user-level settings if they aren't already declared there.
|
|
45
|
+
*/
|
|
46
|
+
async runMigration() {
|
|
47
|
+
try {
|
|
48
|
+
const cacheRegistry = await this.getCacheRegistry();
|
|
49
|
+
const scopedMarketplaces = this.configurationService.getMergedMarketplaces(this.workdir);
|
|
50
|
+
const userMarketplaces = this.configurationService.getScopedMarketplaces(this.workdir, "user");
|
|
51
|
+
const entriesToMigrate = (cacheRegistry?.marketplaces ?? []).filter((m) => !scopedMarketplaces[m.name] && !userMarketplaces[m.name]);
|
|
52
|
+
if (entriesToMigrate.length > 0) {
|
|
53
|
+
for (const m of entriesToMigrate) {
|
|
54
|
+
if (m.name === MarketplaceService.BUILTIN_MARKETPLACE.name)
|
|
55
|
+
continue;
|
|
56
|
+
const config = {
|
|
57
|
+
source: m.source,
|
|
58
|
+
autoUpdate: m.autoUpdate,
|
|
59
|
+
};
|
|
60
|
+
await this.configurationService.addMarketplaceToScope(this.workdir, "user", m.name, config);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Migration failure should not block startup
|
|
66
|
+
}
|
|
67
|
+
}
|
|
34
68
|
/**
|
|
35
69
|
* Check if a lock file is stale by reading its PID and checking if the process is alive.
|
|
36
70
|
* Returns true if the lock is stale and safe to remove.
|
|
@@ -41,17 +75,16 @@ export class MarketplaceService {
|
|
|
41
75
|
const pid = parseInt(content.trim(), 10);
|
|
42
76
|
if (isNaN(pid))
|
|
43
77
|
return true;
|
|
44
|
-
// Check if the process is still running
|
|
45
78
|
try {
|
|
46
79
|
process.kill(pid, 0);
|
|
47
|
-
return false;
|
|
80
|
+
return false;
|
|
48
81
|
}
|
|
49
82
|
catch {
|
|
50
|
-
return true;
|
|
83
|
+
return true;
|
|
51
84
|
}
|
|
52
85
|
}
|
|
53
86
|
catch {
|
|
54
|
-
return true;
|
|
87
|
+
return true;
|
|
55
88
|
}
|
|
56
89
|
}
|
|
57
90
|
/**
|
|
@@ -63,7 +96,7 @@ export class MarketplaceService {
|
|
|
63
96
|
return await fn();
|
|
64
97
|
}
|
|
65
98
|
let lockFd;
|
|
66
|
-
const maxRetries = 600;
|
|
99
|
+
const maxRetries = 600;
|
|
67
100
|
const retryDelay = 100;
|
|
68
101
|
for (let i = 0; i < maxRetries; i++) {
|
|
69
102
|
try {
|
|
@@ -75,7 +108,6 @@ export class MarketplaceService {
|
|
|
75
108
|
typeof error === "object" &&
|
|
76
109
|
"code" in error &&
|
|
77
110
|
error.code === "EEXIST") {
|
|
78
|
-
// Check for stale lock every 60 retries (every ~6 seconds)
|
|
79
111
|
if (i > 0 && i % 60 === 0) {
|
|
80
112
|
const stale = await this.isStaleLock();
|
|
81
113
|
if (stale) {
|
|
@@ -92,7 +124,6 @@ export class MarketplaceService {
|
|
|
92
124
|
if (!lockFd) {
|
|
93
125
|
throw new Error(`Failed to acquire marketplace lock after ${maxRetries} retries. If no other wave-agent process is running, please delete ${this.lockPath}`);
|
|
94
126
|
}
|
|
95
|
-
// Write PID into the lock file for stale lock detection
|
|
96
127
|
await fs.writeFile(this.lockPath, String(process.pid), "utf-8");
|
|
97
128
|
MarketplaceService.isLockedInProcess = true;
|
|
98
129
|
try {
|
|
@@ -105,37 +136,86 @@ export class MarketplaceService {
|
|
|
105
136
|
}
|
|
106
137
|
}
|
|
107
138
|
/**
|
|
108
|
-
* Loads the
|
|
139
|
+
* Loads the cache registry from known_marketplaces.json
|
|
140
|
+
* Returns null if the file doesn't exist or has no parseable content (for first-run detection).
|
|
109
141
|
*/
|
|
110
|
-
async
|
|
142
|
+
async getCacheRegistry() {
|
|
111
143
|
if (!existsSync(this.knownMarketplacesPath)) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const content = await fs.readFile(this.knownMarketplacesPath, "utf-8");
|
|
148
|
+
if (!content.trim()) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return JSON.parse(content);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Legacy method: loads known marketplaces with builtin injection.
|
|
159
|
+
* @deprecated Use listMarketplaces() instead, which combines scoped settings.
|
|
160
|
+
*/
|
|
161
|
+
async getKnownMarketplaces() {
|
|
162
|
+
const cache = await this.getCacheRegistry();
|
|
163
|
+
// If cache is null (file doesn't exist or has no parseable content), inject builtin
|
|
164
|
+
if (cache === null) {
|
|
112
165
|
return {
|
|
113
166
|
marketplaces: [
|
|
114
167
|
{
|
|
115
168
|
...MarketplaceService.BUILTIN_MARKETPLACE,
|
|
116
169
|
isBuiltin: true,
|
|
170
|
+
declaredScope: "builtin",
|
|
117
171
|
},
|
|
118
172
|
],
|
|
119
173
|
};
|
|
120
174
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
175
|
+
// File has valid JSON - respect user's explicit choice even if empty
|
|
176
|
+
const hasBuiltin = cache.marketplaces.some((m) => m.name === MarketplaceService.BUILTIN_MARKETPLACE.name);
|
|
177
|
+
return {
|
|
178
|
+
marketplaces: cache.marketplaces.map((m) => ({
|
|
179
|
+
...m,
|
|
180
|
+
isBuiltin: m.isBuiltin || m.name === MarketplaceService.BUILTIN_MARKETPLACE.name,
|
|
181
|
+
declaredScope: m.declaredScope ?? (hasBuiltin ? "builtin" : "user"),
|
|
182
|
+
})),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Updates the cache registry with metadata for a marketplace
|
|
187
|
+
*/
|
|
188
|
+
async updateCacheMarketplace(name, metadata) {
|
|
189
|
+
const registry = await this.getCacheRegistry();
|
|
190
|
+
const marketplaces = registry?.marketplaces ?? [];
|
|
191
|
+
const existingIndex = marketplaces.findIndex((m) => m.name === name);
|
|
192
|
+
if (existingIndex >= 0) {
|
|
193
|
+
marketplaces[existingIndex] = {
|
|
194
|
+
...marketplaces[existingIndex],
|
|
195
|
+
...metadata,
|
|
196
|
+
};
|
|
134
197
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
198
|
+
else {
|
|
199
|
+
marketplaces.push({
|
|
200
|
+
name,
|
|
201
|
+
source: metadata.source || { source: "directory", path: "" },
|
|
202
|
+
...metadata,
|
|
203
|
+
});
|
|
138
204
|
}
|
|
205
|
+
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
206
|
+
await fs.writeFile(tmpPath, JSON.stringify({ marketplaces }, null, 2));
|
|
207
|
+
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Removes a marketplace from the cache registry
|
|
211
|
+
*/
|
|
212
|
+
async removeFromCache(name) {
|
|
213
|
+
const registry = await this.getCacheRegistry();
|
|
214
|
+
const marketplaces = registry?.marketplaces ?? [];
|
|
215
|
+
const filtered = marketplaces.filter((m) => m.name !== name);
|
|
216
|
+
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
217
|
+
await fs.writeFile(tmpPath, JSON.stringify({ marketplaces: filtered }, null, 2));
|
|
218
|
+
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
139
219
|
}
|
|
140
220
|
/**
|
|
141
221
|
* Loads the installed plugins registry
|
|
@@ -156,14 +236,6 @@ export class MarketplaceService {
|
|
|
156
236
|
return { plugins: [] };
|
|
157
237
|
}
|
|
158
238
|
}
|
|
159
|
-
/**
|
|
160
|
-
* Saves the known marketplaces registry
|
|
161
|
-
*/
|
|
162
|
-
async saveKnownMarketplaces(registry) {
|
|
163
|
-
const tmpPath = `${this.knownMarketplacesPath}.tmp`;
|
|
164
|
-
await fs.writeFile(tmpPath, JSON.stringify(registry, null, 2));
|
|
165
|
-
await fs.rename(tmpPath, this.knownMarketplacesPath);
|
|
166
|
-
}
|
|
167
239
|
/**
|
|
168
240
|
* Saves the installed plugins registry
|
|
169
241
|
*/
|
|
@@ -182,7 +254,6 @@ export class MarketplaceService {
|
|
|
182
254
|
}
|
|
183
255
|
const content = await fs.readFile(manifestPath, "utf-8");
|
|
184
256
|
const manifest = JSON.parse(content);
|
|
185
|
-
// Basic validation
|
|
186
257
|
if (!manifest.name ||
|
|
187
258
|
!manifest.plugins ||
|
|
188
259
|
!Array.isArray(manifest.plugins)) {
|
|
@@ -193,26 +264,49 @@ export class MarketplaceService {
|
|
|
193
264
|
/**
|
|
194
265
|
* Resolves the local path for a marketplace
|
|
195
266
|
*/
|
|
196
|
-
getMarketplacePath(
|
|
197
|
-
if (
|
|
198
|
-
return
|
|
267
|
+
getMarketplacePath(source) {
|
|
268
|
+
if (source.source === "directory") {
|
|
269
|
+
return source.path;
|
|
199
270
|
}
|
|
200
|
-
else if (
|
|
201
|
-
return path.join(this.marketplacesDir,
|
|
271
|
+
else if (source.source === "github") {
|
|
272
|
+
return path.join(this.marketplacesDir, source.repo);
|
|
202
273
|
}
|
|
203
274
|
else {
|
|
204
|
-
|
|
205
|
-
const hash = crypto
|
|
206
|
-
.createHash("md5")
|
|
207
|
-
.update(marketplace.source.url)
|
|
208
|
-
.digest("hex");
|
|
275
|
+
const hash = crypto.createHash("md5").update(source.url).digest("hex");
|
|
209
276
|
return path.join(this.marketplacesDir, hash);
|
|
210
277
|
}
|
|
211
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Builds a KnownMarketplace from a scoped config, enriched with cache metadata
|
|
281
|
+
*/
|
|
282
|
+
async buildMarketplaceEntry(name, config, cache, declaredScope) {
|
|
283
|
+
return {
|
|
284
|
+
name,
|
|
285
|
+
source: config.source,
|
|
286
|
+
autoUpdate: config.autoUpdate ?? cache?.autoUpdate,
|
|
287
|
+
lastUpdated: cache?.lastUpdated,
|
|
288
|
+
isBuiltin: name === MarketplaceService.BUILTIN_MARKETPLACE.name,
|
|
289
|
+
declaredScope,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Finds which scope declared a marketplace (user, project, local, or builtin)
|
|
294
|
+
*/
|
|
295
|
+
getMarketplaceDeclaringSource(name) {
|
|
296
|
+
if (name === MarketplaceService.BUILTIN_MARKETPLACE.name)
|
|
297
|
+
return "builtin";
|
|
298
|
+
const scopes = ["local", "project", "user"];
|
|
299
|
+
for (const scope of scopes) {
|
|
300
|
+
const scoped = this.configurationService.getScopedMarketplaces(this.workdir, scope);
|
|
301
|
+
if (scoped[name])
|
|
302
|
+
return scope;
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
212
306
|
/**
|
|
213
307
|
* Adds a new marketplace (local directory, GitHub repo, or Git URL)
|
|
214
308
|
*/
|
|
215
|
-
async addMarketplace(input) {
|
|
309
|
+
async addMarketplace(input, scope = "user") {
|
|
216
310
|
return this.withLock(async () => {
|
|
217
311
|
let marketplace;
|
|
218
312
|
const isFullUrl = input.startsWith("http://") ||
|
|
@@ -223,16 +317,15 @@ export class MarketplaceService {
|
|
|
223
317
|
(input.includes("/") &&
|
|
224
318
|
!path.isAbsolute(input) &&
|
|
225
319
|
!input.startsWith("."))) {
|
|
226
|
-
// Git or GitHub repo
|
|
227
320
|
let urlOrRepo = input;
|
|
228
321
|
let ref;
|
|
229
322
|
if (input.includes("#")) {
|
|
230
323
|
[urlOrRepo, ref] = input.split("#");
|
|
231
324
|
}
|
|
232
|
-
const
|
|
233
|
-
? {
|
|
234
|
-
: {
|
|
235
|
-
const targetPath = this.getMarketplacePath(
|
|
325
|
+
const tempSource = isFullUrl
|
|
326
|
+
? { source: "git", url: urlOrRepo, ref }
|
|
327
|
+
: { source: "github", repo: urlOrRepo, ref };
|
|
328
|
+
const targetPath = this.getMarketplacePath(tempSource);
|
|
236
329
|
if (!existsSync(targetPath)) {
|
|
237
330
|
try {
|
|
238
331
|
await this.gitService.clone(urlOrRepo, targetPath, ref);
|
|
@@ -258,7 +351,6 @@ export class MarketplaceService {
|
|
|
258
351
|
};
|
|
259
352
|
}
|
|
260
353
|
else {
|
|
261
|
-
// Local directory format
|
|
262
354
|
const absolutePath = path.resolve(input);
|
|
263
355
|
let manifest;
|
|
264
356
|
try {
|
|
@@ -274,44 +366,68 @@ export class MarketplaceService {
|
|
|
274
366
|
lastUpdated: new Date().toISOString(),
|
|
275
367
|
};
|
|
276
368
|
}
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
// (getKnownMarketplaces already handles the default injection)
|
|
289
|
-
await this.saveKnownMarketplaces(registry);
|
|
369
|
+
const config = {
|
|
370
|
+
source: marketplace.source,
|
|
371
|
+
autoUpdate: marketplace.autoUpdate,
|
|
372
|
+
};
|
|
373
|
+
await this.configurationService.addMarketplaceToScope(this.workdir, scope, marketplace.name, config);
|
|
374
|
+
// Update cache with metadata
|
|
375
|
+
await this.updateCacheMarketplace(marketplace.name, {
|
|
376
|
+
source: marketplace.source,
|
|
377
|
+
autoUpdate: marketplace.autoUpdate,
|
|
378
|
+
lastUpdated: marketplace.lastUpdated,
|
|
379
|
+
});
|
|
290
380
|
return marketplace;
|
|
291
381
|
});
|
|
292
382
|
}
|
|
293
383
|
/**
|
|
294
|
-
* Lists all registered marketplaces
|
|
384
|
+
* Lists all registered marketplaces by combining scoped settings + built-in
|
|
295
385
|
*/
|
|
296
386
|
async listMarketplaces() {
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
387
|
+
const scopedMarketplaces = this.configurationService.getMergedMarketplaces(this.workdir);
|
|
388
|
+
const cacheRegistry = await this.getCacheRegistry();
|
|
389
|
+
const cacheMap = new Map((cacheRegistry?.marketplaces ?? []).map((m) => [m.name, m]));
|
|
390
|
+
const result = [];
|
|
391
|
+
// Add built-in marketplace
|
|
392
|
+
result.push({
|
|
393
|
+
...MarketplaceService.BUILTIN_MARKETPLACE,
|
|
394
|
+
isBuiltin: true,
|
|
395
|
+
declaredScope: "builtin",
|
|
396
|
+
});
|
|
397
|
+
// Add all scoped marketplaces (local overrides project overrides user)
|
|
398
|
+
for (const [name, config] of Object.entries(scopedMarketplaces)) {
|
|
399
|
+
if (name === MarketplaceService.BUILTIN_MARKETPLACE.name)
|
|
400
|
+
continue;
|
|
401
|
+
const cache = cacheMap.get(name);
|
|
402
|
+
const declaredScope = this.getMarketplaceDeclaringSource(name);
|
|
403
|
+
result.push(await this.buildMarketplaceEntry(name, config, cache, declaredScope));
|
|
404
|
+
}
|
|
405
|
+
// Add cache entries not yet in scoped settings (backwards compatibility)
|
|
406
|
+
for (const [name, cache] of cacheMap.entries()) {
|
|
407
|
+
if (name === MarketplaceService.BUILTIN_MARKETPLACE.name)
|
|
408
|
+
continue;
|
|
409
|
+
if (scopedMarketplaces[name])
|
|
410
|
+
continue;
|
|
411
|
+
result.push({
|
|
412
|
+
...cache,
|
|
413
|
+
isBuiltin: false,
|
|
414
|
+
declaredScope: cache.declaredScope ?? "user",
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
return result;
|
|
302
418
|
}
|
|
303
419
|
/**
|
|
304
|
-
* Removes a marketplace by name
|
|
420
|
+
* Removes a marketplace by name from the specified scope
|
|
305
421
|
*/
|
|
306
|
-
async removeMarketplace(name) {
|
|
422
|
+
async removeMarketplace(name, scope) {
|
|
307
423
|
return this.withLock(async () => {
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (registry.marketplaces.length === initialCount) {
|
|
312
|
-
throw new Error(`Marketplace ${name} not found`);
|
|
424
|
+
const targetScope = scope || this.getMarketplaceDeclaringSource(name) || "user";
|
|
425
|
+
if (targetScope === "builtin") {
|
|
426
|
+
throw new Error("Cannot remove built-in marketplace");
|
|
313
427
|
}
|
|
314
|
-
await this.
|
|
428
|
+
await this.configurationService.removeMarketplaceFromScope(this.workdir, targetScope, name);
|
|
429
|
+
// Also remove from cache
|
|
430
|
+
await this.removeFromCache(name);
|
|
315
431
|
});
|
|
316
432
|
}
|
|
317
433
|
/**
|
|
@@ -319,10 +435,10 @@ export class MarketplaceService {
|
|
|
319
435
|
*/
|
|
320
436
|
async updateMarketplace(name, options) {
|
|
321
437
|
return this.withLock(async () => {
|
|
322
|
-
const
|
|
438
|
+
const marketplaces = await this.listMarketplaces();
|
|
323
439
|
const toUpdate = name
|
|
324
|
-
?
|
|
325
|
-
:
|
|
440
|
+
? marketplaces.filter((m) => m.name === name)
|
|
441
|
+
: marketplaces;
|
|
326
442
|
if (name && toUpdate.length === 0) {
|
|
327
443
|
throw new Error(`Marketplace ${name} not found`);
|
|
328
444
|
}
|
|
@@ -336,7 +452,7 @@ export class MarketplaceService {
|
|
|
336
452
|
console.warn(`Skipping update for Git/GitHub marketplace "${marketplace.name}" because Git is not installed.`);
|
|
337
453
|
continue;
|
|
338
454
|
}
|
|
339
|
-
const targetPath = this.getMarketplacePath(marketplace);
|
|
455
|
+
const targetPath = this.getMarketplacePath(marketplace.source);
|
|
340
456
|
if (existsSync(targetPath)) {
|
|
341
457
|
await this.gitService.pull(targetPath);
|
|
342
458
|
}
|
|
@@ -351,16 +467,19 @@ export class MarketplaceService {
|
|
|
351
467
|
await this.gitService.clone(url, targetPath, marketplace.source.ref);
|
|
352
468
|
}
|
|
353
469
|
}
|
|
354
|
-
|
|
355
|
-
const manifest = await this.loadMarketplaceManifest(this.getMarketplacePath(marketplace));
|
|
470
|
+
const manifest = await this.loadMarketplaceManifest(this.getMarketplacePath(marketplace.source));
|
|
356
471
|
marketplace.lastUpdated = new Date().toISOString();
|
|
472
|
+
// Update cache metadata
|
|
473
|
+
await this.updateCacheMarketplace(marketplace.name, {
|
|
474
|
+
lastUpdated: marketplace.lastUpdated,
|
|
475
|
+
});
|
|
357
476
|
if (options?.updatePlugins) {
|
|
358
477
|
const installedRegistry = await this.getInstalledPlugins();
|
|
359
478
|
const pluginsToUpdate = installedRegistry.plugins.filter((p) => p.marketplace === marketplace.name);
|
|
360
479
|
for (const plugin of pluginsToUpdate) {
|
|
361
480
|
const pluginEntry = manifest.plugins.find((p) => p.name === plugin.name);
|
|
362
481
|
if (!pluginEntry) {
|
|
363
|
-
|
|
482
|
+
logger.warn(`Plugin "${plugin.name}" no longer found in marketplace "${marketplace.name}". Uninstalling...`);
|
|
364
483
|
try {
|
|
365
484
|
await this.uninstallPlugin(`${plugin.name}@${plugin.marketplace}`, plugin.projectPath);
|
|
366
485
|
}
|
|
@@ -387,7 +506,6 @@ export class MarketplaceService {
|
|
|
387
506
|
if (errors.length > 0) {
|
|
388
507
|
throw new Error(`Some marketplaces failed to update:\n${errors.join("\n")}`);
|
|
389
508
|
}
|
|
390
|
-
await this.saveKnownMarketplaces(registry);
|
|
391
509
|
});
|
|
392
510
|
}
|
|
393
511
|
/**
|
|
@@ -395,16 +513,18 @@ export class MarketplaceService {
|
|
|
395
513
|
*/
|
|
396
514
|
async autoUpdateAll() {
|
|
397
515
|
return this.withLock(async () => {
|
|
398
|
-
const
|
|
399
|
-
const toAutoUpdate =
|
|
400
|
-
|
|
516
|
+
const scopedMarketplaces = this.configurationService.getMergedMarketplaces(this.workdir);
|
|
517
|
+
const toAutoUpdate = Object.entries(scopedMarketplaces)
|
|
518
|
+
.filter(([, config]) => config.autoUpdate)
|
|
519
|
+
.map(([name]) => name);
|
|
520
|
+
for (const marketplaceName of toAutoUpdate) {
|
|
401
521
|
try {
|
|
402
|
-
await this.updateMarketplace(
|
|
522
|
+
await this.updateMarketplace(marketplaceName, {
|
|
403
523
|
updatePlugins: true,
|
|
404
524
|
});
|
|
405
525
|
}
|
|
406
526
|
catch (error) {
|
|
407
|
-
console.error(`Auto-update failed for marketplace "${
|
|
527
|
+
console.error(`Auto-update failed for marketplace "${marketplaceName}":`, error);
|
|
408
528
|
}
|
|
409
529
|
}
|
|
410
530
|
});
|
|
@@ -414,13 +534,19 @@ export class MarketplaceService {
|
|
|
414
534
|
*/
|
|
415
535
|
async toggleAutoUpdate(name, enabled) {
|
|
416
536
|
return this.withLock(async () => {
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
537
|
+
const declaringSource = this.getMarketplaceDeclaringSource(name);
|
|
538
|
+
if (!declaringSource || declaringSource === "builtin") {
|
|
539
|
+
throw new Error(`Marketplace ${name} not found`);
|
|
540
|
+
}
|
|
541
|
+
const scoped = this.configurationService.getScopedMarketplaces(this.workdir, declaringSource);
|
|
542
|
+
const config = scoped[name];
|
|
543
|
+
if (!config) {
|
|
420
544
|
throw new Error(`Marketplace ${name} not found`);
|
|
421
545
|
}
|
|
422
|
-
|
|
423
|
-
await this.
|
|
546
|
+
config.autoUpdate = enabled;
|
|
547
|
+
await this.configurationService.addMarketplaceToScope(this.workdir, declaringSource, name, config);
|
|
548
|
+
// Also update cache
|
|
549
|
+
await this.updateCacheMarketplace(name, { autoUpdate: enabled });
|
|
424
550
|
});
|
|
425
551
|
}
|
|
426
552
|
/**
|
|
@@ -437,7 +563,7 @@ export class MarketplaceService {
|
|
|
437
563
|
if (!marketplace) {
|
|
438
564
|
throw new Error(`Marketplace ${marketplaceName} not found`);
|
|
439
565
|
}
|
|
440
|
-
const marketplacePath = this.getMarketplacePath(marketplace);
|
|
566
|
+
const marketplacePath = this.getMarketplacePath(marketplace.source);
|
|
441
567
|
const manifest = await this.loadMarketplaceManifest(marketplacePath);
|
|
442
568
|
const pluginEntry = manifest.plugins.find((p) => p.name === pluginName);
|
|
443
569
|
if (!pluginEntry) {
|
|
@@ -470,12 +596,11 @@ export class MarketplaceService {
|
|
|
470
596
|
const pluginManifestContent = await fs.readFile(pluginManifestPath, "utf-8");
|
|
471
597
|
const pluginManifest = JSON.parse(pluginManifestContent);
|
|
472
598
|
const version = pluginManifest.version || "1.0.0";
|
|
473
|
-
// Atomic installation
|
|
474
599
|
const tmpPluginDir = path.join(this.tmpDir, `${pluginName}-${Date.now()}`);
|
|
475
600
|
try {
|
|
476
601
|
if (isGitSource) {
|
|
477
602
|
await fs.rename(pluginSrcPath, tmpPluginDir);
|
|
478
|
-
tempCloneDir = undefined;
|
|
603
|
+
tempCloneDir = undefined;
|
|
479
604
|
}
|
|
480
605
|
else {
|
|
481
606
|
await fs.cp(pluginSrcPath, tmpPluginDir, { recursive: true });
|
|
@@ -507,7 +632,6 @@ export class MarketplaceService {
|
|
|
507
632
|
return installedPlugin;
|
|
508
633
|
}
|
|
509
634
|
catch (error) {
|
|
510
|
-
// Cleanup tmp dir if it exists
|
|
511
635
|
if (existsSync(tmpPluginDir)) {
|
|
512
636
|
await fs.rm(tmpPluginDir, { recursive: true, force: true });
|
|
513
637
|
}
|
|
@@ -515,7 +639,6 @@ export class MarketplaceService {
|
|
|
515
639
|
}
|
|
516
640
|
}
|
|
517
641
|
catch (error) {
|
|
518
|
-
// Cleanup temp clone dir if it exists
|
|
519
642
|
if (tempCloneDir && existsSync(tempCloneDir)) {
|
|
520
643
|
await fs.rm(tempCloneDir, { recursive: true, force: true });
|
|
521
644
|
}
|
|
@@ -540,12 +663,9 @@ export class MarketplaceService {
|
|
|
540
663
|
throw new Error(`Plugin ${pluginName}@${marketplaceName} is not installed${projectPath ? ` for project ${projectPath}` : ""}`);
|
|
541
664
|
}
|
|
542
665
|
const pluginToRemove = installedRegistry.plugins[pluginIndex];
|
|
543
|
-
// Remove from registry first
|
|
544
666
|
installedRegistry.plugins.splice(pluginIndex, 1);
|
|
545
667
|
await this.saveInstalledPlugins(installedRegistry);
|
|
546
|
-
// Check if any other project is still using this same cache path
|
|
547
668
|
const isStillReferenced = installedRegistry.plugins.some((p) => p.cachePath === pluginToRemove.cachePath);
|
|
548
|
-
// Only remove cached files if no other references exist
|
|
549
669
|
if (!isStillReferenced && existsSync(pluginToRemove.cachePath)) {
|
|
550
670
|
await fs.rm(pluginToRemove.cachePath, { recursive: true, force: true });
|
|
551
671
|
}
|
|
@@ -37,14 +37,14 @@ export interface CallAgentResult {
|
|
|
37
37
|
additionalFields?: Record<string, unknown>;
|
|
38
38
|
}
|
|
39
39
|
export declare function callAgent(options: CallAgentOptions): Promise<CallAgentResult>;
|
|
40
|
-
export interface
|
|
40
|
+
export interface CompactMessagesOptions {
|
|
41
41
|
gatewayConfig: GatewayConfig;
|
|
42
42
|
modelConfig: ModelConfig;
|
|
43
43
|
messages: ChatCompletionMessageParam[];
|
|
44
44
|
abortSignal?: AbortSignal;
|
|
45
45
|
model?: string;
|
|
46
46
|
}
|
|
47
|
-
export interface
|
|
47
|
+
export interface CompactMessagesResult {
|
|
48
48
|
content: string;
|
|
49
49
|
usage?: {
|
|
50
50
|
prompt_tokens: number;
|
|
@@ -52,7 +52,7 @@ export interface CompressMessagesResult {
|
|
|
52
52
|
total_tokens: number;
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
export declare function
|
|
55
|
+
export declare function compactMessages(options: CompactMessagesOptions): Promise<CompactMessagesResult>;
|
|
56
56
|
export interface ProcessWebContentOptions {
|
|
57
57
|
gatewayConfig: GatewayConfig;
|
|
58
58
|
modelConfig: ModelConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiService.d.ts","sourceRoot":"","sources":["../../src/services/aiService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAGL,0BAA0B,EAC1B,0BAA0B,EAE3B,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,+BAA+B,CAAC;AAgEvC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AA6DD,MAAM,WAAW,gBAAgB;IAE/B,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;IAGzB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;KACnD,KAAK,IAAI,CAAC;IACX,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,6BAA6B,EAAE,CAAC;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EACV,MAAM,GACN,QAAQ,GACR,YAAY,GACZ,gBAAgB,GAChB,eAAe,GACf,IAAI,CAAC;IACT,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAoU1B;AA4OD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"aiService.d.ts","sourceRoot":"","sources":["../../src/services/aiService.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { transformMessagesForClaudeCache, addCacheControlToLastTool, supportsPro
|
|
|
5
5
|
import * as os from "os";
|
|
6
6
|
import * as fs from "fs";
|
|
7
7
|
import * as path from "path";
|
|
8
|
-
import {
|
|
8
|
+
import { COMPACT_MESSAGES_SYSTEM_PROMPT, WEB_CONTENT_SYSTEM_PROMPT, BTW_SYSTEM_PROMPT, } from "../prompts/index.js";
|
|
9
9
|
// Global rate limiter state for 1 QPS
|
|
10
10
|
let nextAllowedTime = 0;
|
|
11
11
|
const MIN_INTERVAL = 1000; // 1 second for 1 QPS
|
|
@@ -450,7 +450,7 @@ async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, o
|
|
|
450
450
|
}
|
|
451
451
|
return result;
|
|
452
452
|
}
|
|
453
|
-
export async function
|
|
453
|
+
export async function compactMessages(options) {
|
|
454
454
|
const { gatewayConfig, modelConfig, messages, abortSignal } = options;
|
|
455
455
|
// Apply global 1 QPS rate limit
|
|
456
456
|
if (process.env.NODE_ENV !== "test" ||
|
|
@@ -492,7 +492,7 @@ export async function compressMessages(options) {
|
|
|
492
492
|
messages: [
|
|
493
493
|
{
|
|
494
494
|
role: "system",
|
|
495
|
-
content:
|
|
495
|
+
content: COMPACT_MESSAGES_SYSTEM_PROMPT,
|
|
496
496
|
},
|
|
497
497
|
...cleanedMessages,
|
|
498
498
|
{
|
|
@@ -505,7 +505,7 @@ export async function compressMessages(options) {
|
|
|
505
505
|
});
|
|
506
506
|
const content = response.choices[0]?.message?.content?.trim();
|
|
507
507
|
if (!content) {
|
|
508
|
-
throw new Error("Failed to
|
|
508
|
+
throw new Error("Failed to compact conversation history: Empty response from AI");
|
|
509
509
|
}
|
|
510
510
|
const usage = response.usage
|
|
511
511
|
? {
|
|
@@ -521,10 +521,10 @@ export async function compressMessages(options) {
|
|
|
521
521
|
}
|
|
522
522
|
catch (error) {
|
|
523
523
|
if (error.name === "AbortError") {
|
|
524
|
-
logger.info("
|
|
525
|
-
throw new Error("
|
|
524
|
+
logger.info("Compaction request was aborted");
|
|
525
|
+
throw new Error("Compaction request was aborted");
|
|
526
526
|
}
|
|
527
|
-
logger.error("Failed to
|
|
527
|
+
logger.error("Failed to compact messages:", error);
|
|
528
528
|
throw error;
|
|
529
529
|
}
|
|
530
530
|
}
|