specsmd 0.1.22 → 0.1.23
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.
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
const ToolInstaller = require('./ToolInstaller');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const CLIUtils = require('../cli-utils');
|
|
5
|
+
const { theme } = CLIUtils;
|
|
2
6
|
|
|
3
7
|
class CodexInstaller extends ToolInstaller {
|
|
4
8
|
get key() {
|
|
@@ -10,12 +14,90 @@ class CodexInstaller extends ToolInstaller {
|
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
get commandsDir() {
|
|
13
|
-
return '.codex';
|
|
17
|
+
return path.join('.codex', 'skills');
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
get detectPath() {
|
|
17
21
|
return '.codex';
|
|
18
22
|
}
|
|
23
|
+
|
|
24
|
+
async installCommands(flowPath, config) {
|
|
25
|
+
const targetSkillsDir = this.commandsDir;
|
|
26
|
+
console.log(theme.dim(` Installing skills to ${targetSkillsDir}/...`));
|
|
27
|
+
await fs.ensureDir(targetSkillsDir);
|
|
28
|
+
|
|
29
|
+
const commandsSourceDir = path.join(flowPath, 'commands');
|
|
30
|
+
if (!await fs.pathExists(commandsSourceDir)) {
|
|
31
|
+
console.log(theme.warning(` No commands folder found at ${commandsSourceDir}`));
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const commandFiles = await fs.readdir(commandsSourceDir);
|
|
36
|
+
const installedFiles = [];
|
|
37
|
+
|
|
38
|
+
for (const cmdFile of commandFiles) {
|
|
39
|
+
if (!cmdFile.endsWith('.md')) continue;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const sourcePath = path.join(commandsSourceDir, cmdFile);
|
|
43
|
+
const content = await fs.readFile(sourcePath, 'utf8');
|
|
44
|
+
const commandName = cmdFile.replace('.md', '');
|
|
45
|
+
const prefix = (config && config.command && config.command.prefix) ? `${config.command.prefix}-` : '';
|
|
46
|
+
const skillName = `specsmd-${prefix}${commandName}`;
|
|
47
|
+
|
|
48
|
+
const { description, body } = this.parseFrontmatter(content);
|
|
49
|
+
|
|
50
|
+
// Build SKILL.md with Codex frontmatter
|
|
51
|
+
const skillContent = [
|
|
52
|
+
'---',
|
|
53
|
+
`name: ${skillName}`,
|
|
54
|
+
`description: "${description || 'specsmd agent'}"`,
|
|
55
|
+
'---',
|
|
56
|
+
'',
|
|
57
|
+
body
|
|
58
|
+
].join('\n');
|
|
59
|
+
|
|
60
|
+
// Write SKILL.md
|
|
61
|
+
const skillDir = path.join(targetSkillsDir, skillName);
|
|
62
|
+
await fs.ensureDir(skillDir);
|
|
63
|
+
await fs.writeFile(path.join(skillDir, 'SKILL.md'), skillContent, 'utf8');
|
|
64
|
+
|
|
65
|
+
// Write agents/openai.yaml
|
|
66
|
+
const agentsDir = path.join(skillDir, 'agents');
|
|
67
|
+
await fs.ensureDir(agentsDir);
|
|
68
|
+
const openaiYaml = [
|
|
69
|
+
'interface:',
|
|
70
|
+
` display_name: "specsmd ${commandName}"`,
|
|
71
|
+
` short_description: "${description || 'specsmd agent'}"`,
|
|
72
|
+
` default_prompt: "Use $${skillName} to start spec-driven development"`
|
|
73
|
+
].join('\n');
|
|
74
|
+
await fs.writeFile(path.join(agentsDir, 'openai.yaml'), openaiYaml, 'utf8');
|
|
75
|
+
|
|
76
|
+
installedFiles.push(skillName);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
console.log(theme.warning(` Failed to install ${cmdFile}: ${err.message}`));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
CLIUtils.displayStatus('', `Installed ${installedFiles.length} skills for ${this.name}`, 'success');
|
|
83
|
+
return installedFiles;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Parse YAML frontmatter from a markdown file
|
|
88
|
+
*/
|
|
89
|
+
parseFrontmatter(content) {
|
|
90
|
+
const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
91
|
+
if (!match) return { description: '', body: content };
|
|
92
|
+
|
|
93
|
+
const frontmatter = match[1];
|
|
94
|
+
const body = match[2];
|
|
95
|
+
const descMatch = frontmatter.match(/description:\s*["']?(.+?)["']?\s*$/m);
|
|
96
|
+
return {
|
|
97
|
+
description: descMatch ? descMatch[1] : '',
|
|
98
|
+
body: body.trim()
|
|
99
|
+
};
|
|
100
|
+
}
|
|
19
101
|
}
|
|
20
102
|
|
|
21
103
|
module.exports = CodexInstaller;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specsmd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
|
|
5
5
|
"main": "lib/installer.js",
|
|
6
6
|
"bin": {
|