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.
Files changed (36) hide show
  1. package/AGENTS.md +11 -2
  2. package/CLAUDE.md +13 -3
  3. package/README.md +104 -6
  4. package/USAGE.md +137 -14
  5. package/bin/cli.js +169 -1
  6. package/bin/harness-artifact.js +621 -0
  7. package/bin/harness-artifact.test.js +520 -0
  8. package/bin/harness-check.js +373 -0
  9. package/bin/harness-check.test.js +168 -0
  10. package/bin/test.js +2 -0
  11. package/docs/01_Concept_Design/01_AGENT_HARNESS_REQUIREMENTS_ANALYSIS.md +164 -0
  12. package/docs/03_Technical_Specs/01_AGENT_HARNESS_ARCHITECTURE.md +378 -0
  13. package/docs/03_Technical_Specs/assets/01_agent_harness_data_flow.svg +94 -0
  14. package/docs/04_Logic_Progress/00_BACKLOG.md +339 -0
  15. package/docs/04_Logic_Progress/01_EXECUTION_PLAN.md +160 -0
  16. package/docs/04_Logic_Progress/03_DECISION_LOG.md +98 -0
  17. package/docs/05_QA_Validation/01_TEST_SCENARIOS.md +322 -0
  18. package/docs/05_QA_Validation/02_AGENT_HARNESS_DESIGN_REVIEW.md +100 -0
  19. package/docs/05_QA_Validation/03_AGENT_HARNESS_CONTRACT_QA.md +96 -0
  20. package/manage-collaboration/SKILL.md +2 -0
  21. package/package.json +6 -4
  22. package/rules-docs/SKILL.md +15 -1
  23. package/rules-product/SKILL.md +32 -8
  24. package/rules-product/agents/openai.yaml +2 -2
  25. package/rules-workflow/SKILL.md +34 -8
  26. package/rules-workflow/adapters/claude/solmate-context-reader.md +20 -0
  27. package/rules-workflow/adapters/claude/solmate-implementer.md +20 -0
  28. package/rules-workflow/adapters/claude/solmate-verifier.md +21 -0
  29. package/rules-workflow/agents/openai.yaml +2 -2
  30. package/rules-workflow/resources/agent-harness-contract.md +191 -0
  31. package/rules-workflow/resources/agent-harness-v1.schema.json +432 -0
  32. package/verify-docs/SKILL.md +33 -6
  33. package/verify-docs/agents/openai.yaml +2 -2
  34. package/verify-implementation/SKILL.md +17 -5
  35. package/verify-implementation/agents/openai.yaml +2 -2
  36. 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('\nUsage: npx solmate-skills install <skill-name> | all | hooks\n');
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();