don-cheli-sdd 1.29.0 → 1.30.1

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.md CHANGED
@@ -4,6 +4,24 @@ Todos los cambios notables en Don Cheli SDD Framework.
4
4
 
5
5
  Formato basado en [Conventional Commits](https://www.conventionalcommits.org/).
6
6
 
7
+ ## [1.30.1](https://github.com/doncheli/don-cheli-sdd/compare/v1.30.0...v1.30.1) (2026-04-08)
8
+
9
+ ### Correcciones
10
+
11
+ * integración completa OpenCode — 13 problemas corregidos ([060cc01](https://github.com/doncheli/don-cheli-sdd/commit/060cc0140680bf7487675a117d216b57bbc41cd5))
12
+
13
+ ## [1.30.0](https://github.com/doncheli/don-cheli-sdd/compare/v1.29.0...v1.30.0) (2026-04-08)
14
+
15
+ ### Nuevas Funcionalidades
16
+
17
+ * agregar soporte para Qwen + fix mirrors generar-config ([099a03f](https://github.com/doncheli/don-cheli-sdd/commit/099a03f3ddbafc7d7e3197d60304b0a1e946c87e))
18
+
19
+ ### Documentación
20
+
21
+ * agregar benchmark posts para X y LinkedIn con datos verificados ([40cc480](https://github.com/doncheli/don-cheli-sdd/commit/40cc480eb2391b502513f16762683a664ed3c957))
22
+ * agregar benchmark posts para X y LinkedIn con datos verificados ([7f3c570](https://github.com/doncheli/don-cheli-sdd/commit/7f3c570d48e51ae0867f2c42823b2e2cd2ebca60))
23
+ * optimizar post LinkedIn a <3000 caracteres ([a2a8b31](https://github.com/doncheli/don-cheli-sdd/commit/a2a8b319d3a400005ca88abcde602a4aa040a475))
24
+
7
25
  ## [1.29.0](https://github.com/doncheli/don-cheli-sdd/compare/v1.28.0...v1.29.0) (2026-04-07)
8
26
 
9
27
  ### Nuevas Funcionalidades
package/README.es.md CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
  <p align="center">
14
14
  <a href="#-instalación"><img src="https://img.shields.io/badge/instalación-2_minutos-brightgreen" alt="Install"></a>
15
- <img src="https://img.shields.io/badge/versión-1.29.0-blue" alt="Version">
15
+ <img src="https://img.shields.io/badge/versión-1.30.1-blue" alt="Version">
16
16
  <img src="https://img.shields.io/badge/licencia-Apache%202.0-green" alt="License">
17
17
  <img src="https://img.shields.io/badge/idiomas-ES%20|%20EN%20|%20PT-red" alt="Languages">
18
18
  <img src="https://img.shields.io/badge/comandos-93+-purple" alt="Commands">
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
  <p align="center">
14
14
  <a href="#-installation"><img src="https://img.shields.io/badge/install-2_minutes-brightgreen" alt="Install"></a>
15
- <img src="https://img.shields.io/badge/version-1.29.0-blue" alt="Version">
15
+ <img src="https://img.shields.io/badge/version-1.30.1-blue" alt="Version">
16
16
  <img src="https://img.shields.io/badge/license-Apache%202.0-green" alt="License">
17
17
  <img src="https://img.shields.io/badge/languages-ES%20|%20EN%20|%20PT-red" alt="Languages">
18
18
  <img src="https://img.shields.io/badge/commands-93+-purple" alt="Commands">
package/README.pt.md CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
  <p align="center">
14
14
  <a href="#-instalação"><img src="https://img.shields.io/badge/instalação-2_minutos-brightgreen" alt="Install"></a>
15
- <img src="https://img.shields.io/badge/versão-1.29.0-blue" alt="Version">
15
+ <img src="https://img.shields.io/badge/versão-1.30.1-blue" alt="Version">
16
16
  <img src="https://img.shields.io/badge/licença-Apache%202.0-green" alt="License">
17
17
  <img src="https://img.shields.io/badge/idiomas-ES%20|%20EN%20|%20PT-red" alt="Languages">
18
18
  <img src="https://img.shields.io/badge/comandos-93+-purple" alt="Commands">
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.29.0
1
+ 1.30.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "don-cheli-sdd",
3
- "version": "1.29.0",
3
+ "version": "1.30.1",
4
4
  "description": "Don Cheli SDD Framework — 93+ commands, 51 skills, 15 reasoning models, Autonomous Mode, TDD Iron Law, OWASP audit, PRD Generator, Crash Recovery. Works with Claude Code, Gemini, Cursor, Codex, Warp, Amp, OpenCode. ES/EN/PT.",
5
5
  "main": "bin/don-cheli.js",
6
6
  "scripts": {
@@ -1 +1 @@
1
- 1.29.0
1
+ 1.30.1
@@ -0,0 +1,383 @@
1
+ #!/bin/bash
2
+ # Don Cheli - Config Generator
3
+ # Generates tool-specific configuration files based on profile, skills, and commands
4
+ #
5
+ # Intended to be sourced from instalar.sh, not run standalone.
6
+ # Main entry point: generar_configs()
7
+
8
+ # Helper: detect project root from FRAMEWORK_HOME path
9
+ # .claude/don-cheli → project root is the parent
10
+ _get_project_root() {
11
+ local dir="$1"
12
+ local root
13
+ if [[ "$dir" == *".claude/don-cheli"* ]]; then
14
+ root="${dir%/.claude/don-cheli*}"
15
+ [ -z "$root" ] && root="."
16
+ elif [[ "$dir" == *".claude"* ]]; then
17
+ root="${dir%/.claude*}"
18
+ [ -z "$root" ] && root="."
19
+ else
20
+ root="$dir"
21
+ fi
22
+ echo "$root"
23
+ }
24
+
25
+ generar_configs() {
26
+ local tools="$1"
27
+ local profile="$2"
28
+ local skills="$3"
29
+ local commands="$4"
30
+ local install_dir="$5"
31
+ local framework_home="$6"
32
+ local locale="${7:-es}"
33
+
34
+ # Colors (fallback to empty if not set by caller)
35
+ local GREEN="${GREEN:-\033[0;32m}"
36
+ local RED="${RED:-\033[0;31m}"
37
+ local YELLOW="${YELLOW:-\033[1;33m}"
38
+ local NC="${NC:-\033[0m}"
39
+
40
+ # Validate required args
41
+ if [ -z "$tools" ] || [ -z "$install_dir" ] || [ -z "$framework_home" ]; then
42
+ echo -e " ${RED}✗${NC} generar_configs: missing required arguments (tools, install_dir, framework_home)" >&2
43
+ return 1
44
+ fi
45
+
46
+ # Parse tools into array
47
+ IFS=',' read -ra TOOL_ARRAY <<< "$tools"
48
+
49
+ for tool in "${TOOL_ARRAY[@]}"; do
50
+ # Trim whitespace
51
+ tool="${tool#"${tool%%[![:space:]]*}"}"
52
+ tool="${tool%"${tool##*[![:space:]]}"}"
53
+
54
+ case "$tool" in
55
+ claude)
56
+ _gen_claude "$install_dir" "$framework_home" "$locale" "$profile" "$skills" "$commands"
57
+ ;;
58
+ codex)
59
+ _gen_codex "$install_dir" "$framework_home" "$locale"
60
+ ;;
61
+ cursor)
62
+ _gen_cursor "$install_dir" "$framework_home" "$locale"
63
+ ;;
64
+ antigravity)
65
+ _gen_antigravity "$install_dir" "$framework_home" "$locale"
66
+ ;;
67
+ windsurf)
68
+ _gen_windsurf "$install_dir" "$framework_home" "$locale"
69
+ ;;
70
+ amp)
71
+ _gen_amp "$install_dir" "$framework_home" "$locale"
72
+ ;;
73
+ continue)
74
+ _gen_continue "$install_dir" "$framework_home" "$locale"
75
+ ;;
76
+ opencode)
77
+ _gen_opencode "$install_dir" "$framework_home" "$locale"
78
+ ;;
79
+ qwen)
80
+ _gen_qwen "$install_dir" "$framework_home" "$locale"
81
+ ;;
82
+ *)
83
+ echo -e " ${YELLOW}⚠${NC} Unknown tool: '$tool' — skipping" >&2
84
+ ;;
85
+ esac
86
+ done
87
+ }
88
+
89
+ # ─────────────────────────────────────────────
90
+ # Claude Code → CLAUDE.md + .claude/commands/
91
+ # ─────────────────────────────────────────────
92
+ _gen_claude() {
93
+ local dir="$1" home="$2" locale="$3" profile="$4" skills="$5" commands="$6"
94
+
95
+ echo -e " ${GREEN:-}✓${NC:-} Claude Code → CLAUDE.md + commands/"
96
+
97
+ # Copy locale-specific CLAUDE.md, fall back to default es
98
+ if [ "$locale" != "es" ] && [ -f "$home/CLAUDE.${locale}.md" ]; then
99
+ cp "$home/CLAUDE.${locale}.md" "$dir/CLAUDE.md" 2>/dev/null || true
100
+ elif [ -f "$home/CLAUDE.md" ]; then
101
+ cp "$home/CLAUDE.md" "$dir/" 2>/dev/null || true
102
+ else
103
+ echo -e " ${YELLOW:-}⚠${NC:-} CLAUDE.md not found in $home — skipping" >&2
104
+ fi
105
+
106
+ # Append active profile/skills/commands summary to CLAUDE.md
107
+ if [ -f "$dir/CLAUDE.md" ] && { [ -n "$profile" ] || [ -n "$skills" ] || [ -n "$commands" ]; }; then
108
+ {
109
+ echo ""
110
+ echo "## Perfil de instalación"
111
+ [ -n "$profile" ] && echo "- **Perfil**: $profile"
112
+ [ -n "$skills" ] && echo "- **Skills activos**: $skills"
113
+ [ -n "$commands" ] && echo "- **Comandos activos**: $commands"
114
+ } >> "$dir/CLAUDE.md" 2>/dev/null || true
115
+ fi
116
+
117
+ # Create command directories and copy command files
118
+ mkdir -p "$dir/.claude/commands/dc" \
119
+ "$dir/.claude/commands/especdev" \
120
+ "$dir/.claude/commands/razonar" 2>/dev/null || true
121
+
122
+ local commands_root
123
+ commands_root="$(cd "$home/../.." 2>/dev/null && pwd)" || commands_root=""
124
+
125
+ if [ -n "$commands_root" ] && [ -d "$commands_root/commands" ]; then
126
+ cp "$commands_root/commands/especdev/"*.md "$dir/.claude/commands/especdev/" 2>/dev/null || true
127
+ cp "$commands_root/commands/dc/"*.md "$dir/.claude/commands/dc/" 2>/dev/null || true
128
+ cp "$commands_root/commands/razonar/"*.md "$dir/.claude/commands/razonar/" 2>/dev/null || true
129
+ fi
130
+ }
131
+
132
+ # ─────────────────────────────────────────────
133
+ # Codex → AGENTS.md
134
+ # ─────────────────────────────────────────────
135
+ _gen_codex() {
136
+ local dir="$1" home="$2" locale="$3"
137
+ local project_root
138
+ project_root=$(_get_project_root "$dir")
139
+
140
+ echo -e " ${GREEN:-}✓${NC:-} Codex → AGENTS.md (en $project_root/)"
141
+
142
+ if [ -f "$home/AGENTS.md" ]; then
143
+ cp "$home/AGENTS.md" "$project_root/" 2>/dev/null || true
144
+ else
145
+ # Generate a minimal AGENTS.md if template is missing
146
+ cat > "$dir/AGENTS.md" 2>/dev/null << 'AGENTSEOF' || true
147
+ # Don Cheli SDD — Codex Agent Instructions
148
+
149
+ ## Iron Laws
150
+ 1. **TDD**: All production code requires tests (RED → GREEN → REFACTOR)
151
+ 2. **Debugging**: Root cause first, then fix
152
+ 3. **Verification**: Evidence before assertions
153
+
154
+ ## Workflow
155
+ - Read files on demand, not preemptively
156
+ - Structured outputs from the start
157
+ - Retrocompatible changes unless explicitly stated otherwise
158
+ AGENTSEOF
159
+ fi
160
+ }
161
+
162
+ # ─────────────────────────────────────────────
163
+ # Cursor → .cursorrules
164
+ # ─────────────────────────────────────────────
165
+ _gen_cursor() {
166
+ local dir="$1" home="$2" locale="$3"
167
+ local project_root
168
+ project_root=$(_get_project_root "$dir")
169
+
170
+ echo -e " ${GREEN:-}✓${NC:-} Cursor → .cursorrules (en $project_root/)"
171
+
172
+ if [ "$locale" != "en" ] && [ -f "$home/.cursorrules.${locale}" ]; then
173
+ cp "$home/.cursorrules.${locale}" "$project_root/.cursorrules" 2>/dev/null || true
174
+ elif [ -f "$home/.cursorrules" ]; then
175
+ cp "$home/.cursorrules" "$project_root/" 2>/dev/null || true
176
+ else
177
+ echo -e " ${YELLOW:-}⚠${NC:-} .cursorrules not found in $home — skipping" >&2
178
+ fi
179
+ }
180
+
181
+ # ─────────────────────────────────────────────
182
+ # Antigravity → GEMINI.md + .agent/ (at PROJECT ROOT, not inside .claude/)
183
+ # ─────────────────────────────────────────────
184
+ _gen_antigravity() {
185
+ local dir="$1" home="$2" locale="$3"
186
+ local project_root
187
+ project_root=$(_get_project_root "$dir")
188
+
189
+ echo -e " ${GREEN:-}✓${NC:-} Antigravity → GEMINI.md + .agent/ (en $project_root/)"
190
+
191
+ if [ "$locale" != "en" ] && [ -f "$home/GEMINI.${locale}.md" ]; then
192
+ cp "$home/GEMINI.${locale}.md" "$project_root/GEMINI.md" 2>/dev/null || true
193
+ elif [ -f "$home/GEMINI.md" ]; then
194
+ cp "$home/GEMINI.md" "$project_root/" 2>/dev/null || true
195
+ else
196
+ echo -e " ${YELLOW:-}⚠${NC:-} GEMINI.md not found in $home — skipping" >&2
197
+ fi
198
+
199
+ if [ -d "$home/.agent" ]; then
200
+ mkdir -p "$project_root/.agent" 2>/dev/null || true
201
+ cp -r "$home/.agent/"* "$project_root/.agent/" 2>/dev/null || true
202
+ fi
203
+ }
204
+
205
+ # ─────────────────────────────────────────────
206
+ # Windsurf → .windsurf/rules/don-cheli.md
207
+ # ─────────────────────────────────────────────
208
+ _gen_windsurf() {
209
+ local dir="$1" home="$2" locale="$3"
210
+ local project_root
211
+ project_root=$(_get_project_root "$dir")
212
+
213
+ echo -e " ${GREEN:-}✓${NC:-} Windsurf → .windsurf/rules/don-cheli.md (en $project_root/)"
214
+
215
+ mkdir -p "$project_root/.windsurf/rules" 2>/dev/null || true
216
+
217
+ if [ -f "$home/.windsurf/rules/don-cheli.md" ]; then
218
+ cp "$home/.windsurf/rules/don-cheli.md" "$project_root/.windsurf/rules/don-cheli.md" 2>/dev/null || true
219
+ elif [ -f "$home/.cursorrules" ]; then
220
+ cp "$home/.cursorrules" "$project_root/.windsurf/rules/don-cheli.md" 2>/dev/null || true
221
+ else
222
+ echo -e " ${YELLOW:-}⚠${NC:-} No Windsurf template found in $home — skipping" >&2
223
+ fi
224
+ }
225
+
226
+ # ─────────────────────────────────────────────
227
+ # Amp → prompt.md
228
+ # ─────────────────────────────────────────────
229
+ _gen_amp() {
230
+ local dir="$1" home="$2" locale="$3"
231
+ local project_root
232
+ project_root=$(_get_project_root "$dir")
233
+
234
+ echo -e " ${GREEN:-}✓${NC:-} Amp → prompt.md (en $project_root/)"
235
+
236
+ if [ -f "$home/prompt.md" ]; then
237
+ cp "$home/prompt.md" "$project_root/" 2>/dev/null || true
238
+ else
239
+ echo -e " ${YELLOW:-}⚠${NC:-} prompt.md not found in $home — skipping" >&2
240
+ fi
241
+ }
242
+
243
+ # ─────────────────────────────────────────────
244
+ # Continue.dev → .continue/config/don-cheli.json
245
+ # ─────────────────────────────────────────────
246
+ _gen_continue() {
247
+ local dir="$1" home="$2" locale="$3"
248
+ local project_root
249
+ project_root=$(_get_project_root "$dir")
250
+
251
+ echo -e " ${GREEN:-}✓${NC:-} Continue.dev → .continue/config/don-cheli.json (en $project_root/)"
252
+
253
+ mkdir -p "$project_root/.continue/config" 2>/dev/null || true
254
+
255
+ if [ -f "$home/.continue/config/don-cheli.json" ]; then
256
+ cp "$home/.continue/config/don-cheli.json" "$project_root/.continue/config/don-cheli.json" 2>/dev/null || true
257
+ else
258
+ cat > "$project_root/.continue/config/don-cheli.json" 2>/dev/null << 'CONTEOF' || true
259
+ {
260
+ "name": "don-cheli-sdd",
261
+ "version": "1.29.0",
262
+ "description": "Don Cheli SDD Framework",
263
+ "rules": [
264
+ "All production code requires tests (TDD: RED → GREEN → REFACTOR)",
265
+ "Root cause first, then fix (Debugging)",
266
+ "Evidence before assertions (Verification)",
267
+ "Read files on demand, not preemptively",
268
+ "Structured outputs from the start"
269
+ ]
270
+ }
271
+ CONTEOF
272
+ fi
273
+ }
274
+
275
+ # ─────────────────────────────────────────────
276
+ # OpenCode → ~/.config/opencode/config.json
277
+ # ─────────────────────────────────────────────
278
+ _gen_opencode() {
279
+ local dir="$1" home="$2" locale="$3"
280
+ local project_root
281
+ project_root=$(_get_project_root "$dir")
282
+
283
+ echo -e " ${GREEN:-}✓${NC:-} OpenCode → config + .opencode/ (en $project_root/)"
284
+
285
+ # Copy opencode.json and .opencode/ to project root
286
+ if [ -f "$home/opencode.json" ]; then
287
+ cp "$home/opencode.json" "$project_root/" 2>/dev/null || true
288
+ fi
289
+ if [ -d "$home/.opencode" ]; then
290
+ # Copy agents, commands and skills to project root
291
+ for subdir in agents commands skills; do
292
+ if [ -d "$home/.opencode/$subdir" ]; then
293
+ mkdir -p "$project_root/.opencode/$subdir" 2>/dev/null || true
294
+ cp -r "$home/.opencode/$subdir/"* "$project_root/.opencode/$subdir/" 2>/dev/null || true
295
+ fi
296
+ done
297
+ fi
298
+
299
+ local opencode_config="$HOME/.config/opencode/config.json"
300
+ local skills_path="${home}/.agent/skills"
301
+ local tmp_config
302
+
303
+ # Ensure opencode config directory exists
304
+ mkdir -p "$(dirname "$opencode_config")" 2>/dev/null || true
305
+
306
+ # If config doesn't exist, create it
307
+ if [ ! -f "$opencode_config" ]; then
308
+ cat > "$opencode_config" << 'OPENCODECONFIG'
309
+ {
310
+ "$schema": "https://opencode.ai/config.json",
311
+ "autoupdate": true,
312
+ "permission": {
313
+ "external_directory": {}
314
+ },
315
+ "skills": {
316
+ "paths": []
317
+ }
318
+ }
319
+ OPENCODECONFIG
320
+ echo -e " ${GREEN:-}✓${NC:-} Created new opencode config"
321
+ fi
322
+
323
+ # Use jq if available for robust JSON editing
324
+ if command -v jq &>/dev/null; then
325
+ # Add external_directory permission
326
+ jq '(.permission.external_directory // {}) |= if has("${HOME}/.claude/**") then . else . + {"${HOME}/.claude/**": "allow"} end' "$opencode_config" > "${opencode_config}.tmp" && mv "${opencode_config}.tmp" "$opencode_config"
327
+
328
+ # Add skills path
329
+ jq ".skills.paths += [\"${skills_path}\"] | .skills.paths = (.skills.paths | unique)" "$opencode_config" > "${opencode_config}.tmp" && mv "${opencode_config}.tmp" "$opencode_config"
330
+
331
+ echo -e " ${GREEN:-}✓${NC:-} Config updated with jq"
332
+ else
333
+ # Fallback: append to paths array manually (less robust)
334
+ if ! grep -q "${skills_path}" "$opencode_config" 2>/dev/null; then
335
+ # Simple append to paths array (last element stays as empty array)
336
+ sed -i "s/\"paths\": \[\]/\"paths\": [\"${skills_path}\"]/" "$opencode_config" 2>/dev/null || true
337
+ fi
338
+
339
+ if ! grep -q '"${HOME}/.claude' "$opencode_config" 2>/dev/null; then
340
+ # Simple append to external_directory (might create invalid JSON)
341
+ sed -i 's/"external_directory": {}/"external_directory": { "\/root\/.claude\/**": "allow" }/' "$opencode_config" 2>/dev/null || true
342
+ fi
343
+
344
+ echo -e " ${YELLOW:-}⚠${NC:-} jq not found, used fallback sed (less reliable)"
345
+ fi
346
+
347
+ # Verify final config
348
+ if [ -f "$opencode_config" ]; then
349
+ echo -e " ${GREEN:-}✓${NC:-} Config saved to ${opencode_config}"
350
+ echo -e " ${GREEN:-}✓${NC:-} Skills path: ${skills_path}"
351
+ else
352
+ echo -e " ${YELLOW:-}⚠${NC:-} Failed to write config"
353
+ fi
354
+ }
355
+
356
+ # ─────────────────────────────────────────────
357
+ # Qwen → AGENTS.md + .opencode/ (at project root)
358
+ # ─────────────────────────────────────────────
359
+ _gen_qwen() {
360
+ local dir="$1" home="$2" locale="$3"
361
+ local project_root
362
+ project_root=$(_get_project_root "$dir")
363
+
364
+ echo -e " ${GREEN:-}✓${NC:-} Qwen → AGENTS.md + .opencode/ (en $project_root/)"
365
+
366
+ # Qwen uses AGENTS.md like Codex
367
+ if [ -f "$home/AGENTS.md" ]; then
368
+ cp "$home/AGENTS.md" "$project_root/" 2>/dev/null || true
369
+ fi
370
+
371
+ # Also copy OpenCode agent, commands and skills (Qwen can use opencode format)
372
+ if [ -d "$home/.opencode" ]; then
373
+ for subdir in agents commands skills; do
374
+ if [ -d "$home/.opencode/$subdir" ]; then
375
+ mkdir -p "$project_root/.opencode/$subdir" 2>/dev/null || true
376
+ cp -r "$home/.opencode/$subdir/"* "$project_root/.opencode/$subdir/" 2>/dev/null || true
377
+ fi
378
+ done
379
+ fi
380
+ if [ -f "$home/opencode.json" ]; then
381
+ cp "$home/opencode.json" "$project_root/" 2>/dev/null || true
382
+ fi
383
+ }
@@ -4,7 +4,7 @@
4
4
 
5
5
  set -euo pipefail
6
6
 
7
- VERSION="1.29.0"
7
+ VERSION="1.30.1"
8
8
  REPO_URL="https://github.com/doncheli/don-cheli-sdd"
9
9
  CLEANUP_TMPDIR=""
10
10
 
@@ -338,7 +338,7 @@ if [ "$INTERACTIVE_MODE" = true ]; then
338
338
  if [ -z "$TOOLS_FLAG" ]; then
339
339
  GUM_TOOLS_OK=false
340
340
  if [ "$HAS_GUM" = true ]; then
341
- TOOLS_RAW=$(printf "Claude Code\nCodex\nCursor\nAntigravity\nWindsurf\nAmp\nContinue.dev\nOpenCode\nTodos" | \
341
+ TOOLS_RAW=$(printf "Claude Code\nCodex\nCursor\nAntigravity\nWindsurf\nAmp\nContinue.dev\nOpenCode\nQwen\nTodos" | \
342
342
  gum choose --no-limit \
343
343
  --header "¿Dónde quieres instalar Don Cheli SDD?" \
344
344
  --header.foreground="99" \
@@ -358,7 +358,8 @@ if [ "$INTERACTIVE_MODE" = true ]; then
358
358
  "Amp") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}amp" ;;
359
359
  "Continue.dev") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}continue" ;;
360
360
  "OpenCode") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}opencode" ;;
