gencode-ai 0.1.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/.env.example +11 -0
- package/CLAUDE.md +70 -0
- package/LICENSE +21 -0
- package/README.md +117 -0
- package/dist/agent/agent.d.ts +84 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +233 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/index.d.ts +6 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +6 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/types.d.ts +47 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +5 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli/components/App.d.ts +14 -0
- package/dist/cli/components/App.d.ts.map +1 -0
- package/dist/cli/components/App.js +395 -0
- package/dist/cli/components/App.js.map +1 -0
- package/dist/cli/components/CommandSuggestions.d.ts +13 -0
- package/dist/cli/components/CommandSuggestions.d.ts.map +1 -0
- package/dist/cli/components/CommandSuggestions.js +32 -0
- package/dist/cli/components/CommandSuggestions.js.map +1 -0
- package/dist/cli/components/Header.d.ts +9 -0
- package/dist/cli/components/Header.d.ts.map +1 -0
- package/dist/cli/components/Header.js +13 -0
- package/dist/cli/components/Header.js.map +1 -0
- package/dist/cli/components/Input.d.ts +13 -0
- package/dist/cli/components/Input.d.ts.map +1 -0
- package/dist/cli/components/Input.js +27 -0
- package/dist/cli/components/Input.js.map +1 -0
- package/dist/cli/components/Logo.d.ts +2 -0
- package/dist/cli/components/Logo.d.ts.map +1 -0
- package/dist/cli/components/Logo.js +8 -0
- package/dist/cli/components/Logo.js.map +1 -0
- package/dist/cli/components/Messages.d.ts +37 -0
- package/dist/cli/components/Messages.d.ts.map +1 -0
- package/dist/cli/components/Messages.js +106 -0
- package/dist/cli/components/Messages.js.map +1 -0
- package/dist/cli/components/ModelSelector.d.ts +13 -0
- package/dist/cli/components/ModelSelector.d.ts.map +1 -0
- package/dist/cli/components/ModelSelector.js +72 -0
- package/dist/cli/components/ModelSelector.js.map +1 -0
- package/dist/cli/components/Spinner.d.ts +12 -0
- package/dist/cli/components/Spinner.d.ts.map +1 -0
- package/dist/cli/components/Spinner.js +45 -0
- package/dist/cli/components/Spinner.js.map +1 -0
- package/dist/cli/components/index.d.ts +12 -0
- package/dist/cli/components/index.d.ts.map +1 -0
- package/dist/cli/components/index.js +12 -0
- package/dist/cli/components/index.js.map +1 -0
- package/dist/cli/components/theme.d.ts +31 -0
- package/dist/cli/components/theme.d.ts.map +1 -0
- package/dist/cli/components/theme.js +36 -0
- package/dist/cli/components/theme.js.map +1 -0
- package/dist/cli/index-legacy.d.ts +7 -0
- package/dist/cli/index-legacy.d.ts.map +1 -0
- package/dist/cli/index-legacy.js +431 -0
- package/dist/cli/index-legacy.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +116 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ink-cli.d.ts +7 -0
- package/dist/cli/ink-cli.d.ts.map +1 -0
- package/dist/cli/ink-cli.js +105 -0
- package/dist/cli/ink-cli.js.map +1 -0
- package/dist/cli/session-picker.d.ts +16 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +280 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli/ui.d.ts +61 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +364 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/manager.d.ts +31 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +65 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +22 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +6 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/index.d.ts +10 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +9 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/init.d.ts +20 -0
- package/dist/memory/init.d.ts.map +1 -0
- package/dist/memory/init.js +332 -0
- package/dist/memory/init.js.map +1 -0
- package/dist/memory/manager.d.ts +85 -0
- package/dist/memory/manager.d.ts.map +1 -0
- package/dist/memory/manager.js +234 -0
- package/dist/memory/manager.js.map +1 -0
- package/dist/memory/types.d.ts +74 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +6 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/permissions/index.d.ts +7 -0
- package/dist/permissions/index.d.ts.map +1 -0
- package/dist/permissions/index.js +6 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/permissions/manager.d.ts +32 -0
- package/dist/permissions/manager.d.ts.map +1 -0
- package/dist/permissions/manager.js +79 -0
- package/dist/permissions/manager.js.map +1 -0
- package/dist/permissions/types.d.ts +14 -0
- package/dist/permissions/types.d.ts.map +1 -0
- package/dist/permissions/types.js +17 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +20 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +185 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/gemini.d.ts +21 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +241 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +34 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +72 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +19 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +221 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +125 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +6 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/session/index.d.ts +6 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +6 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +101 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +295 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/types.d.ts +39 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +10 -0
- package/dist/session/types.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts +7 -0
- package/dist/tools/builtin/bash.d.ts.map +1 -0
- package/dist/tools/builtin/bash.js +80 -0
- package/dist/tools/builtin/bash.js.map +1 -0
- package/dist/tools/builtin/edit.d.ts +7 -0
- package/dist/tools/builtin/edit.d.ts.map +1 -0
- package/dist/tools/builtin/edit.js +32 -0
- package/dist/tools/builtin/edit.js.map +1 -0
- package/dist/tools/builtin/glob.d.ts +7 -0
- package/dist/tools/builtin/glob.d.ts.map +1 -0
- package/dist/tools/builtin/glob.js +36 -0
- package/dist/tools/builtin/glob.js.map +1 -0
- package/dist/tools/builtin/grep.d.ts +7 -0
- package/dist/tools/builtin/grep.d.ts.map +1 -0
- package/dist/tools/builtin/grep.js +59 -0
- package/dist/tools/builtin/grep.js.map +1 -0
- package/dist/tools/builtin/read.d.ts +7 -0
- package/dist/tools/builtin/read.d.ts.map +1 -0
- package/dist/tools/builtin/read.js +29 -0
- package/dist/tools/builtin/read.js.map +1 -0
- package/dist/tools/builtin/write.d.ts +7 -0
- package/dist/tools/builtin/write.d.ts.map +1 -0
- package/dist/tools/builtin/write.js +24 -0
- package/dist/tools/builtin/write.js.map +1 -0
- package/dist/tools/index.d.ts +38 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +32 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +22 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +71 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +62 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +126 -0
- package/dist/tools/types.js.map +1 -0
- package/docs/README.md +16 -0
- package/docs/proposals/0001-web-fetch-tool.md +293 -0
- package/docs/proposals/0002-web-search-tool.md +306 -0
- package/docs/proposals/0003-task-subagents.md +333 -0
- package/docs/proposals/0004-plan-mode.md +338 -0
- package/docs/proposals/0005-todo-system.md +299 -0
- package/docs/proposals/0006-memory-system.md +539 -0
- package/docs/proposals/0007-context-management.md +429 -0
- package/docs/proposals/0008-checkpointing.md +327 -0
- package/docs/proposals/0009-hooks-system.md +343 -0
- package/docs/proposals/0010-mcp-integration.md +382 -0
- package/docs/proposals/0011-custom-commands.md +374 -0
- package/docs/proposals/0012-ask-user-question.md +317 -0
- package/docs/proposals/0013-multi-edit-tool.md +345 -0
- package/docs/proposals/0014-lsp-tool.md +478 -0
- package/docs/proposals/0015-ls-tool.md +407 -0
- package/docs/proposals/0016-kill-shell-tool.md +455 -0
- package/docs/proposals/0017-background-tasks.md +489 -0
- package/docs/proposals/0018-parallel-tool-execution.md +415 -0
- package/docs/proposals/0019-session-enhancements.md +462 -0
- package/docs/proposals/0020-session-summarization.md +447 -0
- package/docs/proposals/0021-skills-system.md +409 -0
- package/docs/proposals/0022-plugin-system.md +467 -0
- package/docs/proposals/0023-permission-enhancements.md +470 -0
- package/docs/proposals/0024-keyboard-shortcuts.md +443 -0
- package/docs/proposals/0025-cost-tracking.md +447 -0
- package/docs/proposals/0026-git-integration.md +475 -0
- package/docs/proposals/0027-enhanced-read-tool.md +514 -0
- package/docs/proposals/0028-enhanced-bash-tool.md +511 -0
- package/docs/proposals/0029-notebook-edit-tool.md +413 -0
- package/docs/proposals/0030-plugin-marketplace.md +360 -0
- package/docs/proposals/0031-command-suggestions.md +295 -0
- package/docs/proposals/0032-ide-integrations.md +328 -0
- package/docs/proposals/0033-enterprise-deployment.md +221 -0
- package/docs/proposals/0034-sandboxing.md +273 -0
- package/docs/proposals/0035-auto-updater.md +311 -0
- package/docs/proposals/0036-enhanced-glob-tool.md +267 -0
- package/docs/proposals/0037-enhanced-grep-tool.md +360 -0
- package/docs/proposals/0038-interactive-cli-ui.md +373 -0
- package/docs/proposals/0039-streaming-enhancements.md +359 -0
- package/docs/proposals/0040-multi-provider-enhancements.md +369 -0
- package/docs/proposals/README.md +84 -0
- package/docs/proposals/TEMPLATE.md +57 -0
- package/docs/proposals/research/claude-code-research.md +307 -0
- package/examples/agent-demo.ts +115 -0
- package/examples/basic.ts +166 -0
- package/package.json +50 -0
- package/src/agent/agent.ts +276 -0
- package/src/agent/index.ts +6 -0
- package/src/agent/types.ts +62 -0
- package/src/cli/components/App.tsx +565 -0
- package/src/cli/components/CommandSuggestions.tsx +58 -0
- package/src/cli/components/Header.tsx +36 -0
- package/src/cli/components/Input.tsx +60 -0
- package/src/cli/components/Logo.tsx +16 -0
- package/src/cli/components/Messages.tsx +210 -0
- package/src/cli/components/ModelSelector.tsx +135 -0
- package/src/cli/components/Spinner.tsx +72 -0
- package/src/cli/components/index.ts +21 -0
- package/src/cli/components/theme.ts +36 -0
- package/src/cli/index.tsx +136 -0
- package/src/config/index.ts +7 -0
- package/src/config/manager.ts +77 -0
- package/src/config/types.ts +25 -0
- package/src/index.ts +86 -0
- package/src/permissions/index.ts +7 -0
- package/src/permissions/manager.ts +97 -0
- package/src/permissions/types.ts +29 -0
- package/src/providers/anthropic.ts +224 -0
- package/src/providers/gemini.ts +295 -0
- package/src/providers/index.ts +97 -0
- package/src/providers/openai.ts +261 -0
- package/src/providers/types.ts +181 -0
- package/src/session/index.ts +6 -0
- package/src/session/manager.ts +354 -0
- package/src/session/types.ts +49 -0
- package/src/tools/builtin/bash.ts +92 -0
- package/src/tools/builtin/edit.ts +37 -0
- package/src/tools/builtin/glob.ts +42 -0
- package/src/tools/builtin/grep.ts +67 -0
- package/src/tools/builtin/read.ts +34 -0
- package/src/tools/builtin/write.ts +27 -0
- package/src/tools/index.ts +36 -0
- package/src/tools/registry.ts +83 -0
- package/src/tools/types.ts +172 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
# Proposal: Plugin System
|
|
2
|
+
|
|
3
|
+
- **Proposal ID**: 0022
|
|
4
|
+
- **Author**: mycode team
|
|
5
|
+
- **Status**: Draft
|
|
6
|
+
- **Created**: 2025-01-15
|
|
7
|
+
- **Updated**: 2025-01-15
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Implement a plugin system that allows packaging and distributing collections of skills, commands, and subagents. Plugins enable community contributions and organizational customization of mycode capabilities.
|
|
12
|
+
|
|
13
|
+
## Motivation
|
|
14
|
+
|
|
15
|
+
Currently, mycode has no mechanism for distributing extensions:
|
|
16
|
+
|
|
17
|
+
1. **No packaging**: Can't bundle related capabilities
|
|
18
|
+
2. **No versioning**: No way to track capability versions
|
|
19
|
+
3. **No distribution**: Can't share with others
|
|
20
|
+
4. **No discovery**: Hard to find available extensions
|
|
21
|
+
5. **Manual installation**: Copy/paste files to add features
|
|
22
|
+
|
|
23
|
+
A plugin system enables ecosystem growth and easy extensibility.
|
|
24
|
+
|
|
25
|
+
## Claude Code Reference
|
|
26
|
+
|
|
27
|
+
Claude Code uses a plugin system with marketplace support:
|
|
28
|
+
|
|
29
|
+
### Plugin Structure
|
|
30
|
+
```
|
|
31
|
+
plugin-name/
|
|
32
|
+
├── .claude-plugin/
|
|
33
|
+
│ └── plugin.json # Plugin manifest
|
|
34
|
+
├── commands/
|
|
35
|
+
│ ├── command-1.md
|
|
36
|
+
│ └── command-2.md
|
|
37
|
+
├── skills/
|
|
38
|
+
│ └── skill-name/
|
|
39
|
+
│ └── SKILL.md
|
|
40
|
+
├── agents/
|
|
41
|
+
│ └── subagent-name.md
|
|
42
|
+
└── README.md
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Plugin Manifest (plugin.json)
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"name": "jira-tools",
|
|
49
|
+
"description": "Jira management and automation tools",
|
|
50
|
+
"version": "1.0.0",
|
|
51
|
+
"author": {
|
|
52
|
+
"name": "Team Name"
|
|
53
|
+
},
|
|
54
|
+
"repository": "https://github.com/org/repo"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Marketplace Configuration
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"cc-plugins": {
|
|
62
|
+
"type": "local",
|
|
63
|
+
"path": "/path/to/plugins"
|
|
64
|
+
},
|
|
65
|
+
"remote-plugins": {
|
|
66
|
+
"type": "github",
|
|
67
|
+
"source": "org/repo",
|
|
68
|
+
"cache_dir": "~/.mycode/plugins/cache/remote"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Plugin Activation
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"enabledPlugins": {
|
|
77
|
+
"jira-tools@remote-plugins": true,
|
|
78
|
+
"git@cc-plugins": true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Detailed Design
|
|
84
|
+
|
|
85
|
+
### API Design
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// src/plugins/types.ts
|
|
89
|
+
interface PluginManifest {
|
|
90
|
+
name: string;
|
|
91
|
+
description: string;
|
|
92
|
+
version: string;
|
|
93
|
+
author?: {
|
|
94
|
+
name: string;
|
|
95
|
+
email?: string;
|
|
96
|
+
url?: string;
|
|
97
|
+
};
|
|
98
|
+
repository?: string;
|
|
99
|
+
homepage?: string;
|
|
100
|
+
keywords?: string[];
|
|
101
|
+
dependencies?: Record<string, string>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
interface Plugin {
|
|
105
|
+
manifest: PluginManifest;
|
|
106
|
+
commands: CommandDefinition[];
|
|
107
|
+
skills: SkillDefinition[];
|
|
108
|
+
agents: AgentDefinition[];
|
|
109
|
+
path: string;
|
|
110
|
+
marketplace: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface Marketplace {
|
|
114
|
+
id: string;
|
|
115
|
+
type: 'local' | 'github' | 'npm';
|
|
116
|
+
source: string; // path for local, "org/repo" for github
|
|
117
|
+
cacheDir?: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface PluginRegistry {
|
|
121
|
+
marketplaces: Map<string, Marketplace>;
|
|
122
|
+
plugins: Map<string, Plugin>; // "name@marketplace" -> Plugin
|
|
123
|
+
enabled: Set<string>; // Enabled plugin IDs
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Plugin Manager
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// src/plugins/manager.ts
|
|
131
|
+
class PluginManager {
|
|
132
|
+
private marketplaces: Map<string, Marketplace> = new Map();
|
|
133
|
+
private plugins: Map<string, Plugin> = new Map();
|
|
134
|
+
private enabled: Set<string> = new Set();
|
|
135
|
+
private cacheDir: string;
|
|
136
|
+
|
|
137
|
+
constructor(cacheDir = '~/.mycode/plugins/cache') {
|
|
138
|
+
this.cacheDir = expandPath(cacheDir);
|
|
139
|
+
this.loadMarketplaces();
|
|
140
|
+
this.loadEnabledPlugins();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private loadMarketplaces(): void {
|
|
144
|
+
const configPath = expandPath('~/.mycode/plugins/marketplaces.json');
|
|
145
|
+
if (fs.existsSync(configPath)) {
|
|
146
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
147
|
+
for (const [id, marketplace] of Object.entries(config)) {
|
|
148
|
+
this.marketplaces.set(id, marketplace as Marketplace);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Add default local marketplace
|
|
153
|
+
this.marketplaces.set('local', {
|
|
154
|
+
id: 'local',
|
|
155
|
+
type: 'local',
|
|
156
|
+
source: expandPath('~/.mycode/plugins')
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async install(pluginId: string): Promise<Plugin> {
|
|
161
|
+
const [name, marketplaceId] = this.parsePluginId(pluginId);
|
|
162
|
+
const marketplace = this.marketplaces.get(marketplaceId);
|
|
163
|
+
|
|
164
|
+
if (!marketplace) {
|
|
165
|
+
throw new Error(`Marketplace not found: ${marketplaceId}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let plugin: Plugin;
|
|
169
|
+
|
|
170
|
+
switch (marketplace.type) {
|
|
171
|
+
case 'local':
|
|
172
|
+
plugin = await this.loadLocalPlugin(marketplace, name);
|
|
173
|
+
break;
|
|
174
|
+
case 'github':
|
|
175
|
+
plugin = await this.fetchGitHubPlugin(marketplace, name);
|
|
176
|
+
break;
|
|
177
|
+
case 'npm':
|
|
178
|
+
plugin = await this.fetchNpmPlugin(marketplace, name);
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
this.plugins.set(pluginId, plugin);
|
|
183
|
+
return plugin;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async enable(pluginId: string): Promise<void> {
|
|
187
|
+
if (!this.plugins.has(pluginId)) {
|
|
188
|
+
await this.install(pluginId);
|
|
189
|
+
}
|
|
190
|
+
this.enabled.add(pluginId);
|
|
191
|
+
this.saveEnabledPlugins();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async disable(pluginId: string): Promise<void> {
|
|
195
|
+
this.enabled.delete(pluginId);
|
|
196
|
+
this.saveEnabledPlugins();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private async loadLocalPlugin(marketplace: Marketplace, name: string): Promise<Plugin> {
|
|
200
|
+
const pluginPath = path.join(marketplace.source, name);
|
|
201
|
+
const manifestPath = path.join(pluginPath, '.claude-plugin', 'plugin.json');
|
|
202
|
+
|
|
203
|
+
if (!fs.existsSync(manifestPath)) {
|
|
204
|
+
throw new Error(`Plugin manifest not found: ${manifestPath}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const manifest: PluginManifest = JSON.parse(
|
|
208
|
+
fs.readFileSync(manifestPath, 'utf-8')
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
manifest,
|
|
213
|
+
commands: await this.loadCommands(path.join(pluginPath, 'commands')),
|
|
214
|
+
skills: await this.loadSkills(path.join(pluginPath, 'skills')),
|
|
215
|
+
agents: await this.loadAgents(path.join(pluginPath, 'agents')),
|
|
216
|
+
path: pluginPath,
|
|
217
|
+
marketplace: marketplace.id
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private async fetchGitHubPlugin(marketplace: Marketplace, name: string): Promise<Plugin> {
|
|
222
|
+
const cacheDir = path.join(
|
|
223
|
+
this.cacheDir,
|
|
224
|
+
marketplace.id,
|
|
225
|
+
name
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
// Check cache
|
|
229
|
+
if (fs.existsSync(cacheDir)) {
|
|
230
|
+
return this.loadLocalPlugin({ ...marketplace, source: cacheDir }, '.');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Fetch from GitHub
|
|
234
|
+
const [owner, repo] = marketplace.source.split('/');
|
|
235
|
+
const pluginPath = `plugins/${name}`;
|
|
236
|
+
|
|
237
|
+
await this.downloadFromGitHub(owner, repo, pluginPath, cacheDir);
|
|
238
|
+
|
|
239
|
+
return this.loadLocalPlugin({ ...marketplace, source: cacheDir }, '.');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
getEnabledPlugins(): Plugin[] {
|
|
243
|
+
return Array.from(this.enabled)
|
|
244
|
+
.map(id => this.plugins.get(id))
|
|
245
|
+
.filter((p): p is Plugin => p !== undefined);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
getAllCommands(): CommandDefinition[] {
|
|
249
|
+
return this.getEnabledPlugins()
|
|
250
|
+
.flatMap(p => p.commands.map(c => ({
|
|
251
|
+
...c,
|
|
252
|
+
fullName: `${p.manifest.name}:${c.name}`
|
|
253
|
+
})));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
getAllSkills(): SkillDefinition[] {
|
|
257
|
+
return this.getEnabledPlugins()
|
|
258
|
+
.flatMap(p => p.skills.map(s => ({
|
|
259
|
+
...s,
|
|
260
|
+
fullName: `${p.manifest.name}:${s.name}`
|
|
261
|
+
})));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export const pluginManager = new PluginManager();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### CLI Commands
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// src/cli/commands/plugin.ts
|
|
272
|
+
const pluginCommands = {
|
|
273
|
+
'/plugin list': 'List all available plugins',
|
|
274
|
+
'/plugin install <name@marketplace>': 'Install a plugin',
|
|
275
|
+
'/plugin enable <name@marketplace>': 'Enable a plugin',
|
|
276
|
+
'/plugin disable <name@marketplace>': 'Disable a plugin',
|
|
277
|
+
'/plugin info <name@marketplace>': 'Show plugin details',
|
|
278
|
+
'/plugin update [name@marketplace]': 'Update plugin(s)',
|
|
279
|
+
'/plugin create <name>': 'Create new plugin template'
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
async function handlePluginCommand(args: string[]): Promise<void> {
|
|
283
|
+
const [subcommand, ...rest] = args;
|
|
284
|
+
|
|
285
|
+
switch (subcommand) {
|
|
286
|
+
case 'list':
|
|
287
|
+
const plugins = pluginManager.getAllPlugins();
|
|
288
|
+
printPluginTable(plugins);
|
|
289
|
+
break;
|
|
290
|
+
|
|
291
|
+
case 'install':
|
|
292
|
+
const installed = await pluginManager.install(rest[0]);
|
|
293
|
+
console.log(`Installed: ${installed.manifest.name}@${installed.manifest.version}`);
|
|
294
|
+
break;
|
|
295
|
+
|
|
296
|
+
case 'enable':
|
|
297
|
+
await pluginManager.enable(rest[0]);
|
|
298
|
+
console.log(`Enabled: ${rest[0]}`);
|
|
299
|
+
break;
|
|
300
|
+
|
|
301
|
+
// ... other subcommands
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### File Changes
|
|
307
|
+
|
|
308
|
+
| File | Action | Description |
|
|
309
|
+
|------|--------|-------------|
|
|
310
|
+
| `src/plugins/types.ts` | Create | Type definitions |
|
|
311
|
+
| `src/plugins/manager.ts` | Create | Plugin lifecycle management |
|
|
312
|
+
| `src/plugins/loader.ts` | Create | Plugin loading utilities |
|
|
313
|
+
| `src/plugins/marketplace.ts` | Create | Marketplace interaction |
|
|
314
|
+
| `src/plugins/index.ts` | Create | Module exports |
|
|
315
|
+
| `src/cli/commands/plugin.ts` | Create | Plugin CLI commands |
|
|
316
|
+
| `src/skills/registry.ts` | Modify | Load skills from plugins |
|
|
317
|
+
|
|
318
|
+
## User Experience
|
|
319
|
+
|
|
320
|
+
### List Plugins
|
|
321
|
+
```
|
|
322
|
+
User: /plugin list
|
|
323
|
+
|
|
324
|
+
Installed Plugins:
|
|
325
|
+
┌────────────────────────────────────────────────────────────────┐
|
|
326
|
+
│ Plugin Version Marketplace Status Components │
|
|
327
|
+
├────────────────────────────────────────────────────────────────┤
|
|
328
|
+
│ jira-tools 1.2.0 acm-plugins enabled 3 cmd, 2 skl │
|
|
329
|
+
│ git 0.5.0 local enabled 5 cmd, 1 skl │
|
|
330
|
+
│ test-helpers 1.0.0 npm disabled 2 cmd │
|
|
331
|
+
└────────────────────────────────────────────────────────────────┘
|
|
332
|
+
|
|
333
|
+
Use /plugin info <name> for details
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Install Plugin
|
|
337
|
+
```
|
|
338
|
+
User: /plugin install code-quality@npm
|
|
339
|
+
|
|
340
|
+
Fetching code-quality from npm registry...
|
|
341
|
+
Installing version 2.1.0...
|
|
342
|
+
|
|
343
|
+
✓ Installed: code-quality@2.1.0
|
|
344
|
+
Components:
|
|
345
|
+
- Commands: lint, format, analyze
|
|
346
|
+
- Skills: code-reviewer
|
|
347
|
+
- Agents: (none)
|
|
348
|
+
|
|
349
|
+
Enable with: /plugin enable code-quality@npm
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Plugin Details
|
|
353
|
+
```
|
|
354
|
+
User: /plugin info jira-tools@acm-plugins
|
|
355
|
+
|
|
356
|
+
┌─ jira-tools ──────────────────────────────────────┐
|
|
357
|
+
│ Version: 1.2.0 │
|
|
358
|
+
│ Author: ACM QE Team │
|
|
359
|
+
│ Repository: github.com/org/acm-workflows │
|
|
360
|
+
│ │
|
|
361
|
+
│ Description: │
|
|
362
|
+
│ Comprehensive Jira management and automation │
|
|
363
|
+
│ tools for Red Hat ACM workflows. │
|
|
364
|
+
│ │
|
|
365
|
+
│ Commands: │
|
|
366
|
+
│ • /jira:my-issues - List assigned issues │
|
|
367
|
+
│ • /jira:sprint-issues - Sprint overview │
|
|
368
|
+
│ • /jira:add-labels - Add labels to issues │
|
|
369
|
+
│ │
|
|
370
|
+
│ Skills: │
|
|
371
|
+
│ • jira-analyzer - Complexity assessment │
|
|
372
|
+
│ • test-plan-generator - Generate test plans │
|
|
373
|
+
│ │
|
|
374
|
+
│ Status: Enabled │
|
|
375
|
+
└───────────────────────────────────────────────────┘
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Create Plugin Template
|
|
379
|
+
```
|
|
380
|
+
User: /plugin create my-tools
|
|
381
|
+
|
|
382
|
+
Created plugin template at:
|
|
383
|
+
~/.mycode/plugins/my-tools/
|
|
384
|
+
|
|
385
|
+
Structure:
|
|
386
|
+
.claude-plugin/plugin.json
|
|
387
|
+
commands/
|
|
388
|
+
skills/
|
|
389
|
+
agents/
|
|
390
|
+
README.md
|
|
391
|
+
|
|
392
|
+
Edit plugin.json to configure, then:
|
|
393
|
+
/plugin enable my-tools@local
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Alternatives Considered
|
|
397
|
+
|
|
398
|
+
### Alternative 1: NPM-only Distribution
|
|
399
|
+
Use npm for all plugins.
|
|
400
|
+
|
|
401
|
+
**Pros**: Established ecosystem
|
|
402
|
+
**Cons**: Requires npm account, heavier
|
|
403
|
+
**Decision**: Support NPM as one option
|
|
404
|
+
|
|
405
|
+
### Alternative 2: Git Submodules
|
|
406
|
+
Use git submodules for plugins.
|
|
407
|
+
|
|
408
|
+
**Pros**: Version control integrated
|
|
409
|
+
**Cons**: Complex for users
|
|
410
|
+
**Decision**: Rejected - Too complex
|
|
411
|
+
|
|
412
|
+
### Alternative 3: Single File Plugins
|
|
413
|
+
Package plugins as single files.
|
|
414
|
+
|
|
415
|
+
**Pros**: Simpler distribution
|
|
416
|
+
**Cons**: Limited capabilities
|
|
417
|
+
**Decision**: Rejected - Need multi-file support
|
|
418
|
+
|
|
419
|
+
## Security Considerations
|
|
420
|
+
|
|
421
|
+
1. **Source Verification**: Verify plugin sources
|
|
422
|
+
2. **Sandboxing**: Limit plugin capabilities
|
|
423
|
+
3. **Permission Review**: Show required permissions on install
|
|
424
|
+
4. **Version Pinning**: Support exact version requirements
|
|
425
|
+
5. **Signature Verification**: Optional plugin signing
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
interface SecurityPolicy {
|
|
429
|
+
requireSignature: boolean;
|
|
430
|
+
allowedMarketplaces: string[];
|
|
431
|
+
blockedPlugins: string[];
|
|
432
|
+
maxPlugins: number;
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## Testing Strategy
|
|
437
|
+
|
|
438
|
+
1. **Unit Tests**:
|
|
439
|
+
- Manifest parsing
|
|
440
|
+
- Plugin loading
|
|
441
|
+
- Marketplace fetching
|
|
442
|
+
- Version resolution
|
|
443
|
+
|
|
444
|
+
2. **Integration Tests**:
|
|
445
|
+
- Install/enable/disable flow
|
|
446
|
+
- Multi-marketplace scenarios
|
|
447
|
+
- Plugin conflicts
|
|
448
|
+
|
|
449
|
+
3. **Manual Testing**:
|
|
450
|
+
- Various plugin types
|
|
451
|
+
- Error scenarios
|
|
452
|
+
- Update workflow
|
|
453
|
+
|
|
454
|
+
## Migration Path
|
|
455
|
+
|
|
456
|
+
1. **Phase 1**: Local plugin support
|
|
457
|
+
2. **Phase 2**: GitHub marketplace
|
|
458
|
+
3. **Phase 3**: NPM marketplace
|
|
459
|
+
4. **Phase 4**: Plugin creation tools
|
|
460
|
+
5. **Phase 5**: Marketplace browser
|
|
461
|
+
|
|
462
|
+
## References
|
|
463
|
+
|
|
464
|
+
- [Claude Code Plugin System](https://code.claude.com/docs/en/plugins)
|
|
465
|
+
- [VSCode Extension API](https://code.visualstudio.com/api)
|
|
466
|
+
- [npm Package Specification](https://docs.npmjs.com/about-packages-and-modules)
|
|
467
|
+
- [Skills System Proposal (0021)](./0021-skills-system.md)
|