@syntesseraai/opencode-feature-factory 0.2.15 → 0.2.16
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/index.js +28 -6
- package/dist/plugins/ff-agents-clear-plugin.d.ts +2 -0
- package/dist/plugins/ff-agents-clear-plugin.js +55 -0
- package/dist/plugins/ff-agents-current-plugin.d.ts +2 -0
- package/dist/plugins/ff-agents-current-plugin.js +49 -0
- package/dist/plugins/ff-agents-show-plugin.d.ts +2 -0
- package/dist/plugins/ff-agents-show-plugin.js +26 -0
- package/package.json +1 -1
- package/dist/agent-management-tools.d.ts +0 -5
- package/dist/agent-management-tools.js +0 -117
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createQualityGateHooks } from './stop-quality-gate.js';
|
|
2
2
|
import { initializeFeatureFactory } from './feature-factory-setup.js';
|
|
3
|
-
import {
|
|
3
|
+
import { FFAgentsCurrentPlugin } from './plugins/ff-agents-current-plugin.js';
|
|
4
|
+
import { FFAgentsClearPlugin } from './plugins/ff-agents-clear-plugin.js';
|
|
5
|
+
import { FFAgentsShowPlugin } from './plugins/ff-agents-show-plugin.js';
|
|
4
6
|
const SERVICE_NAME = 'feature-factory';
|
|
5
7
|
const PLUGIN_INIT_TIMEOUT_MS = 10000; // 10 seconds max for plugin initialization
|
|
6
8
|
/**
|
|
@@ -103,19 +105,39 @@ export const StopQualityGatePlugin = async (input) => {
|
|
|
103
105
|
error: String(error),
|
|
104
106
|
});
|
|
105
107
|
}
|
|
106
|
-
// Create agent management
|
|
107
|
-
let
|
|
108
|
+
// Create agent management tool plugins
|
|
109
|
+
let agentsCurrentHooks = {};
|
|
110
|
+
let agentsClearHooks = {};
|
|
111
|
+
let agentsShowHooks = {};
|
|
108
112
|
try {
|
|
109
|
-
|
|
113
|
+
agentsCurrentHooks = await FFAgentsCurrentPlugin(input);
|
|
110
114
|
}
|
|
111
115
|
catch (error) {
|
|
112
|
-
await log(client, 'error', '
|
|
116
|
+
await log(client, 'error', 'ff-agents-current.init-error', {
|
|
117
|
+
error: String(error),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
agentsClearHooks = await FFAgentsClearPlugin(input);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
await log(client, 'error', 'ff-agents-clear.init-error', {
|
|
125
|
+
error: String(error),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
agentsShowHooks = await FFAgentsShowPlugin(input);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
await log(client, 'error', 'ff-agents-show.init-error', {
|
|
113
133
|
error: String(error),
|
|
114
134
|
});
|
|
115
135
|
}
|
|
116
136
|
return {
|
|
117
137
|
...qualityGateHooks,
|
|
118
|
-
...
|
|
138
|
+
...agentsCurrentHooks,
|
|
139
|
+
...agentsClearHooks,
|
|
140
|
+
...agentsShowHooks,
|
|
119
141
|
};
|
|
120
142
|
};
|
|
121
143
|
// Default export for OpenCode plugin discovery
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin/tool';
|
|
2
|
+
import { findAgentFiles, findAgentFilesById, findAllAgentFiles } from '../agent-context.js';
|
|
3
|
+
export const FFAgentsClearPlugin = async (input) => {
|
|
4
|
+
const { $ } = input;
|
|
5
|
+
return {
|
|
6
|
+
tool: {
|
|
7
|
+
'ff-agents-clear': tool({
|
|
8
|
+
description: 'Clear agent context files. Can clear all, or filter by session, agent type, or specific UUID',
|
|
9
|
+
args: {
|
|
10
|
+
sessionID: tool.schema
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Clear only agents for specific session'),
|
|
14
|
+
agent: tool.schema.string().optional().describe('Clear only specific agent type'),
|
|
15
|
+
id: tool.schema.string().optional().describe('Clear specific agent by UUID'),
|
|
16
|
+
},
|
|
17
|
+
async execute(args) {
|
|
18
|
+
try {
|
|
19
|
+
let files = [];
|
|
20
|
+
if (args.id) {
|
|
21
|
+
files = await findAgentFilesById(input, args.id);
|
|
22
|
+
}
|
|
23
|
+
else if (args.agent && args.sessionID) {
|
|
24
|
+
files = await findAgentFiles(input, args.agent, args.sessionID);
|
|
25
|
+
}
|
|
26
|
+
else if (args.sessionID) {
|
|
27
|
+
files = await findAgentFiles(input, undefined, args.sessionID);
|
|
28
|
+
}
|
|
29
|
+
else if (args.agent) {
|
|
30
|
+
files = await findAgentFiles(input, args.agent);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
files = await findAllAgentFiles(input);
|
|
34
|
+
}
|
|
35
|
+
if (files.length === 0) {
|
|
36
|
+
return 'No agent context files found to clear.';
|
|
37
|
+
}
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
try {
|
|
40
|
+
await $ `rm ${file}`.quiet();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Continue even if one file fails
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return `Cleared ${files.length} agent context file(s)`;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return `Error clearing agents: ${error}`;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin/tool';
|
|
2
|
+
import { listActiveAgents } from '../agent-context.js';
|
|
3
|
+
export const FFAgentsCurrentPlugin = async (input) => {
|
|
4
|
+
return {
|
|
5
|
+
tool: {
|
|
6
|
+
'ff-agents-current': tool({
|
|
7
|
+
description: 'List all currently active Feature Factory agents with their UUIDs and status',
|
|
8
|
+
args: {
|
|
9
|
+
sessionID: tool.schema.string().optional().describe('Filter by specific session ID'),
|
|
10
|
+
agent: tool.schema
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Filter by agent type (e.g., planning, research)'),
|
|
14
|
+
},
|
|
15
|
+
async execute(args) {
|
|
16
|
+
try {
|
|
17
|
+
const agents = await listActiveAgents(input, args.sessionID, args.agent);
|
|
18
|
+
if (agents.length === 0) {
|
|
19
|
+
return JSON.stringify({
|
|
20
|
+
count: 0,
|
|
21
|
+
message: 'No active agents found',
|
|
22
|
+
agents: [],
|
|
23
|
+
}, null, 2);
|
|
24
|
+
}
|
|
25
|
+
return JSON.stringify({
|
|
26
|
+
count: agents.length,
|
|
27
|
+
agents: agents.map((a) => ({
|
|
28
|
+
id: a.id,
|
|
29
|
+
agent: a.agent,
|
|
30
|
+
title: a.title,
|
|
31
|
+
folder: a.folder,
|
|
32
|
+
status: a.status,
|
|
33
|
+
started: a.started,
|
|
34
|
+
session: a.session,
|
|
35
|
+
parent: a.parent || null,
|
|
36
|
+
delegated_to: a.delegated_to || [],
|
|
37
|
+
})),
|
|
38
|
+
}, null, 2);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return JSON.stringify({
|
|
42
|
+
error: `Failed to list agents: ${error}`,
|
|
43
|
+
}, null, 2);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { tool } from '@opencode-ai/plugin/tool';
|
|
2
|
+
import { readAgentContextById } from '../agent-context.js';
|
|
3
|
+
export const FFAgentsShowPlugin = async (input) => {
|
|
4
|
+
return {
|
|
5
|
+
tool: {
|
|
6
|
+
'ff-agents-show': tool({
|
|
7
|
+
description: 'Show detailed context for a specific agent by UUID',
|
|
8
|
+
args: {
|
|
9
|
+
id: tool.schema.string().describe('Agent UUID to show details for'),
|
|
10
|
+
},
|
|
11
|
+
async execute(args) {
|
|
12
|
+
try {
|
|
13
|
+
const agentContext = await readAgentContextById(input, args.id);
|
|
14
|
+
if (!agentContext) {
|
|
15
|
+
return `Agent with ID "${args.id}" not found`;
|
|
16
|
+
}
|
|
17
|
+
return JSON.stringify(agentContext, null, 2);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return `Error reading agent: ${error}`;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@syntesseraai/opencode-feature-factory",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.16",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "OpenCode plugin for Feature Factory agents - provides sub-agents and skills for validation, review, security, and architecture assessment",
|
|
7
7
|
"license": "MIT",
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { tool } from '@opencode-ai/plugin/tool';
|
|
2
|
-
import { listActiveAgents, findAgentFiles, findAgentFilesById, findAllAgentFiles, readAgentContextById, } from './agent-context.js';
|
|
3
|
-
/**
|
|
4
|
-
* Create agent management tools for the plugin
|
|
5
|
-
*/
|
|
6
|
-
export function createAgentManagementTools(input) {
|
|
7
|
-
const { $ } = input;
|
|
8
|
-
return {
|
|
9
|
-
tool: {
|
|
10
|
-
'ff-agents-current': tool({
|
|
11
|
-
description: 'List all currently active Feature Factory agents with their UUIDs and status',
|
|
12
|
-
args: {
|
|
13
|
-
sessionID: tool.schema.string().optional().describe('Filter by specific session ID'),
|
|
14
|
-
agent: tool.schema
|
|
15
|
-
.string()
|
|
16
|
-
.optional()
|
|
17
|
-
.describe('Filter by agent type (e.g., planning, research)'),
|
|
18
|
-
},
|
|
19
|
-
execute: async (args) => {
|
|
20
|
-
try {
|
|
21
|
-
const agents = await listActiveAgents(input, args.sessionID, args.agent);
|
|
22
|
-
if (agents.length === 0) {
|
|
23
|
-
return JSON.stringify({
|
|
24
|
-
count: 0,
|
|
25
|
-
message: 'No active agents found',
|
|
26
|
-
agents: [],
|
|
27
|
-
}, null, 2);
|
|
28
|
-
}
|
|
29
|
-
return JSON.stringify({
|
|
30
|
-
count: agents.length,
|
|
31
|
-
agents: agents.map((a) => ({
|
|
32
|
-
id: a.id,
|
|
33
|
-
agent: a.agent,
|
|
34
|
-
title: a.title,
|
|
35
|
-
folder: a.folder,
|
|
36
|
-
status: a.status,
|
|
37
|
-
started: a.started,
|
|
38
|
-
session: a.session,
|
|
39
|
-
parent: a.parent || null,
|
|
40
|
-
delegated_to: a.delegated_to || [],
|
|
41
|
-
})),
|
|
42
|
-
}, null, 2);
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
return JSON.stringify({
|
|
46
|
-
error: `Failed to list agents: ${error}`,
|
|
47
|
-
}, null, 2);
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
}),
|
|
51
|
-
'ff-agents-clear': tool({
|
|
52
|
-
description: 'Clear agent context files. Can clear all, or filter by session, agent type, or specific UUID',
|
|
53
|
-
args: {
|
|
54
|
-
sessionID: tool.schema
|
|
55
|
-
.string()
|
|
56
|
-
.optional()
|
|
57
|
-
.describe('Clear only agents for specific session'),
|
|
58
|
-
agent: tool.schema.string().optional().describe('Clear only specific agent type'),
|
|
59
|
-
id: tool.schema.string().optional().describe('Clear specific agent by UUID'),
|
|
60
|
-
},
|
|
61
|
-
execute: async (args) => {
|
|
62
|
-
try {
|
|
63
|
-
let files = [];
|
|
64
|
-
if (args.id) {
|
|
65
|
-
files = await findAgentFilesById(input, args.id);
|
|
66
|
-
}
|
|
67
|
-
else if (args.agent && args.sessionID) {
|
|
68
|
-
files = await findAgentFiles(input, args.agent, args.sessionID);
|
|
69
|
-
}
|
|
70
|
-
else if (args.sessionID) {
|
|
71
|
-
files = await findAgentFiles(input, undefined, args.sessionID);
|
|
72
|
-
}
|
|
73
|
-
else if (args.agent) {
|
|
74
|
-
files = await findAgentFiles(input, args.agent);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
files = await findAllAgentFiles(input);
|
|
78
|
-
}
|
|
79
|
-
if (files.length === 0) {
|
|
80
|
-
return 'No agent context files found to clear.';
|
|
81
|
-
}
|
|
82
|
-
for (const file of files) {
|
|
83
|
-
try {
|
|
84
|
-
await $ `rm ${file}`.quiet();
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// Continue even if one file fails
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return `Cleared ${files.length} agent context file(s)`;
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
return `Error clearing agents: ${error}`;
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
}),
|
|
97
|
-
'ff-agents-show': tool({
|
|
98
|
-
description: 'Show detailed context for a specific agent by UUID',
|
|
99
|
-
args: {
|
|
100
|
-
id: tool.schema.string().describe('Agent UUID to show details for'),
|
|
101
|
-
},
|
|
102
|
-
execute: async (args) => {
|
|
103
|
-
try {
|
|
104
|
-
const agentContext = await readAgentContextById(input, args.id);
|
|
105
|
-
if (!agentContext) {
|
|
106
|
-
return `Agent with ID "${args.id}" not found`;
|
|
107
|
-
}
|
|
108
|
-
return JSON.stringify(agentContext, null, 2);
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
return `Error reading agent: ${error}`;
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
}),
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|