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 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`. Run it again anytime to update.
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
- key,
708
- name: cli.name,
709
- desc: cli.configDir
710
- ? `Install agents into ${cli.configDir}/`
711
- : `Install ${cli.instructionsFile}`,
712
- type: 'cli',
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: 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.
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.0.0",
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": {