@ouro.bot/cli 0.1.0-alpha.43 → 0.1.0-alpha.44
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/changelog.json +6 -0
- package/dist/heart/daemon/subagent-installer.js +38 -6
- package/package.json +1 -1
- package/subagents/README.md +33 -7
package/changelog.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.44",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Workflow skills now install into `~/.agents/skills` for Codex/OpenAI instead of duplicating installs under both `.agents` and `.codex`, which prevents duplicate advertised skills while keeping re-installs safe."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.43",
|
|
6
12
|
"changes": [
|
|
@@ -64,6 +64,16 @@ function pathExists(target) {
|
|
|
64
64
|
return false;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
function isSameFile(source, target) {
|
|
68
|
+
try {
|
|
69
|
+
const sourceStats = fs.statSync(source);
|
|
70
|
+
const targetStats = fs.statSync(target);
|
|
71
|
+
return sourceStats.dev === targetStats.dev && sourceStats.ino === targetStats.ino;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
67
77
|
function ensureSymlink(source, target) {
|
|
68
78
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
69
79
|
if (pathExists(target)) {
|
|
@@ -78,6 +88,25 @@ function ensureSymlink(source, target) {
|
|
|
78
88
|
fs.symlinkSync(source, target);
|
|
79
89
|
return true;
|
|
80
90
|
}
|
|
91
|
+
function ensureHardLink(source, target) {
|
|
92
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
93
|
+
if (pathExists(target)) {
|
|
94
|
+
const stats = fs.lstatSync(target);
|
|
95
|
+
if (!stats.isSymbolicLink() && isSameFile(source, target)) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
fs.unlinkSync(target);
|
|
99
|
+
}
|
|
100
|
+
fs.linkSync(source, target);
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
function hasOpenAiSkillHome(homeDir) {
|
|
104
|
+
return pathExists(path.join(homeDir, ".codex")) || pathExists(path.join(homeDir, ".agents"));
|
|
105
|
+
}
|
|
106
|
+
function openAiSkillTargets(homeDir, source) {
|
|
107
|
+
const skillName = path.basename(source, ".md");
|
|
108
|
+
return [path.join(homeDir, ".agents", "skills", skillName, "SKILL.md")];
|
|
109
|
+
}
|
|
81
110
|
async function installSubagentsForAvailableCli(options = {}) {
|
|
82
111
|
const repoRoot = options.repoRoot ?? path.resolve(__dirname, "..", "..", "..");
|
|
83
112
|
const homeDir = options.homeDir ?? os.homedir();
|
|
@@ -111,15 +140,18 @@ async function installSubagentsForAvailableCli(options = {}) {
|
|
|
111
140
|
}
|
|
112
141
|
}
|
|
113
142
|
const codexPath = which("codex");
|
|
114
|
-
if (!codexPath) {
|
|
115
|
-
notes.push("codex CLI not found; skipping subagent install");
|
|
143
|
+
if (!codexPath && !hasOpenAiSkillHome(homeDir)) {
|
|
144
|
+
notes.push("codex CLI/config not found; skipping subagent install");
|
|
116
145
|
}
|
|
117
146
|
else {
|
|
118
|
-
const codexSkillsDir = path.join(homeDir, ".codex", "skills");
|
|
119
147
|
for (const source of sources) {
|
|
120
|
-
|
|
121
|
-
const target
|
|
122
|
-
|
|
148
|
+
let installedForSkill = false;
|
|
149
|
+
for (const target of openAiSkillTargets(homeDir, source)) {
|
|
150
|
+
if (ensureHardLink(source, target)) {
|
|
151
|
+
installedForSkill = true;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (installedForSkill) {
|
|
123
155
|
codexInstalled += 1;
|
|
124
156
|
}
|
|
125
157
|
}
|
package/package.json
CHANGED
package/subagents/README.md
CHANGED
|
@@ -36,13 +36,39 @@ cp subagents/*.md ~/.claude/agents/
|
|
|
36
36
|
## Installing For Codex-Style Skills
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
mkdir -p ~/.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
mkdir -p ~/.agents/skills/work-planner ~/.agents/skills/work-doer ~/.agents/skills/work-merger
|
|
40
|
+
|
|
41
|
+
# Hard-link to keep one source of truth
|
|
42
|
+
ln -f "$(pwd)/subagents/work-planner.md" ~/.agents/skills/work-planner/SKILL.md
|
|
43
|
+
ln -f "$(pwd)/subagents/work-doer.md" ~/.agents/skills/work-doer/SKILL.md
|
|
44
|
+
ln -f "$(pwd)/subagents/work-merger.md" ~/.agents/skills/work-merger/SKILL.md
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
**Important:** For Codex/OpenAI skill installs, use the generic `~/.agents/skills` root and use hard links (`ln`, not `ln -s`). Installing the same skill into both `~/.agents/skills` and `~/.codex/skills` can produce duplicate entries in Codex. Symlinked `SKILL.md` files may load but are not advertised reliably by Codex surfaces. Hard-links break when editors save by replacing the file (new inode). After editing any `subagents/*.md` file, re-run the `ln -f` command for that file to restore the link. You can verify with `stat -f '%i'` — both files should share the same inode.
|
|
48
|
+
|
|
49
|
+
Optional UI metadata:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mkdir -p ~/.agents/skills/work-planner/agents ~/.agents/skills/work-doer/agents ~/.agents/skills/work-merger/agents
|
|
53
|
+
cat > ~/.agents/skills/work-planner/agents/openai.yaml << 'EOF'
|
|
54
|
+
interface:
|
|
55
|
+
display_name: "Work Planner"
|
|
56
|
+
short_description: "Create and gate planning/doing task docs"
|
|
57
|
+
default_prompt: "Use $work-planner to create or update a planning doc, then stop at NEEDS_REVIEW."
|
|
58
|
+
EOF
|
|
59
|
+
cat > ~/.agents/skills/work-doer/agents/openai.yaml << 'EOF'
|
|
60
|
+
interface:
|
|
61
|
+
display_name: "Work Doer"
|
|
62
|
+
short_description: "Execute approved doing docs with strict TDD"
|
|
63
|
+
default_prompt: "Use $work-doer to execute an approved doing doc unit by unit."
|
|
64
|
+
EOF
|
|
65
|
+
cat > ~/.agents/skills/work-merger/agents/openai.yaml << 'EOF'
|
|
66
|
+
interface:
|
|
67
|
+
display_name: "Work Merger"
|
|
68
|
+
short_description: "Merge feature branch into main via PR after work-doer completes"
|
|
69
|
+
default_prompt: "Use $work-merger to merge the current feature branch into main."
|
|
70
|
+
EOF
|
|
71
|
+
```
|
|
46
72
|
|
|
47
73
|
## Keeping Local Skill Copies Fresh
|
|
48
74
|
|
|
@@ -51,8 +77,8 @@ After editing any `subagents/*.md` file, resync your local installed copies.
|
|
|
51
77
|
The repo workflow usually checks this with diffs like:
|
|
52
78
|
|
|
53
79
|
```bash
|
|
54
|
-
diff -q ~/.
|
|
55
|
-
diff -q ~/.
|
|
80
|
+
diff -q ~/.agents/skills/work-planner/SKILL.md subagents/work-planner.md
|
|
81
|
+
diff -q ~/.agents/skills/work-doer/SKILL.md subagents/work-doer.md
|
|
56
82
|
```
|
|
57
83
|
|
|
58
84
|
## Restart Behavior
|