devlyn-cli 2.0.0 → 2.1.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/README.md +1 -1
- package/bin/devlyn.js +56 -10
- package/config/skills/devlyn:ideate/SKILL.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ If devlyn-cli saved you time, [give it a star](https://github.com/fysoul17/devly
|
|
|
27
27
|
npx devlyn-cli
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
That's it. The interactive installer handles everything. Claude Code config is installed by default; optional AI CLI instructions can be selected during install. Choose **Codex CLI (OpenAI)** to install `AGENTS.md
|
|
30
|
+
That's it. The interactive installer handles everything. Claude Code config is installed by default; optional AI CLI instructions can be selected during install. Choose **Codex CLI (OpenAI)** to install `AGENTS.md` AND `/devlyn:resolve` + `/devlyn:ideate` skills into `~/.codex/skills/` so the same slash commands work inside Codex too. Run it again anytime to update.
|
|
31
31
|
|
|
32
32
|
---
|
|
33
33
|
|
package/bin/devlyn.js
CHANGED
|
@@ -19,6 +19,10 @@ const CLI_TARGETS = {
|
|
|
19
19
|
instructionsFile: 'AGENTS.md',
|
|
20
20
|
baseInstructionsFile: 'AGENTS.md',
|
|
21
21
|
configDir: null, // Codex uses AGENTS.md at project root
|
|
22
|
+
// Codex auto-loads skills from ~/.codex/skills/ (user-global). Same
|
|
23
|
+
// SKILL.md format as Claude Code; descriptions must stay ≤1024 chars.
|
|
24
|
+
skillsDir: path.join(os.homedir(), '.codex', 'skills'),
|
|
25
|
+
skillsToInstall: ['devlyn:resolve', 'devlyn:ideate', '_shared'],
|
|
22
26
|
detect: () => fs.existsSync(path.join(process.cwd(), 'AGENTS.md')) || fs.existsSync(path.join(process.cwd(), '.codex')),
|
|
23
27
|
},
|
|
24
28
|
gemini: {
|
|
@@ -509,6 +513,37 @@ function detectOtherCLIs() {
|
|
|
509
513
|
return detected;
|
|
510
514
|
}
|
|
511
515
|
|
|
516
|
+
// Install /devlyn:resolve + /devlyn:ideate + _shared skills into a CLI's
|
|
517
|
+
// global skills directory (e.g. ~/.codex/skills/). Returns count of skills
|
|
518
|
+
// copied. Skipped silently for CLIs without a skillsDir (e.g. cursor, copilot
|
|
519
|
+
// at the time of writing — they don't have an analogous skill-loader).
|
|
520
|
+
function installSkillsForCLI(cliKey) {
|
|
521
|
+
const cli = CLI_TARGETS[cliKey];
|
|
522
|
+
if (!cli || !cli.skillsDir || !cli.skillsToInstall) return 0;
|
|
523
|
+
|
|
524
|
+
const sourceSkillsDir = path.join(CONFIG_SOURCE, 'skills');
|
|
525
|
+
if (!fs.existsSync(sourceSkillsDir)) return 0;
|
|
526
|
+
if (!fs.existsSync(cli.skillsDir)) {
|
|
527
|
+
fs.mkdirSync(cli.skillsDir, { recursive: true });
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
let copied = 0;
|
|
531
|
+
for (const skillName of cli.skillsToInstall) {
|
|
532
|
+
const src = path.join(sourceSkillsDir, skillName);
|
|
533
|
+
const dest = path.join(cli.skillsDir, skillName);
|
|
534
|
+
if (!fs.existsSync(src)) continue;
|
|
535
|
+
// Full replace per cleanManagedSkillDirs semantics: stale files in the
|
|
536
|
+
// installed mirror would otherwise persist forever.
|
|
537
|
+
if (fs.existsSync(dest)) {
|
|
538
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
539
|
+
}
|
|
540
|
+
copyRecursive(src, dest, cli.skillsDir);
|
|
541
|
+
copied++;
|
|
542
|
+
log(` → ${cli.skillsDir.replace(os.homedir(), '~')}/${skillName}`, 'dim');
|
|
543
|
+
}
|
|
544
|
+
return copied;
|
|
545
|
+
}
|
|
546
|
+
|
|
512
547
|
function installAgentsForCLI(cliKey) {
|
|
513
548
|
const cli = CLI_TARGETS[cliKey];
|
|
514
549
|
if (!cli) return false;
|
|
@@ -561,6 +596,14 @@ function installAgentsForCLI(cliKey) {
|
|
|
561
596
|
log(` → ${cli.instructionsFile} (agent instructions appended)`, 'dim');
|
|
562
597
|
}
|
|
563
598
|
|
|
599
|
+
// If this CLI also supports a global skill-loader (currently Codex), install
|
|
600
|
+
// /devlyn:resolve + /devlyn:ideate + _shared so the same slash commands work
|
|
601
|
+
// there. Skipped for CLIs without a skillsDir entry.
|
|
602
|
+
const skillsCopied = installSkillsForCLI(cliKey);
|
|
603
|
+
if (skillsCopied > 0) {
|
|
604
|
+
log(` → ${skillsCopied} skill${skillsCopied > 1 ? 's' : ''} installed (devlyn:resolve / devlyn:ideate / _shared)`, 'dim');
|
|
605
|
+
}
|
|
606
|
+
|
|
564
607
|
return true;
|
|
565
608
|
}
|
|
566
609
|
|
|
@@ -695,7 +738,7 @@ async function init(skipPrompts = false) {
|
|
|
695
738
|
// Skip prompts if -y flag or non-interactive
|
|
696
739
|
if (skipPrompts || !process.stdin.isTTY) {
|
|
697
740
|
log('\n💡 Add optional addons later: run `npx devlyn-cli` without -y', 'dim');
|
|
698
|
-
log(' Add Codex instructions later: run `npx devlyn-cli agents codex`', 'dim');
|
|
741
|
+
log(' Add Codex instructions + skills later: run `npx devlyn-cli agents codex`', 'dim');
|
|
699
742
|
log(`\n${COLORS.dim} Enjoying devlyn? Star it on GitHub — it helps others find it:${COLORS.reset}`);
|
|
700
743
|
log(` ${COLORS.purple}→ https://github.com/fysoul17/devlyn-cli${COLORS.reset}\n`);
|
|
701
744
|
return;
|
|
@@ -703,14 +746,17 @@ async function init(skipPrompts = false) {
|
|
|
703
746
|
|
|
704
747
|
// Ask which non-Claude CLIs should receive instruction files.
|
|
705
748
|
log('\n🤖 Optional AI CLI instructions:\n', 'blue');
|
|
706
|
-
const cliOptions = Object.entries(CLI_TARGETS).map(([key, cli]) =>
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
749
|
+
const cliOptions = Object.entries(CLI_TARGETS).map(([key, cli]) => {
|
|
750
|
+
let desc;
|
|
751
|
+
if (cli.configDir) {
|
|
752
|
+
desc = `Install agents into ${cli.configDir}/`;
|
|
753
|
+
} else if (cli.skillsDir) {
|
|
754
|
+
desc = `Install ${cli.instructionsFile} + /devlyn:resolve + /devlyn:ideate skills (~/.codex/skills/)`;
|
|
755
|
+
} else {
|
|
756
|
+
desc = `Install ${cli.instructionsFile}`;
|
|
757
|
+
}
|
|
758
|
+
return { key, name: cli.name, desc, type: 'cli' };
|
|
759
|
+
});
|
|
714
760
|
const selectedClis = await multiSelect(cliOptions);
|
|
715
761
|
if (selectedClis.length > 0) {
|
|
716
762
|
let agentsInstalled = 0;
|
|
@@ -720,7 +766,7 @@ async function init(skipPrompts = false) {
|
|
|
720
766
|
log(` ✅ Agent instructions installed for ${agentsInstalled} CLI${agentsInstalled !== 1 ? 's' : ''}`, 'green');
|
|
721
767
|
} else {
|
|
722
768
|
log('💡 No additional CLI instructions selected', 'dim');
|
|
723
|
-
log(' Run `npx devlyn-cli agents codex` later to install Codex AGENTS.md', 'dim');
|
|
769
|
+
log(' Run `npx devlyn-cli agents codex` later to install Codex AGENTS.md + /devlyn skills', 'dim');
|
|
724
770
|
}
|
|
725
771
|
|
|
726
772
|
// Ask about optional addons (local skills + external packs)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devlyn:ideate
|
|
3
|
-
description: Extract a verifiable spec from a user's idea by driving the conversation with focused questions. Output is a single-feature `spec.md` + `spec.expected.json` that `/devlyn:resolve --spec` consumes directly. Use when the user has an idea but not a spec, or wants AI to elicit the missing engineering context. Modes
|
|
3
|
+
description: Extract a verifiable spec from a user's idea by driving the conversation with focused questions. Output is a single-feature `spec.md` + `spec.expected.json` that `/devlyn:resolve --spec` consumes directly. Use when the user has an idea but not a spec, or wants AI to elicit the missing engineering context. Modes — default (single spec, AI drives Q&A), `--quick` (assume-and-confirm from one-line goal), `--from-spec <path>` (normalize external spec), `--project` (plan.md index + N specs). Optional in the pipeline — `/devlyn:resolve` works standalone via free-form mode for users who skip ideate.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Spec-elicitation surface for users who have ideas but not engineering specifications. AI drives the conversation with focused questions until a structurally-valid, verifiable spec exists. Output consumed directly by `/devlyn:resolve --spec`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "AI development toolkit for Claude Code — ideate, auto-resolve, and ship with context engineering and agent orchestration",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|