wave-agent-sdk 0.14.0 → 0.14.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/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/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +0 -12
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +1 -1
- package/dist/services/MarketplaceService.d.ts +53 -12
- package/dist/services/MarketplaceService.d.ts.map +1 -1
- package/dist/services/MarketplaceService.js +311 -123
- 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/pluginLoader.d.ts +6 -0
- package/dist/services/pluginLoader.d.ts.map +1 -1
- package/dist/services/pluginLoader.js +52 -7
- package/dist/types/configuration.d.ts +7 -0
- package/dist/types/configuration.d.ts.map +1 -1
- package/dist/types/marketplace.d.ts +28 -1
- package/dist/types/marketplace.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +13 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/plugin.ts +13 -7
- package/src/managers/backgroundTaskManager.ts +1 -20
- package/src/managers/pluginManager.ts +4 -1
- package/src/services/MarketplaceService.ts +425 -134
- package/src/services/configurationService.ts +131 -0
- package/src/services/pluginLoader.ts +66 -7
- package/src/types/configuration.ts +8 -0
- package/src/types/marketplace.ts +26 -1
- package/src/types/plugins.ts +13 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Centralized service for loading, validating, and managing Wave configuration files.
|
|
5
5
|
* Replaces distributed configuration logic previously embedded in hook.ts.
|
|
6
6
|
*/
|
|
7
|
-
import type { ConfigurationLoadResult, ValidationResult, ConfigurationPaths, WaveConfiguration, Scope } from "../types/configuration.js";
|
|
7
|
+
import type { ConfigurationLoadResult, ValidationResult, ConfigurationPaths, WaveConfiguration, Scope, MarketplaceConfig } from "../types/configuration.js";
|
|
8
8
|
import { type EnvironmentValidationResult, type MergedEnvironmentContext, type EnvironmentMergeOptions } from "../types/environment.js";
|
|
9
9
|
import { GatewayConfig, ModelConfig, PermissionMode, AgentOptions } from "../types/index.js";
|
|
10
10
|
import { ClientOptions } from "openai";
|
|
@@ -114,6 +114,22 @@ export declare class ConfigurationService {
|
|
|
114
114
|
* Update the enabled state of a plugin in the specified scope
|
|
115
115
|
*/
|
|
116
116
|
updateEnabledPlugin(workdir: string, scope: Scope, pluginId: string, enabled: boolean): Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* Get merged marketplaces from all scopes
|
|
119
|
+
*/
|
|
120
|
+
getMergedMarketplaces(workdir: string): Record<string, MarketplaceConfig>;
|
|
121
|
+
/**
|
|
122
|
+
* Get marketplaces at a specific scope
|
|
123
|
+
*/
|
|
124
|
+
getScopedMarketplaces(workdir: string, scope: Scope): Record<string, MarketplaceConfig>;
|
|
125
|
+
/**
|
|
126
|
+
* Add a marketplace to the specified scope
|
|
127
|
+
*/
|
|
128
|
+
addMarketplaceToScope(workdir: string, scope: Scope, name: string, config: MarketplaceConfig): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Remove a marketplace from the specified scope
|
|
131
|
+
*/
|
|
132
|
+
removeMarketplaceFromScope(workdir: string, scope: Scope, name: string): Promise<void>;
|
|
117
133
|
/**
|
|
118
134
|
* Remove a plugin from the enabled plugins in the specified scope
|
|
119
135
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurationService.d.ts","sourceRoot":"","sources":["../../src/services/configurationService.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,
|
|
1
|
+
{"version":3,"file":"configurationService.d.ts","sourceRoot":"","sources":["../../src/services/configurationService.ts"],"names":[],"mappings":"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"}
|
|
@@ -627,6 +627,99 @@ export class ConfigurationService {
|
|
|
627
627
|
config.enabledPlugins[pluginId] = enabled;
|
|
628
628
|
await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
629
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* Get merged marketplaces from all scopes
|
|
632
|
+
*/
|
|
633
|
+
getMergedMarketplaces(workdir) {
|
|
634
|
+
const mergedConfig = loadMergedWaveConfig(workdir);
|
|
635
|
+
return mergedConfig?.marketplaces || {};
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Get marketplaces at a specific scope
|
|
639
|
+
*/
|
|
640
|
+
getScopedMarketplaces(workdir, scope) {
|
|
641
|
+
let configPath;
|
|
642
|
+
if (scope === "user") {
|
|
643
|
+
configPath = getUserConfigPaths()[0];
|
|
644
|
+
}
|
|
645
|
+
else if (scope === "project") {
|
|
646
|
+
configPath = getProjectConfigPaths(workdir)[1];
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
configPath = getProjectConfigPaths(workdir)[0];
|
|
650
|
+
}
|
|
651
|
+
const config = loadWaveConfigFromFile(configPath);
|
|
652
|
+
return config?.marketplaces || {};
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Add a marketplace to the specified scope
|
|
656
|
+
*/
|
|
657
|
+
async addMarketplaceToScope(workdir, scope, name, config) {
|
|
658
|
+
if (scope !== "user" && !existsSync(workdir)) {
|
|
659
|
+
throw new Error(`Working directory does not exist: ${workdir}`);
|
|
660
|
+
}
|
|
661
|
+
let configPath;
|
|
662
|
+
if (scope === "user") {
|
|
663
|
+
configPath = getUserConfigPaths()[0];
|
|
664
|
+
}
|
|
665
|
+
else if (scope === "project") {
|
|
666
|
+
configPath = getProjectConfigPaths(workdir)[1];
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
configPath = getProjectConfigPaths(workdir)[0];
|
|
670
|
+
}
|
|
671
|
+
const configDir = path.dirname(configPath);
|
|
672
|
+
if (!existsSync(configDir)) {
|
|
673
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
674
|
+
}
|
|
675
|
+
let fileConfig = {};
|
|
676
|
+
if (existsSync(configPath)) {
|
|
677
|
+
try {
|
|
678
|
+
const content = await fs.readFile(configPath, "utf-8");
|
|
679
|
+
fileConfig = JSON.parse(content);
|
|
680
|
+
}
|
|
681
|
+
catch {
|
|
682
|
+
// Start with empty config if file is corrupted
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (!fileConfig.marketplaces) {
|
|
686
|
+
fileConfig.marketplaces = {};
|
|
687
|
+
}
|
|
688
|
+
fileConfig.marketplaces[name] = config;
|
|
689
|
+
await fs.writeFile(configPath, JSON.stringify(fileConfig, null, 2), "utf-8");
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Remove a marketplace from the specified scope
|
|
693
|
+
*/
|
|
694
|
+
async removeMarketplaceFromScope(workdir, scope, name) {
|
|
695
|
+
if (scope !== "user" && !existsSync(workdir)) {
|
|
696
|
+
throw new Error(`Working directory does not exist: ${workdir}`);
|
|
697
|
+
}
|
|
698
|
+
let configPath;
|
|
699
|
+
if (scope === "user") {
|
|
700
|
+
configPath = getUserConfigPaths()[0];
|
|
701
|
+
}
|
|
702
|
+
else if (scope === "project") {
|
|
703
|
+
configPath = getProjectConfigPaths(workdir)[1];
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
configPath = getProjectConfigPaths(workdir)[0];
|
|
707
|
+
}
|
|
708
|
+
if (!existsSync(configPath)) {
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
try {
|
|
712
|
+
const content = await fs.readFile(configPath, "utf-8");
|
|
713
|
+
const fileConfig = JSON.parse(content);
|
|
714
|
+
if (fileConfig.marketplaces && name in fileConfig.marketplaces) {
|
|
715
|
+
delete fileConfig.marketplaces[name];
|
|
716
|
+
await fs.writeFile(configPath, JSON.stringify(fileConfig, null, 2), "utf-8");
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
catch {
|
|
720
|
+
// Ignore errors for corrupted or non-existent files
|
|
721
|
+
}
|
|
722
|
+
}
|
|
630
723
|
/**
|
|
631
724
|
* Remove a plugin from the enabled plugins in the specified scope
|
|
632
725
|
*/
|
|
@@ -777,6 +870,7 @@ export function loadWaveConfigFromFile(filePath) {
|
|
|
777
870
|
? config.autoMemoryEnabled
|
|
778
871
|
: undefined,
|
|
779
872
|
models: config.models || undefined,
|
|
873
|
+
marketplaces: config.marketplaces || undefined,
|
|
780
874
|
};
|
|
781
875
|
}
|
|
782
876
|
catch (error) {
|
|
@@ -893,6 +987,12 @@ export function loadMergedWaveConfig(workdir) {
|
|
|
893
987
|
if (config.autoMemoryFrequency !== undefined) {
|
|
894
988
|
mergedConfig.autoMemoryFrequency = config.autoMemoryFrequency;
|
|
895
989
|
}
|
|
990
|
+
// Merge marketplaces (last one wins for same key)
|
|
991
|
+
if (config.marketplaces) {
|
|
992
|
+
if (!mergedConfig.marketplaces)
|
|
993
|
+
mergedConfig.marketplaces = {};
|
|
994
|
+
Object.assign(mergedConfig.marketplaces, config.marketplaces);
|
|
995
|
+
}
|
|
896
996
|
// Merge models
|
|
897
997
|
if (config.models) {
|
|
898
998
|
if (!mergedConfig.models)
|
|
@@ -922,6 +1022,10 @@ export function loadMergedWaveConfig(workdir) {
|
|
|
922
1022
|
: undefined,
|
|
923
1023
|
language: mergedConfig.language,
|
|
924
1024
|
autoMemoryEnabled: mergedConfig.autoMemoryEnabled,
|
|
1025
|
+
marketplaces: mergedConfig.marketplaces &&
|
|
1026
|
+
Object.keys(mergedConfig.marketplaces).length > 0
|
|
1027
|
+
? mergedConfig.marketplaces
|
|
1028
|
+
: undefined,
|
|
925
1029
|
models: mergedConfig.models && Object.keys(mergedConfig.models).length > 0
|
|
926
1030
|
? mergedConfig.models
|
|
927
1031
|
: undefined,
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { PluginManifest, CustomSlashCommand, Skill, LspConfig, McpConfig, PartialHookConfiguration } from "../types/index.js";
|
|
2
2
|
export declare class PluginLoader {
|
|
3
|
+
/**
|
|
4
|
+
* Finds the first existing plugin manifest path.
|
|
5
|
+
* Prefers .wave-plugin/ for backward compatibility, falls back to .claude-plugin/.
|
|
6
|
+
* Returns null if neither exists.
|
|
7
|
+
*/
|
|
8
|
+
private static findPluginManifestPath;
|
|
3
9
|
/**
|
|
4
10
|
* Load and validate a plugin manifest from a directory
|
|
5
11
|
* @param pluginPath Absolute path to the plugin directory
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/services/pluginLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/services/pluginLoader.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,SAAS,EACT,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAK3B,qBAAa,YAAY;IACvB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAkCrC;;;OAGG;WACU,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAgEtE;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAK7D;;;OAGG;WACU,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAuC7D;;OAEG;WACU,aAAa,CACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAUjC;;OAEG;WACU,aAAa,CACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAUjC;;OAEG;WACU,eAAe,CAC1B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC;IAUhD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;CAgBhC"}
|
|
@@ -1,28 +1,73 @@
|
|
|
1
1
|
import * as fs from "fs/promises";
|
|
2
|
+
import * as fsSync from "fs";
|
|
2
3
|
import * as path from "path";
|
|
3
4
|
import { scanCommandsDirectory } from "../utils/customCommands.js";
|
|
4
5
|
import { parseSkillFile } from "../utils/skillParser.js";
|
|
5
6
|
import { resolveMcpConfig } from "../managers/mcpManager.js";
|
|
6
7
|
export class PluginLoader {
|
|
8
|
+
/**
|
|
9
|
+
* Finds the first existing plugin manifest path.
|
|
10
|
+
* Prefers .wave-plugin/ for backward compatibility, falls back to .claude-plugin/.
|
|
11
|
+
* Returns null if neither exists.
|
|
12
|
+
*/
|
|
13
|
+
static findPluginManifestPath(pluginPath) {
|
|
14
|
+
const waveManifestPath = path.join(pluginPath, ".wave-plugin", "plugin.json");
|
|
15
|
+
const claudeManifestPath = path.join(pluginPath, ".claude-plugin", "plugin.json");
|
|
16
|
+
// Check .wave-plugin first for backward compatibility
|
|
17
|
+
try {
|
|
18
|
+
const waveStat = fsSync.statSync(waveManifestPath);
|
|
19
|
+
if (waveStat.isFile()) {
|
|
20
|
+
return waveManifestPath;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// .wave-plugin/plugin.json doesn't exist
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const claudeStat = fsSync.statSync(claudeManifestPath);
|
|
28
|
+
if (claudeStat.isFile()) {
|
|
29
|
+
return claudeManifestPath;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// .claude-plugin/plugin.json doesn't exist
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
7
37
|
/**
|
|
8
38
|
* Load and validate a plugin manifest from a directory
|
|
9
39
|
* @param pluginPath Absolute path to the plugin directory
|
|
10
40
|
*/
|
|
11
41
|
static async loadManifest(pluginPath) {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
42
|
+
const manifestPath = this.findPluginManifestPath(pluginPath);
|
|
43
|
+
if (!manifestPath) {
|
|
44
|
+
throw new Error(`Plugin manifest not found at ${pluginPath}. Neither .wave-plugin/plugin.json nor .claude-plugin/plugin.json exists.`);
|
|
45
|
+
}
|
|
46
|
+
// Determine which directory is being used for validation
|
|
47
|
+
const pluginDirName = manifestPath.includes(".claude-plugin")
|
|
48
|
+
? ".claude-plugin"
|
|
49
|
+
: ".wave-plugin";
|
|
50
|
+
const pluginDirPath = path.join(pluginPath, pluginDirName);
|
|
51
|
+
// T018: Ensure plugin.json is the only file in the manifest directory
|
|
52
|
+
// For .claude-plugin/, marketplace.json is also allowed (Claude Code convention)
|
|
15
53
|
try {
|
|
16
|
-
const entries = await fs.readdir(
|
|
17
|
-
const
|
|
54
|
+
const entries = await fs.readdir(pluginDirPath);
|
|
55
|
+
const allowedFiles = ["plugin.json"];
|
|
56
|
+
if (pluginDirName === ".claude-plugin") {
|
|
57
|
+
allowedFiles.push("marketplace.json");
|
|
58
|
+
}
|
|
59
|
+
const misplaced = entries.filter((e) => !allowedFiles.includes(e));
|
|
18
60
|
if (misplaced.length > 0) {
|
|
19
|
-
|
|
61
|
+
const allowedMsg = pluginDirName === ".claude-plugin"
|
|
62
|
+
? "Only plugin.json and marketplace.json should be in this directory."
|
|
63
|
+
: "Only plugin.json should be in this directory.";
|
|
64
|
+
throw new Error(`Misplaced files/directories in ${pluginDirName}/: ${misplaced.join(", ")}. ${allowedMsg}`);
|
|
20
65
|
}
|
|
21
66
|
}
|
|
22
67
|
catch (error) {
|
|
23
68
|
if (error instanceof Error &&
|
|
24
69
|
error.code === "ENOENT") {
|
|
25
|
-
throw new Error(`Plugin manifest directory not found at ${
|
|
70
|
+
throw new Error(`Plugin manifest directory not found at ${pluginDirPath}`);
|
|
26
71
|
}
|
|
27
72
|
throw error;
|
|
28
73
|
}
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
import type { HookEvent, HookEventConfig } from "./hooks.js";
|
|
9
9
|
import type { PermissionMode } from "./permissions.js";
|
|
10
10
|
import type { ModelConfig } from "./config.js";
|
|
11
|
+
import type { MarketplaceSource } from "./marketplace.js";
|
|
11
12
|
export type Scope = "user" | "project" | "local";
|
|
13
|
+
export interface MarketplaceConfig {
|
|
14
|
+
source: MarketplaceSource;
|
|
15
|
+
autoUpdate?: boolean;
|
|
16
|
+
}
|
|
12
17
|
/**
|
|
13
18
|
* Root configuration structure for all Wave Agent settings including hooks and environment variables
|
|
14
19
|
*/
|
|
@@ -36,6 +41,8 @@ export interface WaveConfiguration {
|
|
|
36
41
|
autoMemoryFrequency?: number;
|
|
37
42
|
/** Model-specific configuration overrides */
|
|
38
43
|
models?: Record<string, Partial<ModelConfig>>;
|
|
44
|
+
/** Scoped marketplace declarations */
|
|
45
|
+
marketplaces?: Record<string, MarketplaceConfig>;
|
|
39
46
|
}
|
|
40
47
|
/**
|
|
41
48
|
* Legacy alias for backward compatibility - will be deprecated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/types/configuration.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/types/configuration.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,8 +5,27 @@ export interface MarketplaceOwner {
|
|
|
5
5
|
}
|
|
6
6
|
export interface MarketplacePluginEntry {
|
|
7
7
|
name: string;
|
|
8
|
-
source: string;
|
|
8
|
+
source: string | MarketplaceSource;
|
|
9
9
|
description: string;
|
|
10
|
+
/** Claude Code compatibility: plugin category */
|
|
11
|
+
category?: string;
|
|
12
|
+
/** Claude Code compatibility: plugin tags */
|
|
13
|
+
tags?: string[];
|
|
14
|
+
/** Claude Code compatibility: when false, plugin.json is optional */
|
|
15
|
+
strict?: boolean;
|
|
16
|
+
/** Claude Code compatibility: inline manifest fields */
|
|
17
|
+
version?: string;
|
|
18
|
+
author?: {
|
|
19
|
+
name: string;
|
|
20
|
+
url?: string;
|
|
21
|
+
};
|
|
22
|
+
homepage?: string;
|
|
23
|
+
repository?: string;
|
|
24
|
+
license?: string;
|
|
25
|
+
keywords?: string[];
|
|
26
|
+
commands?: string;
|
|
27
|
+
skills?: string;
|
|
28
|
+
agents?: string;
|
|
10
29
|
}
|
|
11
30
|
export interface MarketplacePluginStatus extends MarketplacePluginEntry {
|
|
12
31
|
marketplace: string;
|
|
@@ -20,6 +39,8 @@ export interface MarketplaceManifest {
|
|
|
20
39
|
name: string;
|
|
21
40
|
owner: MarketplaceOwner;
|
|
22
41
|
plugins: MarketplacePluginEntry[];
|
|
42
|
+
/** Claude Code compatibility: additional metadata */
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
23
44
|
}
|
|
24
45
|
export type MarketplaceSource = {
|
|
25
46
|
source: "directory";
|
|
@@ -32,6 +53,10 @@ export type MarketplaceSource = {
|
|
|
32
53
|
source: "git";
|
|
33
54
|
url: string;
|
|
34
55
|
ref?: string;
|
|
56
|
+
} | {
|
|
57
|
+
source: "url";
|
|
58
|
+
url: string;
|
|
59
|
+
ref?: string;
|
|
35
60
|
};
|
|
36
61
|
export interface KnownMarketplace {
|
|
37
62
|
name: string;
|
|
@@ -39,6 +64,8 @@ export interface KnownMarketplace {
|
|
|
39
64
|
isBuiltin?: boolean;
|
|
40
65
|
autoUpdate?: boolean;
|
|
41
66
|
lastUpdated?: string;
|
|
67
|
+
/** The scope where this marketplace was declared (user, project, local, or builtin) */
|
|
68
|
+
declaredScope?: "user" | "project" | "local" | "builtin";
|
|
42
69
|
}
|
|
43
70
|
export interface KnownMarketplacesRegistry {
|
|
44
71
|
marketplaces: KnownMarketplace[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/types/marketplace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../src/types/marketplace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACD;IACE,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1D;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { LspConfig } from "./lsp.js";
|
|
|
4
4
|
import { McpConfig } from "./mcp.js";
|
|
5
5
|
import { PartialHookConfiguration } from "./configuration.js";
|
|
6
6
|
/**
|
|
7
|
-
* Plugin manifest structure (.wave-plugin/plugin.json)
|
|
7
|
+
* Plugin manifest structure (.wave-plugin/plugin.json or .claude-plugin/plugin.json)
|
|
8
8
|
*/
|
|
9
9
|
export interface PluginManifest {
|
|
10
10
|
name: string;
|
|
@@ -13,6 +13,18 @@ export interface PluginManifest {
|
|
|
13
13
|
author?: {
|
|
14
14
|
name: string;
|
|
15
15
|
};
|
|
16
|
+
/** Claude Code compatibility: plugin keywords */
|
|
17
|
+
keywords?: string[];
|
|
18
|
+
/** Claude Code compatibility: plugin homepage URL */
|
|
19
|
+
homepage?: string;
|
|
20
|
+
/** Claude Code compatibility: repository info */
|
|
21
|
+
repository?: string;
|
|
22
|
+
/** Claude Code compatibility: license info */
|
|
23
|
+
license?: string;
|
|
24
|
+
/** Claude Code compatibility: plugin dependencies */
|
|
25
|
+
dependencies?: Record<string, string>;
|
|
26
|
+
/** Claude Code compatibility: user configuration schema */
|
|
27
|
+
userConfig?: Record<string, unknown>;
|
|
16
28
|
}
|
|
17
29
|
/**
|
|
18
30
|
* Plugin configuration in AgentOptions or wave.settings.json
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/types/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/types/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,MAAO,SAAQ,cAAc;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,wBAAwB,CAAC;CACxC"}
|
package/package.json
CHANGED
package/src/core/plugin.ts
CHANGED
|
@@ -30,7 +30,10 @@ export class PluginCore {
|
|
|
30
30
|
this.workdir = workdir;
|
|
31
31
|
this.container = new Container();
|
|
32
32
|
this.configurationService = new ConfigurationService();
|
|
33
|
-
this.marketplaceService = new MarketplaceService(
|
|
33
|
+
this.marketplaceService = new MarketplaceService(
|
|
34
|
+
this.workdir,
|
|
35
|
+
this.configurationService,
|
|
36
|
+
);
|
|
34
37
|
|
|
35
38
|
// Wire up ConfigurationService in the container for PluginManager to use
|
|
36
39
|
this.container.register("ConfigurationService", this.configurationService);
|
|
@@ -122,7 +125,7 @@ export class PluginCore {
|
|
|
122
125
|
for (const m of marketplaces) {
|
|
123
126
|
try {
|
|
124
127
|
const manifest = await this.marketplaceService.loadMarketplaceManifest(
|
|
125
|
-
this.marketplaceService.getMarketplacePath(m),
|
|
128
|
+
this.marketplaceService.getMarketplacePath(m.source),
|
|
126
129
|
);
|
|
127
130
|
manifest.plugins.forEach((p) => {
|
|
128
131
|
const pluginId = `${p.name}@${m.name}`;
|
|
@@ -154,15 +157,18 @@ export class PluginCore {
|
|
|
154
157
|
/**
|
|
155
158
|
* Adds a new marketplace
|
|
156
159
|
*/
|
|
157
|
-
async addMarketplace(
|
|
158
|
-
|
|
160
|
+
async addMarketplace(
|
|
161
|
+
input: string,
|
|
162
|
+
scope: Scope = "user",
|
|
163
|
+
): Promise<KnownMarketplace> {
|
|
164
|
+
return await this.marketplaceService.addMarketplace(input, scope);
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
/**
|
|
162
168
|
* Removes a marketplace by name
|
|
163
169
|
*/
|
|
164
|
-
async removeMarketplace(name: string): Promise<void> {
|
|
165
|
-
await this.marketplaceService.removeMarketplace(name);
|
|
170
|
+
async removeMarketplace(name: string, scope?: Scope): Promise<void> {
|
|
171
|
+
await this.marketplaceService.removeMarketplace(name, scope);
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
/**
|
|
@@ -208,7 +214,7 @@ export class PluginCore {
|
|
|
208
214
|
* Resolves the local path for a marketplace
|
|
209
215
|
*/
|
|
210
216
|
getMarketplacePath(marketplace: KnownMarketplace): string {
|
|
211
|
-
return this.marketplaceService.getMarketplacePath(marketplace);
|
|
217
|
+
return this.marketplaceService.getMarketplacePath(marketplace.source);
|
|
212
218
|
}
|
|
213
219
|
|
|
214
220
|
/**
|
|
@@ -2,11 +2,7 @@ import { spawn, type ChildProcess } from "child_process";
|
|
|
2
2
|
import * as os from "os";
|
|
3
3
|
import * as fs from "fs";
|
|
4
4
|
import * as path from "path";
|
|
5
|
-
import {
|
|
6
|
-
BackgroundTask,
|
|
7
|
-
BackgroundShell,
|
|
8
|
-
BackgroundSubagent,
|
|
9
|
-
} from "../types/processes.js";
|
|
5
|
+
import { BackgroundTask, BackgroundShell } from "../types/processes.js";
|
|
10
6
|
import { stripAnsiColors } from "../utils/stringUtils.js";
|
|
11
7
|
import { logger } from "../utils/globalLogger.js";
|
|
12
8
|
import { Container } from "../utils/container.js";
|
|
@@ -427,21 +423,6 @@ export class BackgroundTaskManager {
|
|
|
427
423
|
task.runtime = task.endTime - task.startTime;
|
|
428
424
|
this.notifyTasksChange();
|
|
429
425
|
|
|
430
|
-
// Enqueue killed notification
|
|
431
|
-
const notificationQueue = this.container.has("NotificationQueue")
|
|
432
|
-
? this.container.get<NotificationQueue>("NotificationQueue")
|
|
433
|
-
: undefined;
|
|
434
|
-
if (notificationQueue) {
|
|
435
|
-
const description = (task as BackgroundSubagent).description || "";
|
|
436
|
-
const command = (task as BackgroundShell).command || "";
|
|
437
|
-
const summary =
|
|
438
|
-
task.type === "subagent"
|
|
439
|
-
? `Agent task "${description}" was stopped`
|
|
440
|
-
: `Command "${command}" was stopped`;
|
|
441
|
-
notificationQueue.enqueue(
|
|
442
|
-
`<task-notification>\n<task-id>${id}</task-id>\n<task-type>${task.type}</task-type>\n<status>killed</status>\n<summary>${summary}</summary>\n</task-notification>`,
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
426
|
return true;
|
|
446
427
|
}
|
|
447
428
|
|
|
@@ -72,7 +72,10 @@ export class PluginManager {
|
|
|
72
72
|
);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const marketplaceService = new MarketplaceService(
|
|
75
|
+
const marketplaceService = new MarketplaceService(
|
|
76
|
+
this.workdir,
|
|
77
|
+
this.configurationService,
|
|
78
|
+
);
|
|
76
79
|
|
|
77
80
|
// Trigger auto-update for marketplaces in the background
|
|
78
81
|
if (!process.env.VITEST) {
|