361
- "Todos") TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode" ;;
361
+ "Qwen") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}qwen" ;;
362
+ "Todos") TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode,qwen" ;;
362
363
  esac
363
364
  done <<< "$TOOLS_RAW"
364
365
  GUM_TOOLS_OK=true
@@ -375,7 +376,8 @@ if [ "$INTERACTIVE_MODE" = true ]; then
375
376
  echo -e " ${CYAN}6)${NC} Amp (prompt.md)"
376
377
  echo -e " ${CYAN}7)${NC} Continue.dev (.continue/config/)"
377
378
  echo -e " ${CYAN}8)${NC} OpenCode (.opencode/ + @doncheli)"
378
- echo -e " ${CYAN}9)${NC} Todos"
379
+ echo -e " ${CYAN}9)${NC} Qwen (AGENTS.md + .opencode/)"
380
+ echo -e " ${CYAN}10)${NC} Todos"
379
381
  echo ""
380
382
  echo -ne " ${BOLD}▸ Elige (números separados por coma): ${NC}"
381
383
  TOOLS_CHOICE=""
@@ -396,7 +398,8 @@ if [ "$INTERACTIVE_MODE" = true ]; then
396
398
  6) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}amp" ;;
397
399
  7) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}continue" ;;
398
400
  8) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}opencode" ;;
