@h-rig/core 0.0.6-alpha.155 → 0.0.6-alpha.156
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/src/config.d.ts +1 -1
- package/dist/src/config.js +4 -91
- package/dist/src/define-plugin.d.ts +11 -7
- package/dist/src/define-plugin.js +4 -91
- package/dist/src/index.d.ts +1 -11
- package/dist/src/index.js +33 -3704
- package/dist/src/plugin-host.d.ts +25 -18
- package/dist/src/plugin-host.js +28 -149
- package/dist/src/plugin-runtime.d.ts +82 -51
- package/dist/src/project-plugins.d.ts +66 -0
- package/dist/src/project-plugins.js +596 -0
- package/dist/src/task-io.d.ts +54 -0
- package/dist/src/task-io.js +707 -0
- package/package.json +8 -20
- package/dist/src/dependencyGraph.d.ts +0 -43
- package/dist/src/dependencyGraph.js +0 -703
- package/dist/src/engineReadModelReducer.d.ts +0 -12
- package/dist/src/engineReadModelReducer.js +0 -1784
- package/dist/src/rig-init-builder.d.ts +0 -30
- package/dist/src/rig-init-builder.js +0 -61
- package/dist/src/rigSelectors.d.ts +0 -220
- package/dist/src/rigSelectors.js +0 -414
- package/dist/src/rollups.d.ts +0 -6
- package/dist/src/rollups.js +0 -377
- package/dist/src/stageResolve.d.ts +0 -77
- package/dist/src/stageResolve.js +0 -361
- package/dist/src/taskGraph.d.ts +0 -64
- package/dist/src/taskGraph.js +0 -377
- package/dist/src/taskGraphCodes.d.ts +0 -3
- package/dist/src/taskGraphCodes.js +0 -26
- package/dist/src/taskGraphLayout.d.ts +0 -61
- package/dist/src/taskGraphLayout.js +0 -397
- package/dist/src/taskScore.d.ts +0 -17
- package/dist/src/taskScore.js +0 -49
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { BlockerClassifierRegistration, CliCommandRegistration, HookRegistration, PanelRegistration, ProductCapabilityRegistration, RepoSourceRegistration,
|
|
2
|
-
import type {
|
|
1
|
+
import type { AgentRoleRegistration, BlockerClassifierRegistration, CliCommandRegistration, HookRegistration, PanelRegistration, ProductCapabilityRegistration, RepoSourceRegistration, SkillRegistration, Stage, StageMutation, StageRun, TaskFieldExtension, TaskSourceRegistration, ValidatorRegistration } from "@rig/contracts";
|
|
2
|
+
import type { BlockerClassifierEntry, CliCommand, FeatureCapability, Panel, RigPlugin, SessionExtensionEntry, TaskSource, Validator } from "./plugin-runtime";
|
|
3
3
|
export interface PluginHost {
|
|
4
4
|
getValidator(id: string): ValidatorRegistration | undefined;
|
|
5
5
|
getHook(id: string): HookRegistration | undefined;
|
|
@@ -32,34 +32,41 @@ export interface PluginHost {
|
|
|
32
32
|
*/
|
|
33
33
|
listStageMutations(): readonly StageMutation[];
|
|
34
34
|
/**
|
|
35
|
-
* Executable stage implementations contributed by plugins
|
|
36
|
-
*
|
|
37
|
-
* plugin-contributed stages
|
|
35
|
+
* Executable stage implementations contributed by plugins, derived from
|
|
36
|
+
* `contributes.stages` entries that carry a `run`, keyed by stage id. The
|
|
37
|
+
* kernel's stage runner uses these to execute plugin-contributed stages
|
|
38
|
+
* inserted via stageMutations.
|
|
38
39
|
*/
|
|
39
40
|
listStageExecutors(): Readonly<Record<string, StageRun>>;
|
|
40
41
|
/**
|
|
41
|
-
* Executable validators contributed by plugins
|
|
42
|
-
*
|
|
43
|
-
* implementation via `definePlugin(meta, { validators: [...] })` appear here.
|
|
44
|
-
* Validators registered metadata-only (no run() implementation) are absent.
|
|
42
|
+
* Executable validators contributed by plugins (single-channel: the same
|
|
43
|
+
* `contributes.validators` entries, which carry their `run`).
|
|
45
44
|
*/
|
|
46
|
-
listExecutableValidators(): readonly
|
|
45
|
+
listExecutableValidators(): readonly Validator[];
|
|
47
46
|
/**
|
|
48
47
|
* Executable task source factories contributed by plugins. Used by the
|
|
49
48
|
* runtime's `buildTaskSourceRegistry` to instantiate non-standard task
|
|
50
49
|
* source kinds (Linear, Jira, custom) declared by plugins.
|
|
51
50
|
*/
|
|
52
|
-
listExecutableTaskSources(): readonly
|
|
53
|
-
listExecutableCapabilities(): readonly
|
|
54
|
-
listExecutablePanels(): readonly
|
|
55
|
-
listExecutableBlockerClassifiers(): readonly
|
|
56
|
-
listExecutableCliCommands(): readonly
|
|
57
|
-
|
|
51
|
+
listExecutableTaskSources(): readonly TaskSource[];
|
|
52
|
+
listExecutableCapabilities(): readonly FeatureCapability[];
|
|
53
|
+
listExecutablePanels(): readonly Panel[];
|
|
54
|
+
listExecutableBlockerClassifiers(): readonly BlockerClassifierEntry[];
|
|
55
|
+
listExecutableCliCommands(): readonly CliCommand[];
|
|
56
|
+
/**
|
|
57
|
+
* Executable session-extension installers contributed by plugins. The
|
|
58
|
+
* agent-session host (rig-host) resolves these and invokes each `install(api)`
|
|
59
|
+
* at `createAgentSession` time, so the run lifecycle (and any other
|
|
60
|
+
* session-time extension) is resolved from the explicit plugin collection
|
|
61
|
+
* rather than injected directly by a leaf.
|
|
62
|
+
*/
|
|
63
|
+
listSessionExtensions(): readonly SessionExtensionEntry[];
|
|
64
|
+
resolveExecutableCliCommand(requested: string): CliCommand | undefined;
|
|
58
65
|
/**
|
|
59
66
|
* Look up an executable task source factory by its `kind` (the value in
|
|
60
67
|
* `config.taskSource.kind`). Returns undefined when no plugin provides
|
|
61
68
|
* a factory for that kind.
|
|
62
69
|
*/
|
|
63
|
-
resolveTaskSourceFactoryByKind(kind: string):
|
|
70
|
+
resolveTaskSourceFactoryByKind(kind: string): TaskSource | undefined;
|
|
64
71
|
}
|
|
65
|
-
export declare function createPluginHost(plugins: readonly
|
|
72
|
+
export declare function createPluginHost(plugins: readonly RigPlugin[]): PluginHost;
|
package/dist/src/plugin-host.js
CHANGED
|
@@ -21,102 +21,8 @@ function assertUniquePluginNames(plugins) {
|
|
|
21
21
|
seen.add(plugin.name);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
function assertRuntimeMatchesMetadata(plugin) {
|
|
25
|
-
const declaredValidators = new Map((plugin.contributes?.validators ?? []).map((validator) => [validator.id, validator]));
|
|
26
|
-
const runtimeValidators = new Map((plugin?.validators ?? []).map((validator) => [validator.id, validator]));
|
|
27
|
-
for (const validator of runtimeValidators.values()) {
|
|
28
|
-
const metadata = declaredValidators.get(validator.id);
|
|
29
|
-
if (!metadata) {
|
|
30
|
-
throw new Error(`plugin "${plugin.name}" executable validator "${validator.id}" has no matching metadata entry in contributes.validators`);
|
|
31
|
-
}
|
|
32
|
-
if (metadata.category !== validator.category) {
|
|
33
|
-
throw new Error(`plugin "${plugin.name}" executable validator "${validator.id}" category "${validator.category}" does not match metadata category "${metadata.category}"`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (plugin?.validators) {
|
|
37
|
-
for (const validator of declaredValidators.values()) {
|
|
38
|
-
if (!runtimeValidators.has(validator.id)) {
|
|
39
|
-
throw new Error(`plugin "${plugin.name}" validator metadata "${validator.id}" has no runtime implementation`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
const declaredTaskSources = new Map((plugin.contributes?.taskSources ?? []).map((source) => [source.id, source]));
|
|
44
|
-
const runtimeTaskSources = new Map((plugin?.taskSources ?? []).map((source) => [source.id, source]));
|
|
45
|
-
for (const source of runtimeTaskSources.values()) {
|
|
46
|
-
const metadata = declaredTaskSources.get(source.id);
|
|
47
|
-
if (!metadata) {
|
|
48
|
-
throw new Error(`plugin "${plugin.name}" executable task source "${source.id}" has no matching metadata entry in contributes.taskSources`);
|
|
49
|
-
}
|
|
50
|
-
if (metadata.kind !== source.kind) {
|
|
51
|
-
throw new Error(`plugin "${plugin.name}" executable task source "${source.id}" kind "${source.kind}" does not match metadata kind "${metadata.kind}"`);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (plugin?.taskSources) {
|
|
55
|
-
for (const source of declaredTaskSources.values()) {
|
|
56
|
-
if (!runtimeTaskSources.has(source.id)) {
|
|
57
|
-
throw new Error(`plugin "${plugin.name}" task source metadata "${source.id}" has no runtime implementation`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
const declaredHooks = new Map((plugin.contributes?.hooks ?? []).map((hook) => [hook.id, hook]));
|
|
62
|
-
const runtimeHooks = plugin?.hooks;
|
|
63
|
-
for (const hookId of Object.keys(runtimeHooks ?? {})) {
|
|
64
|
-
const metadata = declaredHooks.get(hookId);
|
|
65
|
-
if (!metadata) {
|
|
66
|
-
throw new Error(`plugin "${plugin.name}" typed hook "${hookId}" has no matching metadata entry in contributes.hooks`);
|
|
67
|
-
}
|
|
68
|
-
if (metadata.command) {
|
|
69
|
-
throw new Error(`plugin "${plugin.name}" hook "${hookId}" has both a typed implementation and a command string \u2014 pick one`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (runtimeHooks) {
|
|
73
|
-
for (const hook of declaredHooks.values()) {
|
|
74
|
-
if (!runtimeHooks[hook.id] && !hook.command) {
|
|
75
|
-
throw new Error(`plugin "${plugin.name}" hook metadata "${hook.id}" has no implementation (typed function or command)`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const declaredCapabilities = new Map((plugin.contributes?.capabilities ?? []).map((capability) => [capability.id, capability]));
|
|
80
|
-
const runtimeCapabilities = new Map((plugin?.featureCapabilities ?? []).map((capability) => [capability.id, capability]));
|
|
81
|
-
for (const capability of runtimeCapabilities.values()) {
|
|
82
|
-
if (!declaredCapabilities.has(capability.id)) {
|
|
83
|
-
throw new Error(`plugin "${plugin.name}" executable capability "${capability.id}" has no matching metadata entry in contributes.capabilities`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
const declaredPanels = new Map((plugin.contributes?.panels ?? []).map((panel) => [panel.id, panel]));
|
|
87
|
-
const runtimePanels = new Map((plugin?.panels ?? []).map((panel) => [panel.id, panel]));
|
|
88
|
-
for (const panel of runtimePanels.values()) {
|
|
89
|
-
const metadata = declaredPanels.get(panel.id);
|
|
90
|
-
if (!metadata) {
|
|
91
|
-
throw new Error(`plugin "${plugin.name}" executable panel "${panel.id}" has no matching metadata entry in contributes.panels`);
|
|
92
|
-
}
|
|
93
|
-
if (metadata.slot !== panel.slot) {
|
|
94
|
-
throw new Error(`plugin "${plugin.name}" executable panel "${panel.id}" slot "${panel.slot}" does not match metadata slot "${metadata.slot}"`);
|
|
95
|
-
}
|
|
96
|
-
if (metadata.capabilityId !== panel.capabilityId) {
|
|
97
|
-
throw new Error(`plugin "${plugin.name}" executable panel "${panel.id}" capabilityId "${panel.capabilityId ?? "(none)"}" does not match metadata capabilityId "${metadata.capabilityId ?? "(none)"}"`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
const declaredBlockerClassifiers = new Map((plugin.contributes?.blockerClassifiers ?? []).map((classifier) => [classifier.id, classifier]));
|
|
101
|
-
const runtimeBlockerClassifiers = new Map((plugin?.blockerClassifiers ?? []).map((classifier) => [classifier.id, classifier]));
|
|
102
|
-
for (const classifier of runtimeBlockerClassifiers.values()) {
|
|
103
|
-
if (!declaredBlockerClassifiers.has(classifier.id)) {
|
|
104
|
-
throw new Error(`plugin "${plugin.name}" executable blocker classifier "${classifier.id}" has no matching metadata entry in contributes.blockerClassifiers`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const declaredCliCommands = new Map((plugin.contributes?.cliCommands ?? []).map((command) => [command.id, command]));
|
|
108
|
-
const runtimeCliCommands = new Map((plugin?.cliCommands ?? []).map((command) => [command.id, command]));
|
|
109
|
-
for (const command of runtimeCliCommands.values()) {
|
|
110
|
-
if (!declaredCliCommands.has(command.id)) {
|
|
111
|
-
throw new Error(`plugin "${plugin.name}" executable cli command "${command.id}" has no matching metadata entry in contributes.cliCommands`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
24
|
function createPluginHost(plugins) {
|
|
116
25
|
assertUniquePluginNames(plugins);
|
|
117
|
-
for (const plugin of plugins) {
|
|
118
|
-
assertRuntimeMatchesMetadata(plugin);
|
|
119
|
-
}
|
|
120
26
|
const validators = [];
|
|
121
27
|
const hooks = [];
|
|
122
28
|
const skills = [];
|
|
@@ -128,38 +34,15 @@ function createPluginHost(plugins) {
|
|
|
128
34
|
const capabilities = [];
|
|
129
35
|
const panels = [];
|
|
130
36
|
const blockerClassifiers = [];
|
|
37
|
+
const sessionExtensions = [];
|
|
131
38
|
const stages = [];
|
|
132
39
|
const stageMutations = [];
|
|
133
40
|
const stageExecutors = {};
|
|
134
|
-
const executableValidators = [];
|
|
135
|
-
const executableTaskSources = [];
|
|
136
|
-
const executableCapabilities = [];
|
|
137
|
-
const executablePanels = [];
|
|
138
|
-
const executableBlockerClassifiers = [];
|
|
139
|
-
const executableCliCommands = [];
|
|
140
41
|
for (const plugin of plugins) {
|
|
141
42
|
const c = plugin.contributes;
|
|
142
43
|
if (!c)
|
|
143
44
|
continue;
|
|
144
45
|
const pluginName = plugin.name;
|
|
145
|
-
if (plugin?.validators) {
|
|
146
|
-
executableValidators.push(...plugin.validators.map((item) => ({ item, pluginName })));
|
|
147
|
-
}
|
|
148
|
-
if (plugin?.taskSources) {
|
|
149
|
-
executableTaskSources.push(...plugin.taskSources.map((item) => ({ item, pluginName })));
|
|
150
|
-
}
|
|
151
|
-
if (plugin?.featureCapabilities) {
|
|
152
|
-
executableCapabilities.push(...plugin.featureCapabilities.map((item) => ({ item, pluginName })));
|
|
153
|
-
}
|
|
154
|
-
if (plugin?.panels) {
|
|
155
|
-
executablePanels.push(...plugin.panels.map((item) => ({ item, pluginName })));
|
|
156
|
-
}
|
|
157
|
-
if (plugin?.blockerClassifiers) {
|
|
158
|
-
executableBlockerClassifiers.push(...plugin.blockerClassifiers.map((item) => ({ item, pluginName })));
|
|
159
|
-
}
|
|
160
|
-
if (plugin?.cliCommands) {
|
|
161
|
-
executableCliCommands.push(...plugin.cliCommands.map((item) => ({ item, pluginName })));
|
|
162
|
-
}
|
|
163
46
|
if (c.validators)
|
|
164
47
|
validators.push(...c.validators.map((item) => ({ item, pluginName })));
|
|
165
48
|
if (c.hooks)
|
|
@@ -182,27 +65,17 @@ function createPluginHost(plugins) {
|
|
|
182
65
|
panels.push(...c.panels.map((item) => ({ item, pluginName })));
|
|
183
66
|
if (c.blockerClassifiers)
|
|
184
67
|
blockerClassifiers.push(...c.blockerClassifiers.map((item) => ({ item, pluginName })));
|
|
185
|
-
if (c.
|
|
186
|
-
|
|
68
|
+
if (c.sessionExtensions)
|
|
69
|
+
sessionExtensions.push(...c.sessionExtensions.map((item) => ({ item, pluginName })));
|
|
187
70
|
if (c.stageMutations)
|
|
188
71
|
stageMutations.push(...c.stageMutations.map((item) => ({ item, pluginName })));
|
|
189
|
-
if (
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
indexById(executablePanels, "executablePanel");
|
|
196
|
-
indexById(executableBlockerClassifiers, "executableBlockerClassifier");
|
|
197
|
-
indexById(executableCliCommands, "executableCliCommand");
|
|
198
|
-
const taskSourceFactoryByKind = new Map;
|
|
199
|
-
const taskSourceKindRegistrant = new Map;
|
|
200
|
-
for (const { item, pluginName } of executableTaskSources) {
|
|
201
|
-
if (taskSourceFactoryByKind.has(item.kind)) {
|
|
202
|
-
throw new Error(`duplicate task source kind "${item.kind}": registered by plugins "${taskSourceKindRegistrant.get(item.kind)}" and "${pluginName}"`);
|
|
72
|
+
if (c.stages) {
|
|
73
|
+
for (const stage of c.stages) {
|
|
74
|
+
stages.push({ item: stage, pluginName });
|
|
75
|
+
if (stage.run)
|
|
76
|
+
stageExecutors[stage.id] = stage.run;
|
|
77
|
+
}
|
|
203
78
|
}
|
|
204
|
-
taskSourceFactoryByKind.set(item.kind, item);
|
|
205
|
-
taskSourceKindRegistrant.set(item.kind, pluginName);
|
|
206
79
|
}
|
|
207
80
|
const validatorMap = indexById(validators, "validator");
|
|
208
81
|
const hookMap = indexById(hooks, "hook");
|
|
@@ -215,6 +88,16 @@ function createPluginHost(plugins) {
|
|
|
215
88
|
const capabilityMap = indexById(capabilities, "capability");
|
|
216
89
|
const panelMap = indexById(panels, "panel");
|
|
217
90
|
const blockerClassifierMap = indexById(blockerClassifiers, "blockerClassifier");
|
|
91
|
+
indexById(sessionExtensions, "sessionExtension");
|
|
92
|
+
const taskSourceFactoryByKind = new Map;
|
|
93
|
+
const taskSourceKindRegistrant = new Map;
|
|
94
|
+
for (const { item, pluginName } of taskSources) {
|
|
95
|
+
if (taskSourceFactoryByKind.has(item.kind)) {
|
|
96
|
+
throw new Error(`duplicate task source kind "${item.kind}": registered by plugins "${taskSourceKindRegistrant.get(item.kind)}" and "${pluginName}"`);
|
|
97
|
+
}
|
|
98
|
+
taskSourceFactoryByKind.set(item.kind, item);
|
|
99
|
+
taskSourceKindRegistrant.set(item.kind, pluginName);
|
|
100
|
+
}
|
|
218
101
|
const allValidators = validators.map((c) => c.item);
|
|
219
102
|
const allHooks = hooks.map((c) => c.item);
|
|
220
103
|
const allSkills = skills.map((c) => c.item);
|
|
@@ -228,12 +111,7 @@ function createPluginHost(plugins) {
|
|
|
228
111
|
const allCapabilities = capabilities.map((c) => c.item);
|
|
229
112
|
const allPanels = panels.map((c) => c.item);
|
|
230
113
|
const allBlockerClassifiers = blockerClassifiers.map((c) => c.item);
|
|
231
|
-
const
|
|
232
|
-
const allExecutableTaskSources = executableTaskSources.map((c) => c.item);
|
|
233
|
-
const allExecutableCapabilities = executableCapabilities.map((c) => c.item);
|
|
234
|
-
const allExecutablePanels = executablePanels.map((c) => c.item);
|
|
235
|
-
const allExecutableBlockerClassifiers = executableBlockerClassifiers.map((c) => c.item);
|
|
236
|
-
const allExecutableCliCommands = executableCliCommands.map((c) => c.item);
|
|
114
|
+
const allSessionExtensions = sessionExtensions.map((c) => c.item);
|
|
237
115
|
const executableCliCommandByName = new Map;
|
|
238
116
|
const registerExecutableCliCommandSelector = (selector, contribution) => {
|
|
239
117
|
const existing = executableCliCommandByName.get(selector);
|
|
@@ -242,7 +120,7 @@ function createPluginHost(plugins) {
|
|
|
242
120
|
}
|
|
243
121
|
executableCliCommandByName.set(selector, contribution);
|
|
244
122
|
};
|
|
245
|
-
for (const contribution of
|
|
123
|
+
for (const contribution of cliCommands) {
|
|
246
124
|
const command = contribution.item;
|
|
247
125
|
const family = command.family ?? command.id;
|
|
248
126
|
registerExecutableCliCommandSelector(command.id, contribution);
|
|
@@ -277,12 +155,13 @@ function createPluginHost(plugins) {
|
|
|
277
155
|
listStages: () => allStages,
|
|
278
156
|
listStageMutations: () => allStageMutations,
|
|
279
157
|
listStageExecutors: () => stageExecutors,
|
|
280
|
-
listExecutableValidators: () =>
|
|
281
|
-
listExecutableTaskSources: () =>
|
|
282
|
-
listExecutableCapabilities: () =>
|
|
283
|
-
listExecutablePanels: () =>
|
|
284
|
-
listExecutableBlockerClassifiers: () =>
|
|
285
|
-
listExecutableCliCommands: () =>
|
|
158
|
+
listExecutableValidators: () => allValidators.filter((v) => typeof v.run === "function"),
|
|
159
|
+
listExecutableTaskSources: () => allTaskSources,
|
|
160
|
+
listExecutableCapabilities: () => allCapabilities.filter((c) => typeof c.run === "function"),
|
|
161
|
+
listExecutablePanels: () => allPanels.filter((p) => typeof p.produce === "function"),
|
|
162
|
+
listExecutableBlockerClassifiers: () => allBlockerClassifiers,
|
|
163
|
+
listExecutableCliCommands: () => allCliCommands,
|
|
164
|
+
listSessionExtensions: () => allSessionExtensions,
|
|
286
165
|
resolveExecutableCliCommand: (requested) => executableCliCommandByName.get(requested)?.item,
|
|
287
166
|
resolveTaskSourceFactoryByKind: (kind) => taskSourceFactoryByKind.get(kind)
|
|
288
167
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockerClassifierRegistration, CliCommandRegistration, HookImplementation, PanelRegistration, ProductCapabilityRegistration, RegisteredTaskSource, RigConfig,
|
|
1
|
+
import type { AgentRoleRegistration, BlockerClassifierRegistration, CapabilityReplacementSpec, CapabilityTag, CliCommandRegistration, HookImplementation, HookRegistration, PanelRegistration, ProductCapabilityRegistration, RegisteredTaskSource, RepoSourceRegistration, RigConfig, SessionExtensionRegistration, SkillRegistration, Stage, StageMutation, StageRun, TaskFieldExtension, TaskSourceConfig, TaskSourceRegistration, ValidatorRegistration } from "@rig/contracts";
|
|
2
2
|
export interface ValidatorResult {
|
|
3
3
|
id: string;
|
|
4
4
|
passed: boolean;
|
|
@@ -13,7 +13,7 @@ export interface ValidatorContext {
|
|
|
13
13
|
artifactsDir?: string;
|
|
14
14
|
taskConfig?: unknown;
|
|
15
15
|
}
|
|
16
|
-
export interface
|
|
16
|
+
export interface Validator extends ValidatorRegistration {
|
|
17
17
|
run(ctx: ValidatorContext): Promise<ValidatorResult>;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
@@ -33,71 +33,102 @@ export interface TaskSourceFactoryContext {
|
|
|
33
33
|
rigConfig?: RigConfig;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `kind` is matched against `config.taskSource.kind` at boot. The first
|
|
41
|
-
* matching plugin factory wins; if multiple plugins claim the same kind,
|
|
42
|
-
* `createPluginHost` throws a duplicate-kind error.
|
|
36
|
+
* Task-source contribution: metadata (`id`, `kind`) plus the `factory` that
|
|
37
|
+
* turns a TaskSourceConfig into a RegisteredTaskSource. `kind` is matched
|
|
38
|
+
* against `config.taskSource.kind` at boot; duplicate kinds throw in
|
|
39
|
+
* `createPluginHost`.
|
|
43
40
|
*/
|
|
44
|
-
export interface
|
|
41
|
+
export interface TaskSource extends TaskSourceRegistration {
|
|
45
42
|
factory(config: TaskSourceConfig, context?: TaskSourceFactoryContext): RegisteredTaskSource;
|
|
46
43
|
}
|
|
47
|
-
export interface
|
|
44
|
+
export interface FeatureCapability extends ProductCapabilityRegistration {
|
|
48
45
|
run?: (input: unknown) => Promise<unknown> | unknown;
|
|
49
46
|
}
|
|
50
|
-
|
|
47
|
+
/** @deprecated single-channel rename — use {@link FeatureCapability}. */
|
|
48
|
+
export type RuntimeFeatureCapability = FeatureCapability;
|
|
49
|
+
export interface Panel extends PanelRegistration {
|
|
51
50
|
produce?: (context?: unknown) => Promise<unknown> | unknown;
|
|
52
51
|
}
|
|
53
|
-
export interface
|
|
52
|
+
export interface BlockerClassifierEntry extends BlockerClassifierRegistration {
|
|
54
53
|
classify(input: unknown): Promise<unknown> | unknown;
|
|
55
54
|
}
|
|
55
|
+
/** @deprecated single-channel rename — use {@link BlockerClassifierEntry}. */
|
|
56
|
+
export type RuntimeBlockerClassifier = BlockerClassifierEntry;
|
|
56
57
|
export interface RuntimeCliContext {
|
|
57
58
|
projectRoot: string;
|
|
58
59
|
outputMode?: string;
|
|
59
60
|
dryRun?: boolean;
|
|
60
61
|
}
|
|
61
|
-
export interface
|
|
62
|
+
export interface CliCommand extends CliCommandRegistration {
|
|
62
63
|
run(context: RuntimeCliContext, args: readonly string[]): Promise<unknown> | unknown;
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Hook contribution: metadata plus an optional typed `handler`. A hook is
|
|
67
|
+
* implemented either by a typed `handler` or by a raw `command` string in its
|
|
68
|
+
* metadata — never both. The runtime's hook-materializer generates the shim
|
|
69
|
+
* command that routes Claude Code's hook invocation to the typed function.
|
|
70
|
+
*/
|
|
71
|
+
export interface Hook extends HookRegistration {
|
|
72
|
+
handler?: HookImplementation;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Stage contribution: the stage descriptor plus its executor. When a plugin
|
|
76
|
+
* inserts/replaces a stage (via a matching `stageMutations` entry), its
|
|
77
|
+
* `run(ctx)` lives here so the kernel's stage runner can execute it.
|
|
78
|
+
*/
|
|
79
|
+
export interface StageEntry extends Stage {
|
|
80
|
+
run?: StageRun;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Executable installer for a contributed session extension. The `api` argument
|
|
84
|
+
* is the agent-session extension API (the OMP/Pi `ExtensionAPI`), kept as `any`
|
|
85
|
+
* here on purpose: typing it against the OMP runtime would couple the
|
|
86
|
+
* substrate-agnostic plugin model to the OMP substrate (architecture reference
|
|
87
|
+
* §12). The plugin author (run-worker) and the consumer (rig-host) hold the
|
|
88
|
+
* concrete `ExtensionAPI` type; the plugin host only sees an opaque installer.
|
|
89
|
+
*/
|
|
90
|
+
export type SessionExtensionInstall = (api: any) => void | Promise<void>;
|
|
91
|
+
export interface SessionExtensionEntry extends SessionExtensionRegistration {
|
|
92
|
+
install: SessionExtensionInstall;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Single-channel contributions. Fn-bearing kinds carry their executable fn on
|
|
96
|
+
* the same entry as their metadata; metadata-only kinds (skills, repoSources,
|
|
97
|
+
* agentRoles, taskFieldSchemas, stageMutations) are pure registrations.
|
|
98
|
+
*/
|
|
99
|
+
export interface PluginContributes {
|
|
100
|
+
validators?: readonly Validator[];
|
|
101
|
+
hooks?: readonly Hook[];
|
|
102
|
+
skills?: readonly SkillRegistration[];
|
|
103
|
+
repoSources?: readonly RepoSourceRegistration[];
|
|
104
|
+
agentRoles?: readonly AgentRoleRegistration[];
|
|
105
|
+
taskFieldSchemas?: readonly TaskFieldExtension[];
|
|
106
|
+
taskSources?: readonly TaskSource[];
|
|
107
|
+
cliCommands?: readonly CliCommand[];
|
|
108
|
+
stages?: readonly StageEntry[];
|
|
109
|
+
stageMutations?: readonly StageMutation[];
|
|
110
|
+
capabilities?: readonly FeatureCapability[];
|
|
111
|
+
panels?: readonly Panel[];
|
|
112
|
+
blockerClassifiers?: readonly BlockerClassifierEntry[];
|
|
113
|
+
sessionExtensions?: readonly SessionExtensionEntry[];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The authored plugin object. Validated against the `RigPlugin` metadata schema
|
|
117
|
+
* in @rig/contracts; the executable fns on `contributes` entries and the kernel
|
|
118
|
+
* `capabilityProviders` ride alongside and are ignored by Schema decode.
|
|
119
|
+
*/
|
|
120
|
+
export interface RigPlugin {
|
|
121
|
+
name: string;
|
|
122
|
+
version: string;
|
|
123
|
+
provides?: readonly CapabilityTag[];
|
|
124
|
+
requires?: readonly CapabilityTag[];
|
|
125
|
+
replaces?: readonly CapabilityReplacementSpec[];
|
|
126
|
+
contributes?: PluginContributes;
|
|
95
127
|
/**
|
|
96
|
-
*
|
|
97
|
-
* (`transport`, `journal`,
|
|
98
|
-
*
|
|
99
|
-
*
|
|
128
|
+
* Kernel capability implementations keyed by the tag named in `provides`
|
|
129
|
+
* (`transport`, `journal`, `stage-runner`, `loader-policy`, `kernel`). This
|
|
130
|
+
* is the single home for what the old kernel `LoadedPlugin.runtime.capabilities`
|
|
131
|
+
* / `runtime.kernel` carried — kernel-seed resolves capabilities from here.
|
|
100
132
|
*/
|
|
101
|
-
|
|
133
|
+
capabilityProviders?: Partial<Record<CapabilityTag, unknown>>;
|
|
102
134
|
}
|
|
103
|
-
export type RigPluginWithRuntime = RigPlugin & RigPluginRuntime;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { RigConfig } from "@rig/contracts";
|
|
2
|
+
import { type PluginHost } from "./plugin-host";
|
|
3
|
+
import type { RigPlugin } from "./plugin-runtime";
|
|
4
|
+
export type ProjectPluginResolutionMode = "strict-config-only";
|
|
5
|
+
export type ProjectConfigPresence = {
|
|
6
|
+
readonly status: "loaded";
|
|
7
|
+
readonly path: string | null;
|
|
8
|
+
} | {
|
|
9
|
+
readonly status: "missing";
|
|
10
|
+
readonly path: null;
|
|
11
|
+
};
|
|
12
|
+
export type ProjectPluginResolutionWarningCode = never;
|
|
13
|
+
export type ProjectPluginResolutionWarning = {
|
|
14
|
+
readonly code: ProjectPluginResolutionWarningCode;
|
|
15
|
+
readonly level: "warning" | "info";
|
|
16
|
+
readonly message: string;
|
|
17
|
+
};
|
|
18
|
+
export type ProjectPluginResolution = {
|
|
19
|
+
readonly mode: ProjectPluginResolutionMode;
|
|
20
|
+
readonly projectRoot: string;
|
|
21
|
+
readonly surfaceName: string;
|
|
22
|
+
readonly configPresence: ProjectConfigPresence;
|
|
23
|
+
readonly config: RigConfig | null;
|
|
24
|
+
readonly warnings: readonly ProjectPluginResolutionWarning[];
|
|
25
|
+
readonly plugins: readonly RigPlugin[];
|
|
26
|
+
};
|
|
27
|
+
export type ProjectPluginHostResult = {
|
|
28
|
+
readonly host: PluginHost;
|
|
29
|
+
readonly resolved: ProjectPluginResolution;
|
|
30
|
+
};
|
|
31
|
+
export type LoadProjectConfig = (projectRoot: string) => Promise<RigConfig>;
|
|
32
|
+
export type LoadProjectPluginSetOptions = {
|
|
33
|
+
readonly mode?: ProjectPluginResolutionMode;
|
|
34
|
+
readonly surfaceName?: string;
|
|
35
|
+
readonly load?: LoadProjectConfig;
|
|
36
|
+
};
|
|
37
|
+
export type ProjectPluginResolutionOptions = Omit<LoadProjectPluginSetOptions, "mode" | "surfaceName"> & {
|
|
38
|
+
readonly projectRoot: string;
|
|
39
|
+
readonly mode: ProjectPluginResolutionMode;
|
|
40
|
+
readonly surfaceName: string;
|
|
41
|
+
};
|
|
42
|
+
export declare function projectPluginResolutionWarningMessages(resolved: Pick<ProjectPluginResolution, "warnings">): readonly string[];
|
|
43
|
+
export declare function loadProjectPluginSet(options: ProjectPluginResolutionOptions): Promise<ProjectPluginResolution>;
|
|
44
|
+
export declare function loadProjectPluginSet(projectRoot: string, options?: LoadProjectPluginSetOptions): Promise<ProjectPluginResolution>;
|
|
45
|
+
export type ResolvedPluginHost = {
|
|
46
|
+
readonly host: PluginHost;
|
|
47
|
+
readonly config: RigConfig;
|
|
48
|
+
};
|
|
49
|
+
export type ResolvePluginHostOptions = {
|
|
50
|
+
readonly load?: LoadProjectConfig;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The single cached plugin-host resolver. Returns the resolved host plus the
|
|
54
|
+
* loaded config for a project root, memoized per normalized root and validated
|
|
55
|
+
* by the rig.config file mtime — an edited config rebuilds the host (preserving
|
|
56
|
+
* loadConfig's mtime-cache semantics) while every other consumer in the same
|
|
57
|
+
* generation shares one resolved host.
|
|
58
|
+
*
|
|
59
|
+
* It propagates loadConfig's throw on a missing/broken config; each consumer
|
|
60
|
+
* keeps its own try/catch so per-call-site degradation (graceful-null vs
|
|
61
|
+
* surfaced error) is unchanged. A custom `load` bypasses the shared cache so it
|
|
62
|
+
* cannot poison the canonical on-disk host other consumers read.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolvePluginHost(projectRoot: string, options?: ResolvePluginHostOptions): Promise<ResolvedPluginHost>;
|
|
65
|
+
export declare function createProjectPluginHost(options: ProjectPluginResolutionOptions): Promise<ProjectPluginHostResult>;
|
|
66
|
+
export declare function createProjectPluginHost(projectRoot: string, options?: LoadProjectPluginSetOptions): Promise<ProjectPluginHostResult>;
|