@agentplugins/core 0.1.0 → 0.2.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/README.md +2 -2
- package/dist/adapter.d.ts +15 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +14 -0
- package/dist/adapter.js.map +1 -0
- package/dist/codegen.d.ts +22 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +178 -0
- package/dist/codegen.js.map +1 -0
- package/dist/index.d.ts +6 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/lint.d.ts +29 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +238 -0
- package/dist/lint.js.map +1 -0
- package/dist/store.d.ts +178 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +620 -0
- package/dist/store.js.map +1 -0
- package/package.json +14 -9
- package/dist/profiling-hof.d.ts +0 -11
- package/dist/profiling-hof.d.ts.map +0 -1
- package/dist/profiling-hof.js +0 -80
- package/dist/profiling-hof.js.map +0 -1
- package/dist/profiling.d.ts +0 -64
- package/dist/profiling.d.ts.map +0 -1
- package/dist/profiling.js +0 -58
- package/dist/profiling.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @agentplugins/core
|
|
2
2
|
|
|
3
|
-
> Core types, validation, and plugin registry for [AgentPlugins](https://github.com/
|
|
3
|
+
> Core types, validation, and plugin registry for [AgentPlugins](https://github.com/sigilco/agentplugins).
|
|
4
4
|
|
|
5
5
|
`@agentplugins/core` defines the universal plugin manifest (`PluginManifest`), runs schema validation, and exposes the adapter registry that platform adapters register themselves with. It is the **Port** in AgentPlugins's Ports & Adapters (Hexagonal) architecture.
|
|
6
6
|
|
|
@@ -50,7 +50,7 @@ if (issues.some(i => i.severity === 'error')) {
|
|
|
50
50
|
|
|
51
51
|
- [`@agentplugins/cli`](https://www.npmjs.com/package/@agentplugins/cli) — build, validate, and scaffold plugins.
|
|
52
52
|
- [`@agentplugins/adapter-claude`](https://www.npmjs.com/package/@agentplugins/adapter-claude) and the other 6 platform adapters.
|
|
53
|
-
- Root repo: <https://github.com/
|
|
53
|
+
- Root repo: <https://github.com/sigilco/agentplugins>
|
|
54
54
|
|
|
55
55
|
## License
|
|
56
56
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentPlugins Adapter Layer
|
|
3
|
+
*
|
|
4
|
+
* For adapter developers building platform-specific compilers.
|
|
5
|
+
*/
|
|
6
|
+
export type { PlatformAdapter, AdapterOutput, FileOutput, HandlerType, ValidationIssue, BuildConfig, UniversalHookName, HookDefinition, } from './types.js';
|
|
7
|
+
export type { FileOutput as AdapterFile } from './types.js';
|
|
8
|
+
export { validateUniversal, validateForPlatform, getPlatformConstraints, } from './validation.js';
|
|
9
|
+
export type { PlatformConstraints } from './validation.js';
|
|
10
|
+
export { registerAdapter, hasAdapter, loadAdapter, loadAllAdapters, getRegisteredPlatforms, registerBuiltinAdapters, } from './registry.js';
|
|
11
|
+
export { generateHookWrapper, generateHandlersModule, serializeHandler, } from './hook-wrapper.js';
|
|
12
|
+
export type { WrapperOptions } from './hook-wrapper.js';
|
|
13
|
+
export { extractCompiledHooks, getEmitter, TypeScriptEmitter, JavaScriptEmitter, GoEmitter, } from './codegen.js';
|
|
14
|
+
export type { EmitLanguage, CompiledHook, CodeEmitter, } from './codegen.js';
|
|
15
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,eAAe,EACf,aAAa,EACb,UAAU,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EACL,eAAe,EACf,UAAU,EACV,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,GACV,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,cAAc,CAAC"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentPlugins Adapter Layer
|
|
3
|
+
*
|
|
4
|
+
* For adapter developers building platform-specific compilers.
|
|
5
|
+
*/
|
|
6
|
+
// Validation
|
|
7
|
+
export { validateUniversal, validateForPlatform, getPlatformConstraints, } from './validation.js';
|
|
8
|
+
// Registry
|
|
9
|
+
export { registerAdapter, hasAdapter, loadAdapter, loadAllAdapters, getRegisteredPlatforms, registerBuiltinAdapters, } from './registry.js';
|
|
10
|
+
// Hook Wrapper Generation
|
|
11
|
+
export { generateHookWrapper, generateHandlersModule, serializeHandler, } from './hook-wrapper.js';
|
|
12
|
+
// Codegen — multi-language CodeEmitter abstraction
|
|
13
|
+
export { extractCompiledHooks, getEmitter, TypeScriptEmitter, JavaScriptEmitter, GoEmitter, } from './codegen.js';
|
|
14
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgBH,aAAa;AACb,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAGzB,WAAW;AACX,OAAO,EACL,eAAe,EACf,UAAU,EACV,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,eAAe,CAAC;AAEvB,0BAA0B;AAC1B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,mDAAmD;AACnD,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,GACV,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PluginManifest, UniversalHookName, FileOutput } from './types.js';
|
|
2
|
+
export type EmitLanguage = 'typescript' | 'javascript' | 'go';
|
|
3
|
+
export interface CompiledHook {
|
|
4
|
+
name: UniversalHookName;
|
|
5
|
+
matcher?: string;
|
|
6
|
+
handlerType: 'command' | 'http' | 'inline' | 'reference';
|
|
7
|
+
command?: string;
|
|
8
|
+
url?: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
reference?: string;
|
|
11
|
+
inlineSource?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CodeEmitter {
|
|
14
|
+
readonly language: EmitLanguage;
|
|
15
|
+
emit(manifest: PluginManifest, hooks: CompiledHook[]): FileOutput[];
|
|
16
|
+
}
|
|
17
|
+
export declare function extractCompiledHooks(manifest: PluginManifest): CompiledHook[];
|
|
18
|
+
export declare const TypeScriptEmitter: CodeEmitter;
|
|
19
|
+
export declare const JavaScriptEmitter: CodeEmitter;
|
|
20
|
+
export declare const GoEmitter: CodeEmitter;
|
|
21
|
+
export declare function getEmitter(language: EmitLanguage): CodeEmitter;
|
|
22
|
+
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,UAAU,EAEX,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,IAAI,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,UAAU,EAAE,CAAC;CACrE;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY,EAAE,CA6B7E;AAyDD,eAAO,MAAM,iBAAiB,EAAE,WAiB/B,CAAC;AAQF,eAAO,MAAM,iBAAiB,EAAE,WAoC/B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,WAsCvB,CAAC;AAQF,wBAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,WAAW,CAM9D"}
|
package/dist/codegen.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
export function extractCompiledHooks(manifest) {
|
|
2
|
+
const hooks = manifest.hooks;
|
|
3
|
+
if (!hooks)
|
|
4
|
+
return [];
|
|
5
|
+
const compiled = [];
|
|
6
|
+
for (const name of Object.keys(hooks)) {
|
|
7
|
+
const def = hooks[name];
|
|
8
|
+
if (!def)
|
|
9
|
+
continue;
|
|
10
|
+
const handler = def.handler;
|
|
11
|
+
const entry = {
|
|
12
|
+
name,
|
|
13
|
+
handlerType: handler.type,
|
|
14
|
+
...(def.matcher !== undefined ? { matcher: def.matcher } : {}),
|
|
15
|
+
};
|
|
16
|
+
if (handler.type === 'command') {
|
|
17
|
+
entry.command = handler.command;
|
|
18
|
+
}
|
|
19
|
+
else if (handler.type === 'http') {
|
|
20
|
+
entry.url = handler.url;
|
|
21
|
+
if (handler.headers)
|
|
22
|
+
entry.headers = { ...handler.headers };
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
entry.inlineSource = `// inline handler for ${name} — emit at build time`;
|
|
26
|
+
}
|
|
27
|
+
compiled.push(entry);
|
|
28
|
+
}
|
|
29
|
+
return compiled;
|
|
30
|
+
}
|
|
31
|
+
function escapeStr(value) {
|
|
32
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
33
|
+
}
|
|
34
|
+
function pascalCase(name) {
|
|
35
|
+
if (name.length === 0)
|
|
36
|
+
return name;
|
|
37
|
+
const first = name.charAt(0).toUpperCase();
|
|
38
|
+
const rest = name.slice(1);
|
|
39
|
+
const parts = rest.split(/(?=[A-Z])/).map((p) => p.charAt(0).toUpperCase() + p.slice(1));
|
|
40
|
+
return first + parts.join('');
|
|
41
|
+
}
|
|
42
|
+
function hookEntry(hook) {
|
|
43
|
+
switch (hook.handlerType) {
|
|
44
|
+
case 'command':
|
|
45
|
+
return `{ command: "${escapeStr(hook.command ?? '')}" }`;
|
|
46
|
+
case 'http':
|
|
47
|
+
return `{ http: "${escapeStr(hook.url ?? '')}" }`;
|
|
48
|
+
case 'inline':
|
|
49
|
+
return `{ handler: ${hook.inlineSource ?? 'null'} }`;
|
|
50
|
+
case 'reference':
|
|
51
|
+
return `{ ref: "${escapeStr(hook.reference ?? '')}" }`;
|
|
52
|
+
default:
|
|
53
|
+
return `{}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function buildHooksMap(hooks) {
|
|
57
|
+
const indent = ' ';
|
|
58
|
+
const lines = hooks.map((h) => `${indent}${h.name}: ${hookEntry(h)},`);
|
|
59
|
+
return `{\n${lines.join('\n')}\n}`;
|
|
60
|
+
}
|
|
61
|
+
function buildSummary(manifest, hooks) {
|
|
62
|
+
return JSON.stringify({
|
|
63
|
+
name: manifest.name,
|
|
64
|
+
version: manifest.version,
|
|
65
|
+
hooks: hooks.map((h) => h.name),
|
|
66
|
+
}, null, 2);
|
|
67
|
+
}
|
|
68
|
+
function buildHeaderComment(manifest) {
|
|
69
|
+
return [
|
|
70
|
+
`/**`,
|
|
71
|
+
` * Generated by AgentPlugins`,
|
|
72
|
+
` * Plugin: ${manifest.name} v${manifest.version}`,
|
|
73
|
+
` * DO NOT EDIT — regenerated on build.`,
|
|
74
|
+
` */`,
|
|
75
|
+
].join('\n');
|
|
76
|
+
}
|
|
77
|
+
export const TypeScriptEmitter = {
|
|
78
|
+
language: 'typescript',
|
|
79
|
+
emit(manifest, hooks) {
|
|
80
|
+
const header = buildHeaderComment(manifest);
|
|
81
|
+
const hooksMap = buildHooksMap(hooks);
|
|
82
|
+
const summary = buildSummary(manifest, hooks);
|
|
83
|
+
const content = `${header}
|
|
84
|
+
|
|
85
|
+
export const hooks = ${hooksMap};
|
|
86
|
+
|
|
87
|
+
const plugin = ${summary};
|
|
88
|
+
|
|
89
|
+
export default plugin;
|
|
90
|
+
`;
|
|
91
|
+
return [{ path: 'index.ts', content }];
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
function buildHooksDTS(hooks) {
|
|
95
|
+
const indent = ' ';
|
|
96
|
+
const lines = hooks.map((h) => `${indent}${h.name}: Record<string, unknown>;`);
|
|
97
|
+
return `{\n${lines.join('\n')}\n}`;
|
|
98
|
+
}
|
|
99
|
+
export const JavaScriptEmitter = {
|
|
100
|
+
language: 'javascript',
|
|
101
|
+
emit(manifest, hooks) {
|
|
102
|
+
const header = buildHeaderComment(manifest);
|
|
103
|
+
const hooksMap = buildHooksMap(hooks);
|
|
104
|
+
const summary = buildSummary(manifest, hooks);
|
|
105
|
+
const jsContent = `${header}
|
|
106
|
+
|
|
107
|
+
export const hooks = ${hooksMap};
|
|
108
|
+
|
|
109
|
+
const plugin = ${summary};
|
|
110
|
+
|
|
111
|
+
export default plugin;
|
|
112
|
+
`;
|
|
113
|
+
const hooksDTS = buildHooksDTS(hooks);
|
|
114
|
+
const dtsContent = `${header}
|
|
115
|
+
|
|
116
|
+
export const hooks: ${hooksDTS};
|
|
117
|
+
|
|
118
|
+
export interface PluginSummary {
|
|
119
|
+
name: string;
|
|
120
|
+
version: string;
|
|
121
|
+
hooks: string[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
declare const plugin: PluginSummary;
|
|
125
|
+
export default plugin;
|
|
126
|
+
`;
|
|
127
|
+
return [
|
|
128
|
+
{ path: 'index.js', content: jsContent },
|
|
129
|
+
{ path: 'index.d.ts', content: dtsContent },
|
|
130
|
+
];
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
export const GoEmitter = {
|
|
134
|
+
language: 'go',
|
|
135
|
+
emit(manifest, hooks) {
|
|
136
|
+
const header = '// Code generated by AgentPlugins. DO NOT EDIT.';
|
|
137
|
+
const pkgLine = `package main`;
|
|
138
|
+
const imports = hooks.length > 0 ? `\nimport "context"\n` : '';
|
|
139
|
+
const funcs = hooks.map((h) => {
|
|
140
|
+
const fnName = `On${pascalCase(h.name)}`;
|
|
141
|
+
return [
|
|
142
|
+
`func ${fnName}(ctx context.Context) error {`,
|
|
143
|
+
`\t// TODO: implement ${h.handlerType} handler`,
|
|
144
|
+
`\treturn nil`,
|
|
145
|
+
`}`,
|
|
146
|
+
].join('\n');
|
|
147
|
+
});
|
|
148
|
+
const registrations = hooks.map((h) => `\t// register On${pascalCase(h.name)}`).join('\n');
|
|
149
|
+
const initFn = hooks.length > 0
|
|
150
|
+
? `\nfunc init() {\n${registrations}\n}\n`
|
|
151
|
+
: '\nfunc init() {}\n';
|
|
152
|
+
const pluginComment = `// Plugin: ${manifest.name} v${manifest.version}`;
|
|
153
|
+
const content = [
|
|
154
|
+
header,
|
|
155
|
+
pkgLine,
|
|
156
|
+
pluginComment,
|
|
157
|
+
imports,
|
|
158
|
+
...funcs,
|
|
159
|
+
initFn,
|
|
160
|
+
]
|
|
161
|
+
.filter((part) => part.length > 0)
|
|
162
|
+
.join('\n');
|
|
163
|
+
return [{ path: 'main.go', content }];
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
const EMITTERS = {
|
|
167
|
+
typescript: TypeScriptEmitter,
|
|
168
|
+
javascript: JavaScriptEmitter,
|
|
169
|
+
go: GoEmitter,
|
|
170
|
+
};
|
|
171
|
+
export function getEmitter(language) {
|
|
172
|
+
const emitter = EMITTERS[language];
|
|
173
|
+
if (!emitter) {
|
|
174
|
+
throw new Error(`Unknown emit language: ${String(language)}`);
|
|
175
|
+
}
|
|
176
|
+
return emitter;
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=codegen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The Port — universal plugin interface for AI agent harnesses.
|
|
5
5
|
*/
|
|
6
|
-
export type { PluginManifest, TargetPlatform, Skill, MCPServerConfig, ToolDefinition,
|
|
7
|
-
export type { FileOutput as AdapterFile } from './types.js';
|
|
6
|
+
export type { PluginManifest, TargetPlatform, Skill, MCPServerConfig, ToolDefinition, ToolParameter, ToolContext, ToolResult, UserConfigOption, UniversalHooks, HookHandler, CommandHookHandler, HttpHookHandler, InlineHookHandler, HookContext, HookResult, } from './types.js';
|
|
8
7
|
export { Severity } from './types.js';
|
|
9
8
|
import type { PluginManifest } from './types.js';
|
|
10
9
|
export { ALL_TARGETS, UNIVERSAL_HOOK_NAMES } from './types.js';
|
|
11
|
-
export { validateUniversal, validateForPlatform
|
|
12
|
-
export
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export type {
|
|
10
|
+
export { validateUniversal, validateForPlatform } from './validation.js';
|
|
11
|
+
export { lint, lintManifest } from './lint.js';
|
|
12
|
+
export type { LintIssue, LintRule } from './lint.js';
|
|
13
|
+
export { AGENT_PATHS, expandHome, getStorePath, getSkillsCompatPath, getPluginStorePath, getMetaPath, getAgentPaths, detectAgents, getDetectedAgents, normalizeSource, extractRepoName, initStore, cloneRepo, pullRepo, findManifestInDir, readMeta, writeMeta, installPlugin, addPluginFromSource, removePlugin, listPlugins, getPluginInfo, updatePlugin, symlinkPlugin, unlinkPluginSymlink, getSymlinks, runDoctor, } from './store.js';
|
|
14
|
+
export type { AgentPathEntry, PluginMeta, DetectedAgent, SymlinkInfo, InstalledPlugin, ManifestFindResult, InstallOptions, InstallResult, DoctorResult, DoctorIssue, } from './store.js';
|
|
16
15
|
/**
|
|
17
16
|
* Convenience function to define a plugin with TypeScript intellisense.
|
|
18
17
|
*/
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,cAAc,EACd,cAAc,EACd,KAAK,EACL,eAAe,EACf,cAAc,EACd,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,cAAc,EACd,cAAc,EACd,KAAK,EACL,eAAe,EACf,cAAc,EACd,aAAa,EACb,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,SAAS,EACT,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,UAAU,EACV,aAAa,EACb,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc,CAErE"}
|
package/dist/index.js
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
export { Severity } from './types.js';
|
|
7
7
|
// Constants
|
|
8
8
|
export { ALL_TARGETS, UNIVERSAL_HOOK_NAMES } from './types.js';
|
|
9
|
-
// Validation
|
|
10
|
-
export { validateUniversal, validateForPlatform
|
|
11
|
-
//
|
|
12
|
-
export {
|
|
13
|
-
//
|
|
14
|
-
export {
|
|
9
|
+
// Validation — plugin CI
|
|
10
|
+
export { validateUniversal, validateForPlatform } from './validation.js';
|
|
11
|
+
// Lint — plugin CI
|
|
12
|
+
export { lint, lintManifest } from './lint.js';
|
|
13
|
+
// Store — re-exported for CLI use (internal only)
|
|
14
|
+
export { AGENT_PATHS, expandHome, getStorePath, getSkillsCompatPath, getPluginStorePath, getMetaPath, getAgentPaths, detectAgents, getDetectedAgents, normalizeSource, extractRepoName, initStore, cloneRepo, pullRepo, findManifestInDir, readMeta, writeMeta, installPlugin, addPluginFromSource, removePlugin, listPlugins, getPluginInfo, updatePlugin, symlinkPlugin, unlinkPluginSymlink, getSymlinks, runDoctor, } from './store.js';
|
|
15
15
|
/**
|
|
16
16
|
* Convenience function to define a plugin with TypeScript intellisense.
|
|
17
17
|
*/
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE/D,yBAAyB;AACzB,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEzE,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG/C,kDAAkD;AAClD,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,SAAS,EACT,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC;AAcpB;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAwB;IACnD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/lint.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentPlugins Lint System
|
|
3
|
+
*
|
|
4
|
+
* Static analysis layer that runs registered rules over a plugin manifest,
|
|
5
|
+
* catching quality and safety issues beyond structural validation.
|
|
6
|
+
*/
|
|
7
|
+
import type { PluginManifest } from './types.js';
|
|
8
|
+
export interface LintIssue {
|
|
9
|
+
rule: string;
|
|
10
|
+
severity: 'error' | 'warning';
|
|
11
|
+
field?: string;
|
|
12
|
+
message: string;
|
|
13
|
+
suggestion?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface LintContext {
|
|
16
|
+
manifest: PluginManifest;
|
|
17
|
+
inlineHandlerSource?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface LintRule {
|
|
20
|
+
id: string;
|
|
21
|
+
description: string;
|
|
22
|
+
run: (ctx: LintContext) => LintIssue[];
|
|
23
|
+
}
|
|
24
|
+
export declare const BUILTIN_LINT_RULES: LintRule[];
|
|
25
|
+
export declare function registerLintRule(rule: LintRule): void;
|
|
26
|
+
export declare function getLintRules(): LintRule[];
|
|
27
|
+
export declare function lint(ctx: LintContext): LintIssue[];
|
|
28
|
+
export declare function lintManifest(manifest: PluginManifest): LintIssue[];
|
|
29
|
+
//# sourceMappingURL=lint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,cAAc,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;CACxC;AA4ND,eAAO,MAAM,kBAAkB,EAAE,QAAQ,EASxC,CAAC;AAIF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAErD;AAED,wBAAgB,YAAY,IAAI,QAAQ,EAAE,CAEzC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,CAMlD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,CAElE"}
|
package/dist/lint.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentPlugins Lint System
|
|
3
|
+
*
|
|
4
|
+
* Static analysis layer that runs registered rules over a plugin manifest,
|
|
5
|
+
* catching quality and safety issues beyond structural validation.
|
|
6
|
+
*/
|
|
7
|
+
const KEBAB_CASE_RE = /^[a-z][a-z0-9-]*$/;
|
|
8
|
+
const SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
9
|
+
const SAFETY_PATTERNS = [
|
|
10
|
+
/\beval\s*\(/,
|
|
11
|
+
/require\s*\(\s*['"]child_process['"]\s*\)/,
|
|
12
|
+
/\bchild_process\b/,
|
|
13
|
+
/fs\.unlink(Sync)?\s*\(/,
|
|
14
|
+
/\bprocess\.exit\s*\(/,
|
|
15
|
+
];
|
|
16
|
+
const SECRET_PATTERNS = [
|
|
17
|
+
/(?:sk|pk|AKIA|ghp|gho|github_pat)_[A-Za-z0-9]{16,}/,
|
|
18
|
+
/(?:api[_-]?key|secret|token|password)\s*[:=]\s*['"][^'"]{8,}['"]/i,
|
|
19
|
+
];
|
|
20
|
+
const namingRule = {
|
|
21
|
+
id: 'naming',
|
|
22
|
+
description: 'Plugin name must be kebab-case and must not self-reference the platform',
|
|
23
|
+
run: ({ manifest }) => {
|
|
24
|
+
const issues = [];
|
|
25
|
+
const { name } = manifest;
|
|
26
|
+
if (!KEBAB_CASE_RE.test(name)) {
|
|
27
|
+
issues.push({
|
|
28
|
+
rule: 'naming',
|
|
29
|
+
severity: 'error',
|
|
30
|
+
field: 'name',
|
|
31
|
+
message: `Plugin name "${name}" must be kebab-case (lowercase letters, digits, hyphens; must start with a letter)`,
|
|
32
|
+
suggestion: 'Use a name like "my-cool-plugin"',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (name.toLowerCase().startsWith('agentplugin')) {
|
|
36
|
+
issues.push({
|
|
37
|
+
rule: 'naming',
|
|
38
|
+
severity: 'error',
|
|
39
|
+
field: 'name',
|
|
40
|
+
message: 'Plugin name must not be prefixed with "agentplugin" (anti-self-reference)',
|
|
41
|
+
suggestion: 'Choose a name that describes what the plugin does',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return issues;
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
const versioningRule = {
|
|
48
|
+
id: 'versioning',
|
|
49
|
+
description: 'Plugin version must follow semantic versioning',
|
|
50
|
+
run: ({ manifest }) => {
|
|
51
|
+
if (!SEMVER_RE.test(manifest.version)) {
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
rule: 'versioning',
|
|
55
|
+
severity: 'error',
|
|
56
|
+
field: 'version',
|
|
57
|
+
message: `Version "${manifest.version}" is not valid semantic versioning`,
|
|
58
|
+
suggestion: 'Use format "MAJOR.MINOR.PATCH" e.g. "1.0.0"',
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
return [];
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const descriptionRule = {
|
|
66
|
+
id: 'description',
|
|
67
|
+
description: 'Plugin should have a meaningful description of at least 10 characters',
|
|
68
|
+
run: ({ manifest }) => {
|
|
69
|
+
if (!manifest.description || manifest.description.length === 0) {
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
rule: 'description',
|
|
73
|
+
severity: 'warning',
|
|
74
|
+
field: 'description',
|
|
75
|
+
message: 'Description is missing — add one for discoverability',
|
|
76
|
+
suggestion: 'Describe what the plugin does in a sentence',
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
if (manifest.description.length < 10) {
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
rule: 'description',
|
|
84
|
+
severity: 'warning',
|
|
85
|
+
field: 'description',
|
|
86
|
+
message: `Description is only ${manifest.description.length} chars — aim for at least 10`,
|
|
87
|
+
suggestion: 'Expand the description to better explain the plugin',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
return [];
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
const licenseRule = {
|
|
95
|
+
id: 'license',
|
|
96
|
+
description: 'Plugin should declare a license',
|
|
97
|
+
run: ({ manifest }) => {
|
|
98
|
+
if (!manifest.license) {
|
|
99
|
+
return [
|
|
100
|
+
{
|
|
101
|
+
rule: 'license',
|
|
102
|
+
severity: 'warning',
|
|
103
|
+
field: 'license',
|
|
104
|
+
message: 'License is missing — declare one for redistribution clarity',
|
|
105
|
+
suggestion: 'Common choices: MIT, Apache-2.0, ISC',
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const targetHygieneRule = {
|
|
113
|
+
id: 'target-hygiene',
|
|
114
|
+
description: 'Declared targets should have reachable hooks',
|
|
115
|
+
run: ({ manifest }) => {
|
|
116
|
+
const targets = manifest.targets;
|
|
117
|
+
const hasHooks = !!manifest.hooks && Object.keys(manifest.hooks).length > 0;
|
|
118
|
+
if (targets && targets.length > 0 && !hasHooks) {
|
|
119
|
+
return [
|
|
120
|
+
{
|
|
121
|
+
rule: 'target-hygiene',
|
|
122
|
+
severity: 'warning',
|
|
123
|
+
field: 'targets',
|
|
124
|
+
message: `Targets [${targets.join(', ')}] are declared but no hooks are defined — the plugin will have no behavior on those platforms`,
|
|
125
|
+
suggestion: 'Add hooks or remove unused targets',
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
return [];
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
const hookCoverageRule = {
|
|
133
|
+
id: 'hook-coverage',
|
|
134
|
+
description: 'Plugins that declare tools should guard them with a preToolUse hook',
|
|
135
|
+
run: ({ manifest }) => {
|
|
136
|
+
const hasTools = !!manifest.tools && manifest.tools.length > 0;
|
|
137
|
+
const hasPreToolUse = !!manifest.hooks?.preToolUse;
|
|
138
|
+
if (hasTools && !hasPreToolUse) {
|
|
139
|
+
return [
|
|
140
|
+
{
|
|
141
|
+
rule: 'hook-coverage',
|
|
142
|
+
severity: 'warning',
|
|
143
|
+
field: 'hooks.preToolUse',
|
|
144
|
+
message: 'Plugin declares tools but no preToolUse hook — tool calls will not be guarded',
|
|
145
|
+
suggestion: 'Add a preToolUse hook to validate or gate tool invocations',
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
}
|
|
149
|
+
return [];
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
const handlerSafetyRule = {
|
|
153
|
+
id: 'handler-safety',
|
|
154
|
+
description: 'Inline handler source must not contain dangerous patterns',
|
|
155
|
+
run: ({ inlineHandlerSource }) => {
|
|
156
|
+
if (!inlineHandlerSource || inlineHandlerSource.length === 0)
|
|
157
|
+
return [];
|
|
158
|
+
const issues = [];
|
|
159
|
+
for (const source of inlineHandlerSource) {
|
|
160
|
+
for (const pattern of SAFETY_PATTERNS) {
|
|
161
|
+
const match = pattern.exec(source);
|
|
162
|
+
if (match) {
|
|
163
|
+
issues.push({
|
|
164
|
+
rule: 'handler-safety',
|
|
165
|
+
severity: 'error',
|
|
166
|
+
field: 'hooks.<handler>',
|
|
167
|
+
message: `Handler source contains dangerous pattern "${match[0]}"`,
|
|
168
|
+
suggestion: 'Remove or sandbox the dangerous code',
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return issues;
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
const secretsRule = {
|
|
177
|
+
id: 'secrets',
|
|
178
|
+
description: 'Handler source and commands must not contain accidental secrets',
|
|
179
|
+
run: ({ manifest, inlineHandlerSource }) => {
|
|
180
|
+
const haystacks = [];
|
|
181
|
+
if (inlineHandlerSource) {
|
|
182
|
+
for (const src of inlineHandlerSource) {
|
|
183
|
+
haystacks.push({ field: 'hooks.<handler>', text: src });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (manifest.hooks) {
|
|
187
|
+
for (const [name, def] of Object.entries(manifest.hooks)) {
|
|
188
|
+
if (def && def.handler.type === 'command') {
|
|
189
|
+
haystacks.push({ field: `hooks.${name}`, text: def.handler.command });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const issues = [];
|
|
194
|
+
for (const { field, text } of haystacks) {
|
|
195
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
196
|
+
const match = pattern.exec(text);
|
|
197
|
+
if (match) {
|
|
198
|
+
issues.push({
|
|
199
|
+
rule: 'secrets',
|
|
200
|
+
severity: 'error',
|
|
201
|
+
field,
|
|
202
|
+
message: 'Possible secret or API token detected in handler source',
|
|
203
|
+
suggestion: 'Move secrets to environment variables or user config',
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return issues;
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
export const BUILTIN_LINT_RULES = [
|
|
212
|
+
namingRule,
|
|
213
|
+
versioningRule,
|
|
214
|
+
descriptionRule,
|
|
215
|
+
licenseRule,
|
|
216
|
+
targetHygieneRule,
|
|
217
|
+
hookCoverageRule,
|
|
218
|
+
handlerSafetyRule,
|
|
219
|
+
secretsRule,
|
|
220
|
+
];
|
|
221
|
+
let registry = [...BUILTIN_LINT_RULES];
|
|
222
|
+
export function registerLintRule(rule) {
|
|
223
|
+
registry.push(rule);
|
|
224
|
+
}
|
|
225
|
+
export function getLintRules() {
|
|
226
|
+
return registry;
|
|
227
|
+
}
|
|
228
|
+
export function lint(ctx) {
|
|
229
|
+
const issues = [];
|
|
230
|
+
for (const rule of registry) {
|
|
231
|
+
issues.push(...rule.run(ctx));
|
|
232
|
+
}
|
|
233
|
+
return issues;
|
|
234
|
+
}
|
|
235
|
+
export function lintManifest(manifest) {
|
|
236
|
+
return lint({ manifest });
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=lint.js.map
|
package/dist/lint.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
|