399
- 9|all) TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode" ;;
401
+ 9) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}qwen" ;;
402
+ 10|all) TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode,qwen" ;;
400
403
  esac
401
404
  done
402
405
  fi
@@ -76,6 +76,9 @@ generar_configs() {
76
76
  opencode)
77
77
  _gen_opencode "$install_dir" "$framework_home" "$locale"
78
78
  ;;
79
+ qwen)
80
+ _gen_qwen "$install_dir" "$framework_home" "$locale"
81
+ ;;
79
82
  *)
80
83
  echo -e " ${YELLOW}⚠${NC} Unknown tool: '$tool' — skipping" >&2
81
84
  ;;
@@ -255,7 +258,7 @@ _gen_continue() {
255
258
  cat > "$project_root/.continue/config/don-cheli.json" 2>/dev/null << 'CONTEOF' || true
256
259
  {
257
260
  "name": "don-cheli-sdd",
258
- "version": "1.29.0",
261
+ "version": "1.30.1",
259
262
  "description": "Don Cheli SDD Framework",
260
263
  "rules": [
261
264
  "All production code requires tests (TDD: RED → GREEN → REFACTOR)",
@@ -284,8 +287,13 @@ _gen_opencode() {
284
287
  cp "$home/opencode.json" "$project_root/" 2>/dev/null || true
285
288
  fi
286
289
  if [ -d "$home/.opencode" ]; then
287
- mkdir -p "$project_root/.opencode/agents" 2>/dev/null || true
288
- cp -r "$home/.opencode/"* "$project_root/.opencode/" 2>/dev/null || true
290
+ # Copy agents, commands and skills to project root
291
+ for subdir in agents commands skills; do
292
+ if [ -d "$home/.opencode/$subdir" ]; then
293
+ mkdir -p "$project_root/.opencode/$subdir" 2>/dev/null || true
294
+ cp -r "$home/.opencode/$subdir/"* "$project_root/.opencode/$subdir/" 2>/dev/null || true
295
+ fi
296
+ done
289
297
  fi
290
298
 
291
299
  local opencode_config="$HOME/.config/opencode/config.json"
@@ -315,7 +323,7 @@ OPENCODECONFIG
315
323
  # Use jq if available for robust JSON editing
316
324
  if command -v jq &>/dev/null; then
317
325
  # Add external_directory permission
318
- jq '(.permission.external_directory // {}) |= if has("/root/.claude/**") then . else . + {"/root/.claude/**": "allow"} end' "$opencode_config" > "${opencode_config}.tmp" && mv "${opencode_config}.tmp" "$opencode_config"
326
+ jq '(.permission.external_directory // {}) |= if has("${HOME}/.claude/**") then . else . + {"${HOME}/.claude/**": "allow"} end' "$opencode_config" > "${opencode_config}.tmp" && mv "${opencode_config}.tmp" "$opencode_config"
319
327
 
320
328
  # Add skills path
321
329
  jq ".skills.paths += [\"${skills_path}\"] | .skills.paths = (.skills.paths | unique)" "$opencode_config" > "${opencode_config}.tmp" && mv "${opencode_config}.tmp" "$opencode_config"
@@ -328,7 +336,7 @@ OPENCODECONFIG
328
336
  sed -i "s/\"paths\": \[\]/\"paths\": [\"${skills_path}\"]/" "$opencode_config" 2>/dev/null || true
329
337
  fi
330
338
 
331
- if ! grep -q '"/root/.claude' "$opencode_config" 2>/dev/null; then
339
+ if ! grep -q '"${HOME}/.claude' "$opencode_config" 2>/dev/null; then
332
340
  # Simple append to external_directory (might create invalid JSON)
333
341
  sed -i 's/"external_directory": {}/"external_directory": { "\/root\/.claude\/**": "allow" }/' "$opencode_config" 2>/dev/null || true
334
342
  fi
@@ -344,3 +352,32 @@ OPENCODECONFIG
344
352
  echo -e " ${YELLOW:-}⚠${NC:-} Failed to write config"
345
353
  fi
346
354
  }
355
+
356
+ # ─────────────────────────────────────────────
357
+ # Qwen → AGENTS.md + .opencode/ (at project root)
358
+ # ─────────────────────────────────────────────
359
+ _gen_qwen() {
360
+ local dir="$1" home="$2" locale="$3"
361
+ local project_root
362
+ project_root=$(_get_project_root "$dir")
363
+
364
+ echo -e " ${GREEN:-}✓${NC:-} Qwen → AGENTS.md + .opencode/ (en $project_root/)"
365
+
366
+ # Qwen uses AGENTS.md like Codex
367
+ if [ -f "$home/AGENTS.md" ]; then
368
+ cp "$home/AGENTS.md" "$project_root/" 2>/dev/null || true
369
+ fi
370
+
371
+ # Also copy OpenCode agent, commands and skills (Qwen can use opencode format)
372
+ if [ -d "$home/.opencode" ]; then
373
+ for subdir in agents commands skills; do
374
+ if [ -d "$home/.opencode/$subdir" ]; then
375
+ mkdir -p "$project_root/.opencode/$subdir" 2>/dev/null || true
376
+ cp -r "$home/.opencode/$subdir/"* "$project_root/.opencode/$subdir/" 2>/dev/null || true
377
+ fi
378
+ done
379
+ fi
380
+ if [ -f "$home/opencode.json" ]; then
381
+ cp "$home/opencode.json" "$project_root/" 2>/dev/null || true
382
+ fi
383
+ }
@@ -4,7 +4,7 @@
4
4
 
5
5
  set -euo pipefail
6
6
 
7
- VERSION="1.29.0"
7
+ VERSION="1.30.1"
8
8
  REPO_URL="https://github.com/doncheli/don-cheli-sdd"
9
9
  CLEANUP_TMPDIR=""
10
10
 
@@ -338,7 +338,7 @@ if [ "$INTERACTIVE_MODE" = true ]; then
338
338
  if [ -z "$TOOLS_FLAG" ]; then
339
339
  GUM_TOOLS_OK=false
340
340
  if [ "$HAS_GUM" = true ]; then
341
- TOOLS_RAW=$(printf "Claude Code\nCodex\nCursor\nAntigravity\nWindsurf\nAmp\nContinue.dev\nOpenCode\nTodos" | \
341
+ TOOLS_RAW=$(printf "Claude Code\nCodex\nCursor\nAntigravity\nWindsurf\nAmp\nContinue.dev\nOpenCode\nQwen\nTodos" | \
342
342
  gum choose --no-limit \
343
343
  --header "¿Dónde quieres instalar Don Cheli SDD?" \
344
344
  --header.foreground="99" \
@@ -358,7 +358,8 @@ if [ "$INTERACTIVE_MODE" = true ]; then
358
358
  "Amp") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}amp" ;;
359
359
  "Continue.dev") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}continue" ;;
360
360
  "OpenCode") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}opencode" ;;
