@christang/keel 5.77.0 → 5.79.0
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/assets/bootstrap/AGENTS.md +1 -1
- package/bin/keel.js +62 -16
- package/npm-shrinkwrap.json +194 -320
- package/package.json +1 -1
- package/plugins/keel/.claude-plugin/plugin.json +1 -1
- package/plugins/keel/.codex-plugin/plugin.json +1 -1
- package/plugins/keel/scripts/session-start.js +51 -4
- package/scripts/validate_plugin.py +175 -27
- package/src/core/context.js +4 -3
package/bin/keel.js
CHANGED
|
@@ -1277,9 +1277,34 @@ function skillRootForTarget(target) {
|
|
|
1277
1277
|
return path.join(".opencode", "skills");
|
|
1278
1278
|
}
|
|
1279
1279
|
|
|
1280
|
-
|
|
1280
|
+
// Which OpenSpec layout a Codex repository carries (#169). OpenSpec 1.6 wrote
|
|
1281
|
+
// Codex's skills under `.codex/skills` and its commands as prompts in
|
|
1282
|
+
// CODEX_HOME; 1.13, which Keel pins, writes skills under `.agents/skills` and
|
|
1283
|
+
// no command files. A repository set up under 1.6 keeps its layout, and every
|
|
1284
|
+
// other one — a fresh repository included — gets the one the pin writes.
|
|
1285
|
+
function codexOpenSpecLayout(repo) {
|
|
1286
|
+
const holdsOpenSpec = (root) => {
|
|
1287
|
+
try {
|
|
1288
|
+
return fs
|
|
1289
|
+
.readdirSync(path.join(repo, root))
|
|
1290
|
+
.some((entry) => entry.startsWith("openspec-"));
|
|
1291
|
+
} catch {
|
|
1292
|
+
return false;
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
return holdsOpenSpec(path.join(".codex", "skills"))
|
|
1296
|
+
&& !holdsOpenSpec(path.join(".agents", "skills"))
|
|
1297
|
+
? "legacy"
|
|
1298
|
+
: "agents";
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
function openspecSkillRootForTarget(target, repo) {
|
|
1281
1302
|
if (target === "claude") return path.join(".claude", "skills");
|
|
1282
|
-
if (target === "codex")
|
|
1303
|
+
if (target === "codex") {
|
|
1304
|
+
return codexOpenSpecLayout(repo) === "legacy"
|
|
1305
|
+
? path.join(".codex", "skills")
|
|
1306
|
+
: path.join(".agents", "skills");
|
|
1307
|
+
}
|
|
1283
1308
|
return path.join(".opencode", "skills");
|
|
1284
1309
|
}
|
|
1285
1310
|
|
|
@@ -1294,6 +1319,16 @@ function commandSurfaceForTarget(target, repo) {
|
|
|
1294
1319
|
remediation: "run keel --init --target claude or openspec update --force",
|
|
1295
1320
|
};
|
|
1296
1321
|
}
|
|
1322
|
+
if (target === "codex" && codexOpenSpecLayout(repo) === "agents") {
|
|
1323
|
+
// OpenSpec 1.13 surfaces Codex's workflows as the skills counted on the
|
|
1324
|
+
// line above and writes no command file, so there is nothing to count here.
|
|
1325
|
+
return {
|
|
1326
|
+
location: path.join(".agents", "skills"),
|
|
1327
|
+
paths: [],
|
|
1328
|
+
remediation: "run keel --init --target codex or openspec update --force",
|
|
1329
|
+
skillsOnly: true,
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1297
1332
|
if (target === "codex") {
|
|
1298
1333
|
const home = codexHome();
|
|
1299
1334
|
const location = path.join(home, "prompts");
|
|
@@ -1320,13 +1355,15 @@ function commandPathForAction(target, repo, action) {
|
|
|
1320
1355
|
return path.join(repo, ".claude", "commands", "opsx", `${action}.md`);
|
|
1321
1356
|
}
|
|
1322
1357
|
if (target === "codex") {
|
|
1323
|
-
return
|
|
1358
|
+
return codexOpenSpecLayout(repo) === "legacy"
|
|
1359
|
+
? path.join(codexHome(), "prompts", `opsx-${action}.md`)
|
|
1360
|
+
: null;
|
|
1324
1361
|
}
|
|
1325
1362
|
return path.join(repo, ".opencode", "commands", `opsx-${action}.md`);
|
|
1326
1363
|
}
|
|
1327
1364
|
|
|
1328
1365
|
function openspecOverlaySurfacesForTarget(target, repo) {
|
|
1329
|
-
const skillRoot = openspecSkillRootForTarget(target);
|
|
1366
|
+
const skillRoot = openspecSkillRootForTarget(target, repo);
|
|
1330
1367
|
return OPENSPEC_OVERLAY_ACTIONS.flatMap((action) => {
|
|
1331
1368
|
if (action === "propose" && target === "opencode") {
|
|
1332
1369
|
return [];
|
|
@@ -1346,7 +1383,7 @@ function openspecOverlaySurfacesForTarget(target, repo) {
|
|
|
1346
1383
|
action,
|
|
1347
1384
|
path: commandPathForAction(target, repo, action),
|
|
1348
1385
|
},
|
|
1349
|
-
];
|
|
1386
|
+
].filter((surface) => surface.path !== null);
|
|
1350
1387
|
});
|
|
1351
1388
|
}
|
|
1352
1389
|
|
|
@@ -1699,7 +1736,7 @@ function printTargetSurface(repo, target) {
|
|
|
1699
1736
|
}
|
|
1700
1737
|
}
|
|
1701
1738
|
|
|
1702
|
-
const openspecSkillRoot = openspecSkillRootForTarget(target);
|
|
1739
|
+
const openspecSkillRoot = openspecSkillRootForTarget(target, repo);
|
|
1703
1740
|
const openspecSkillPaths = OPENSPEC_SKILLS.map((skill) =>
|
|
1704
1741
|
path.join(repo, openspecSkillRoot, skill, "SKILL.md")
|
|
1705
1742
|
);
|
|
@@ -1722,16 +1759,25 @@ function printTargetSurface(repo, target) {
|
|
|
1722
1759
|
);
|
|
1723
1760
|
|
|
1724
1761
|
const commands = commandSurfaceForTarget(target, repo);
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1762
|
+
if (commands.skillsOnly) {
|
|
1763
|
+
printDoctorLine(
|
|
1764
|
+
"OpenSpec commands",
|
|
1765
|
+
"ok",
|
|
1766
|
+
`none; OpenSpec 1.13 surfaces Codex's workflows as the skills under `
|
|
1767
|
+
+ `${commands.location}`
|
|
1768
|
+
);
|
|
1769
|
+
} else {
|
|
1770
|
+
const commandCounts = countExisting(commands.paths);
|
|
1771
|
+
const commandDetail =
|
|
1772
|
+
surfaceStatus(commandCounts) === "ok"
|
|
1773
|
+
? formatCount(commandCounts, commands.location)
|
|
1774
|
+
: `${formatCount(commandCounts, commands.location)}; ${commands.remediation}`;
|
|
1775
|
+
printDoctorLine(
|
|
1776
|
+
"OpenSpec commands",
|
|
1777
|
+
surfaceStatus(commandCounts),
|
|
1778
|
+
commandDetail
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1735
1781
|
|
|
1736
1782
|
const overlayPaths = openspecOverlaySurfacesForTarget(target, repo).map(
|
|
1737
1783
|
(surface) => surface.path
|