solmate-skills 2.0.12 → 2.0.14
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/AGENTS.md +11 -2
- package/CLAUDE.md +13 -3
- package/README.md +104 -6
- package/USAGE.md +137 -14
- package/bin/cli.js +169 -1
- package/bin/harness-artifact.js +621 -0
- package/bin/harness-artifact.test.js +520 -0
- package/bin/harness-check.js +373 -0
- package/bin/harness-check.test.js +168 -0
- package/bin/test.js +2 -0
- package/docs/01_Concept_Design/01_AGENT_HARNESS_REQUIREMENTS_ANALYSIS.md +164 -0
- package/docs/03_Technical_Specs/01_AGENT_HARNESS_ARCHITECTURE.md +378 -0
- package/docs/03_Technical_Specs/assets/01_agent_harness_data_flow.svg +94 -0
- package/docs/04_Logic_Progress/00_BACKLOG.md +339 -0
- package/docs/04_Logic_Progress/01_EXECUTION_PLAN.md +160 -0
- package/docs/04_Logic_Progress/03_DECISION_LOG.md +98 -0
- package/docs/05_QA_Validation/01_TEST_SCENARIOS.md +322 -0
- package/docs/05_QA_Validation/02_AGENT_HARNESS_DESIGN_REVIEW.md +100 -0
- package/docs/05_QA_Validation/03_AGENT_HARNESS_CONTRACT_QA.md +96 -0
- package/manage-collaboration/SKILL.md +2 -0
- package/package.json +6 -4
- package/rules-docs/SKILL.md +15 -1
- package/rules-product/SKILL.md +32 -8
- package/rules-product/agents/openai.yaml +2 -2
- package/rules-workflow/SKILL.md +34 -8
- package/rules-workflow/adapters/claude/solmate-context-reader.md +20 -0
- package/rules-workflow/adapters/claude/solmate-implementer.md +20 -0
- package/rules-workflow/adapters/claude/solmate-verifier.md +21 -0
- package/rules-workflow/agents/openai.yaml +2 -2
- package/rules-workflow/resources/agent-harness-contract.md +191 -0
- package/rules-workflow/resources/agent-harness-v1.schema.json +432 -0
- package/verify-docs/SKILL.md +33 -6
- package/verify-docs/agents/openai.yaml +2 -2
- package/verify-implementation/SKILL.md +17 -5
- package/verify-implementation/agents/openai.yaml +2 -2
- package/verify-skills/SKILL.md +29 -0
package/bin/cli.js
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { execSync } = require('child_process');
|
|
6
|
+
const {
|
|
7
|
+
checkHarnessTask,
|
|
8
|
+
formatHarnessResult,
|
|
9
|
+
getHarnessExitCode,
|
|
10
|
+
} = require('./harness-check');
|
|
11
|
+
const {
|
|
12
|
+
checkHarnessArtifact,
|
|
13
|
+
formatHarnessArtifactResult,
|
|
14
|
+
getHarnessArtifactExitCode,
|
|
15
|
+
} = require('./harness-artifact');
|
|
6
16
|
|
|
7
17
|
const IGNORED_FOLDERS = ['bin', 'node_modules', '.git', '.github', '.gemini', '.agent'];
|
|
8
18
|
const IGNORED_FILES = ['package.json', 'package-lock.json', 'AGENTS.md', 'SKILL.md', 'init-skills.sh', 'README.md', '.DS_Store', 'old_AGENTS.md'];
|
|
@@ -19,6 +29,8 @@ const POST_INSTALL_SCRIPTS = {
|
|
|
19
29
|
const packageRoot = path.join(__dirname, '..');
|
|
20
30
|
const targetProjectRoot = process.cwd();
|
|
21
31
|
const targetSkillsDir = path.join(targetProjectRoot, '.agent', 'skills');
|
|
32
|
+
const claudeAgentSourceDir = path.join(packageRoot, 'rules-workflow', 'adapters', 'claude');
|
|
33
|
+
const targetClaudeAgentsDir = path.join(targetProjectRoot, '.claude', 'agents');
|
|
22
34
|
|
|
23
35
|
function getAvailableSkills() {
|
|
24
36
|
return fs.readdirSync(packageRoot, { withFileTypes: true })
|
|
@@ -61,13 +73,38 @@ function copyFolderSync(from, to) {
|
|
|
61
73
|
});
|
|
62
74
|
}
|
|
63
75
|
|
|
76
|
+
function installAgentAdapters() {
|
|
77
|
+
if (!fs.existsSync(claudeAgentSourceDir)) {
|
|
78
|
+
console.error('Error: Claude agent adapters not found in rules-workflow.');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
fs.mkdirSync(targetClaudeAgentsDir, { recursive: true });
|
|
83
|
+
const agentFiles = fs.readdirSync(claudeAgentSourceDir)
|
|
84
|
+
.filter(fileName => fileName.startsWith('solmate-') && fileName.endsWith('.md'));
|
|
85
|
+
|
|
86
|
+
for (const fileName of agentFiles) {
|
|
87
|
+
fs.copyFileSync(
|
|
88
|
+
path.join(claudeAgentSourceDir, fileName),
|
|
89
|
+
path.join(targetClaudeAgentsDir, fileName),
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log(`Installed ${agentFiles.length} Claude agent adapters to .claude/agents`);
|
|
94
|
+
console.log('Codex uses the same contract through rules-workflow; linked AGENTS.md reinforces it globally.');
|
|
95
|
+
}
|
|
96
|
+
|
|
64
97
|
function listSkills() {
|
|
65
98
|
const skills = getAvailableSkills();
|
|
66
99
|
console.log('\nAvailable skills to install:');
|
|
67
100
|
skills.forEach(skill => console.log(` - ${skill}`));
|
|
68
101
|
console.log('\nUtilities:');
|
|
69
102
|
console.log(' - hooks (install with: npx solmate-skills install hooks)');
|
|
70
|
-
console.log('
|
|
103
|
+
console.log(' - agents (install with: npx solmate-skills install agents)');
|
|
104
|
+
console.log('\nWorkflow verification:');
|
|
105
|
+
console.log(' - Feature work is verified automatically by rules-workflow and verify-implementation.');
|
|
106
|
+
console.log(' - Advanced runtime and CI contracts: see USAGE.md and agent-harness-contract.md.');
|
|
107
|
+
console.log('\nUsage: npx solmate-skills install <skill-name> | all | hooks | agents\n');
|
|
71
108
|
}
|
|
72
109
|
|
|
73
110
|
function installHooks() {
|
|
@@ -123,6 +160,10 @@ function installSkill(skillName, options = {}) {
|
|
|
123
160
|
copyFolderSync(sourcePath, destPath);
|
|
124
161
|
console.log(`Successfully installed ${skillName} to .agent/skills/${skillName}`);
|
|
125
162
|
|
|
163
|
+
if (skillName === 'rules-workflow') {
|
|
164
|
+
installAgentAdapters();
|
|
165
|
+
}
|
|
166
|
+
|
|
126
167
|
// Run post-install script if defined for this skill
|
|
127
168
|
if (POST_INSTALL_SCRIPTS[skillName]) {
|
|
128
169
|
const scriptPath = path.join(destPath, POST_INSTALL_SCRIPTS[skillName]);
|
|
@@ -141,6 +182,120 @@ function installSkill(skillName, options = {}) {
|
|
|
141
182
|
}
|
|
142
183
|
}
|
|
143
184
|
|
|
185
|
+
function installHarnessAgents() {
|
|
186
|
+
installSkill('rules-workflow');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function parseHarnessOptions(rawArgs) {
|
|
190
|
+
const options = { mode: 'warning' };
|
|
191
|
+
|
|
192
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
193
|
+
const arg = rawArgs[index];
|
|
194
|
+
if (arg === '--strict') {
|
|
195
|
+
options.mode = 'blocking';
|
|
196
|
+
} else if (arg === '--mode') {
|
|
197
|
+
if (!rawArgs[index + 1]) {
|
|
198
|
+
throw new Error('--mode requires warning or blocking.');
|
|
199
|
+
}
|
|
200
|
+
options.mode = rawArgs[index + 1];
|
|
201
|
+
index += 1;
|
|
202
|
+
} else if (arg === '--backlog') {
|
|
203
|
+
if (!rawArgs[index + 1]) {
|
|
204
|
+
throw new Error('--backlog requires a file path.');
|
|
205
|
+
}
|
|
206
|
+
options.backlogPath = rawArgs[index + 1];
|
|
207
|
+
index += 1;
|
|
208
|
+
} else if (arg === '--json') {
|
|
209
|
+
options.json = true;
|
|
210
|
+
} else {
|
|
211
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return options;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function runHarnessCommand(stage, taskId, rawArgs) {
|
|
219
|
+
let options;
|
|
220
|
+
try {
|
|
221
|
+
options = parseHarnessOptions(rawArgs);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.error(`Error: ${error.message}`);
|
|
224
|
+
process.exitCode = 2;
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const result = checkHarnessTask({
|
|
229
|
+
stage,
|
|
230
|
+
taskId,
|
|
231
|
+
mode: options.mode,
|
|
232
|
+
backlogPath: options.backlogPath,
|
|
233
|
+
cwd: targetProjectRoot,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
if (options.json) {
|
|
237
|
+
console.log(JSON.stringify(result, null, 2));
|
|
238
|
+
} else {
|
|
239
|
+
console.log(formatHarnessResult(result));
|
|
240
|
+
}
|
|
241
|
+
process.exitCode = getHarnessExitCode(result);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function parseHarnessArtifactOptions(rawArgs) {
|
|
245
|
+
const options = { mode: 'warning' };
|
|
246
|
+
|
|
247
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
248
|
+
const arg = rawArgs[index];
|
|
249
|
+
if (arg === '--strict') {
|
|
250
|
+
options.mode = 'blocking';
|
|
251
|
+
} else if (arg === '--mode') {
|
|
252
|
+
if (!rawArgs[index + 1]) {
|
|
253
|
+
throw new Error('--mode requires warning or blocking.');
|
|
254
|
+
}
|
|
255
|
+
options.mode = rawArgs[index + 1];
|
|
256
|
+
index += 1;
|
|
257
|
+
} else if (arg === '--manifest') {
|
|
258
|
+
if (!rawArgs[index + 1]) {
|
|
259
|
+
throw new Error('--manifest requires a file path.');
|
|
260
|
+
}
|
|
261
|
+
options.manifestPath = rawArgs[index + 1];
|
|
262
|
+
index += 1;
|
|
263
|
+
} else if (arg === '--json') {
|
|
264
|
+
options.json = true;
|
|
265
|
+
} else {
|
|
266
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return options;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function runHarnessArtifactCommand(artifactType, filePath, rawArgs) {
|
|
274
|
+
let options;
|
|
275
|
+
try {
|
|
276
|
+
options = parseHarnessArtifactOptions(rawArgs);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
console.error(`Error: ${error.message}`);
|
|
279
|
+
process.exitCode = 2;
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const result = checkHarnessArtifact({
|
|
284
|
+
artifactType,
|
|
285
|
+
filePath,
|
|
286
|
+
mode: options.mode,
|
|
287
|
+
manifestPath: options.manifestPath,
|
|
288
|
+
cwd: targetProjectRoot,
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
if (options.json) {
|
|
292
|
+
console.log(JSON.stringify(result, null, 2));
|
|
293
|
+
} else {
|
|
294
|
+
console.log(formatHarnessArtifactResult(result));
|
|
295
|
+
}
|
|
296
|
+
process.exitCode = getHarnessArtifactExitCode(result);
|
|
297
|
+
}
|
|
298
|
+
|
|
144
299
|
const args = process.argv.slice(2);
|
|
145
300
|
const command = args[0];
|
|
146
301
|
const subCommand = args[1];
|
|
@@ -157,6 +312,8 @@ if (!command || command === 'list') {
|
|
|
157
312
|
installSkill('install-all');
|
|
158
313
|
} else if (subCommand === 'hooks' || subCommand === 'install-hooks') {
|
|
159
314
|
installHooks();
|
|
315
|
+
} else if (subCommand === 'agents' || subCommand === 'install-agents') {
|
|
316
|
+
installHarnessAgents();
|
|
160
317
|
} else {
|
|
161
318
|
installSkill(subCommand);
|
|
162
319
|
}
|
|
@@ -164,6 +321,17 @@ if (!command || command === 'list') {
|
|
|
164
321
|
installSkill('install-all');
|
|
165
322
|
} else if (command === 'install-hooks' || command === 'hooks') {
|
|
166
323
|
installHooks();
|
|
324
|
+
} else if (command === 'install-agents' || command === 'agents') {
|
|
325
|
+
installHarnessAgents();
|
|
326
|
+
} else if (command === 'preflight' || command === 'verify') {
|
|
327
|
+
if (!subCommand) {
|
|
328
|
+
console.error(`Error: ${command} requires a backlog task ID.`);
|
|
329
|
+
process.exitCode = 2;
|
|
330
|
+
} else {
|
|
331
|
+
runHarnessCommand(command, subCommand, args.slice(2));
|
|
332
|
+
}
|
|
333
|
+
} else if (command === 'validate-harness') {
|
|
334
|
+
runHarnessArtifactCommand(subCommand, args[2], args.slice(3));
|
|
167
335
|
} else {
|
|
168
336
|
console.log(`Unknown command: ${command}`);
|
|
169
337
|
listSkills();
|