361
- "Todos") TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode" ;;
361
+ "Qwen") TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}qwen" ;;
362
+ "Todos") TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode,qwen" ;;
362
363
  esac
363
364
  done <<< "$TOOLS_RAW"
364
365
  GUM_TOOLS_OK=true
@@ -375,7 +376,8 @@ if [ "$INTERACTIVE_MODE" = true ]; then
375
376
  echo -e " ${CYAN}6)${NC} Amp (prompt.md)"
376
377
  echo -e " ${CYAN}7)${NC} Continue.dev (.continue/config/)"
377
378
  echo -e " ${CYAN}8)${NC} OpenCode (.opencode/ + @doncheli)"
378
- echo -e " ${CYAN}9)${NC} Todos"
379
+ echo -e " ${CYAN}9)${NC} Qwen (AGENTS.md + .opencode/)"
380
+ echo -e " ${CYAN}10)${NC} Todos"
379
381
  echo ""
380
382
  echo -ne " ${BOLD}▸ Elige (números separados por coma): ${NC}"
381
383
  TOOLS_CHOICE=""
@@ -396,7 +398,8 @@ if [ "$INTERACTIVE_MODE" = true ]; then
396
398
  6) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}amp" ;;
397
399
  7) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}continue" ;;
398
400
  8) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}opencode" ;;
399
- 9|all) TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode" ;;
401
+ 9) TOOLS_FLAG="${TOOLS_FLAG:+$TOOLS_FLAG,}qwen" ;;
402
+ 10|all) TOOLS_FLAG="claude,codex,cursor,antigravity,windsurf,amp,continue,opencode,qwen" ;;
400
403
  esac
401
404
  done
402
405
  fi