@the-bearded-bear/claude-craft 8.26.0 → 8.27.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.
Files changed (187) hide show
  1. package/Dev/i18n/base/Common/commands/aliases.md +48 -48
  2. package/Dev/i18n/base/Common/skills/sub-agents-patterns/SKILL.md +1 -0
  3. package/Dev/i18n/de/Common/agents/devops-engineer.md +19 -14
  4. package/Dev/i18n/de/Common/agents/migration-specialist.md +10 -15
  5. package/Dev/i18n/de/Common/agents/mlops-engineer.md +19 -15
  6. package/Dev/i18n/de/Common/agents/ralph-conductor.md +4 -15
  7. package/Dev/i18n/de/Common/agents/refactoring-specialist.md +0 -9
  8. package/Dev/i18n/de/Common/agents/tdd-coach.md +0 -9
  9. package/Dev/i18n/de/Common/agents/uiux-orchestrator.md +0 -9
  10. package/Dev/i18n/de/Common/commands/ralph-run.md +52 -0
  11. package/Dev/i18n/de/Common/commands/research-context7.md +5 -253
  12. package/Dev/i18n/de/Common/rules/12-context-management.md +10 -8
  13. package/Dev/i18n/de/Common/templates/settings.json.template +4 -0
  14. package/Dev/i18n/de/Python/skills/coding-standards/SKILL.md +1 -1
  15. package/Dev/i18n/de/Python/skills/testing-python/SKILL.md +1 -1
  16. package/Dev/i18n/de/Python/skills/tooling/SKILL.md +1 -1
  17. package/Dev/i18n/de/Symfony/commands/check-security.md +20 -20
  18. package/Dev/i18n/de/Symfony/skills/aggregates/SKILL.md +1 -1
  19. package/Dev/i18n/de/Symfony/skills/async/SKILL.md +1 -1
  20. package/Dev/i18n/de/Symfony/skills/cqrs/SKILL.md +1 -1
  21. package/Dev/i18n/de/Symfony/skills/domain-events/SKILL.md +1 -1
  22. package/Dev/i18n/de/Symfony/skills/i18n/SKILL.md +1 -1
  23. package/Dev/i18n/de/Symfony/skills/multitenant/SKILL.md +1 -1
  24. package/Dev/i18n/de/Symfony/skills/value-objects/SKILL.md +1 -1
  25. package/Dev/i18n/de/Team/commands/audit.md +29 -4
  26. package/Dev/i18n/de/Team/commands/delivery.md +29 -4
  27. package/Dev/i18n/de/Team/commands/security.md +31 -4
  28. package/Dev/i18n/de/Team/commands/sprint.md +30 -5
  29. package/Dev/i18n/de/UIUX/commands/audit.md +1 -30
  30. package/Dev/i18n/de/UIUX/commands/component-spec.md +1 -5
  31. package/Dev/i18n/de/UIUX/commands/orchestrator.md +5 -98
  32. package/Dev/i18n/de/Workflow/commands/auto-sprint.md +7 -4
  33. package/Dev/i18n/de/Workflow/commands/plan.md +1 -2
  34. package/Dev/i18n/en/Common/agents/devops-engineer.md +19 -14
  35. package/Dev/i18n/en/Common/agents/migration-specialist.md +10 -15
  36. package/Dev/i18n/en/Common/agents/mlops-engineer.md +19 -15
  37. package/Dev/i18n/en/Common/agents/ralph-conductor.md +4 -15
  38. package/Dev/i18n/en/Common/agents/refactoring-specialist.md +0 -9
  39. package/Dev/i18n/en/Common/agents/tdd-coach.md +0 -9
  40. package/Dev/i18n/en/Common/agents/uiux-orchestrator.md +0 -9
  41. package/Dev/i18n/en/Common/commands/ralph-run.md +52 -0
  42. package/Dev/i18n/en/Common/commands/research-context7.md +5 -253
  43. package/Dev/i18n/en/Common/rules/12-context-management.md +12 -10
  44. package/Dev/i18n/en/Common/templates/settings.json.template +4 -0
  45. package/Dev/i18n/en/Python/skills/coding-standards/SKILL.md +1 -1
  46. package/Dev/i18n/en/Python/skills/testing-python/SKILL.md +1 -1
  47. package/Dev/i18n/en/Python/skills/tooling/SKILL.md +1 -1
  48. package/Dev/i18n/en/Symfony/commands/check-security.md +20 -20
  49. package/Dev/i18n/en/Symfony/skills/aggregates/SKILL.md +1 -1
  50. package/Dev/i18n/en/Symfony/skills/async/SKILL.md +1 -1
  51. package/Dev/i18n/en/Symfony/skills/cqrs/SKILL.md +1 -1
  52. package/Dev/i18n/en/Symfony/skills/domain-events/SKILL.md +1 -1
  53. package/Dev/i18n/en/Symfony/skills/i18n/SKILL.md +1 -1
  54. package/Dev/i18n/en/Symfony/skills/multitenant/SKILL.md +1 -1
  55. package/Dev/i18n/en/Symfony/skills/value-objects/SKILL.md +1 -1
  56. package/Dev/i18n/en/Team/commands/audit.md +29 -4
  57. package/Dev/i18n/en/Team/commands/delivery.md +29 -4
  58. package/Dev/i18n/en/Team/commands/security.md +31 -4
  59. package/Dev/i18n/en/Team/commands/sprint.md +30 -5
  60. package/Dev/i18n/en/UIUX/commands/audit.md +1 -30
  61. package/Dev/i18n/en/UIUX/commands/component-spec.md +1 -5
  62. package/Dev/i18n/en/UIUX/commands/orchestrator.md +5 -98
  63. package/Dev/i18n/en/Workflow/commands/auto-sprint.md +7 -4
  64. package/Dev/i18n/en/Workflow/commands/plan.md +1 -2
  65. package/Dev/i18n/es/Common/agents/devops-engineer.md +19 -14
  66. package/Dev/i18n/es/Common/agents/migration-specialist.md +10 -15
  67. package/Dev/i18n/es/Common/agents/mlops-engineer.md +19 -15
  68. package/Dev/i18n/es/Common/agents/ralph-conductor.md +4 -15
  69. package/Dev/i18n/es/Common/agents/refactoring-specialist.md +0 -9
  70. package/Dev/i18n/es/Common/agents/tdd-coach.md +0 -9
  71. package/Dev/i18n/es/Common/agents/uiux-orchestrator.md +0 -9
  72. package/Dev/i18n/es/Common/commands/ralph-run.md +52 -0
  73. package/Dev/i18n/es/Common/commands/research-context7.md +5 -253
  74. package/Dev/i18n/es/Common/rules/12-context-management.md +9 -7
  75. package/Dev/i18n/es/Common/templates/settings.json.template +4 -0
  76. package/Dev/i18n/es/Python/skills/coding-standards/SKILL.md +1 -1
  77. package/Dev/i18n/es/Python/skills/testing-python/SKILL.md +1 -1
  78. package/Dev/i18n/es/Python/skills/tooling/SKILL.md +1 -1
  79. package/Dev/i18n/es/Symfony/commands/check-security.md +20 -20
  80. package/Dev/i18n/es/Symfony/skills/aggregates/SKILL.md +1 -1
  81. package/Dev/i18n/es/Symfony/skills/async/SKILL.md +1 -1
  82. package/Dev/i18n/es/Symfony/skills/cqrs/SKILL.md +1 -1
  83. package/Dev/i18n/es/Symfony/skills/domain-events/SKILL.md +1 -1
  84. package/Dev/i18n/es/Symfony/skills/i18n/SKILL.md +1 -1
  85. package/Dev/i18n/es/Symfony/skills/multitenant/SKILL.md +1 -1
  86. package/Dev/i18n/es/Symfony/skills/value-objects/SKILL.md +1 -1
  87. package/Dev/i18n/es/Team/commands/audit.md +29 -4
  88. package/Dev/i18n/es/Team/commands/delivery.md +29 -4
  89. package/Dev/i18n/es/Team/commands/security.md +31 -4
  90. package/Dev/i18n/es/Team/commands/sprint.md +30 -5
  91. package/Dev/i18n/es/UIUX/commands/audit.md +1 -30
  92. package/Dev/i18n/es/UIUX/commands/component-spec.md +1 -5
  93. package/Dev/i18n/es/UIUX/commands/orchestrator.md +5 -98
  94. package/Dev/i18n/es/Workflow/commands/auto-sprint.md +7 -4
  95. package/Dev/i18n/es/Workflow/commands/plan.md +1 -2
  96. package/Dev/i18n/fr/Common/agents/devops-engineer.md +19 -14
  97. package/Dev/i18n/fr/Common/agents/migration-specialist.md +10 -15
  98. package/Dev/i18n/fr/Common/agents/mlops-engineer.md +19 -15
  99. package/Dev/i18n/fr/Common/agents/ralph-conductor.md +4 -15
  100. package/Dev/i18n/fr/Common/agents/refactoring-specialist.md +0 -9
  101. package/Dev/i18n/fr/Common/agents/tdd-coach.md +0 -9
  102. package/Dev/i18n/fr/Common/agents/uiux-orchestrator.md +0 -9
  103. package/Dev/i18n/fr/Common/commands/ralph-run.md +52 -0
  104. package/Dev/i18n/fr/Common/commands/research-context7.md +5 -253
  105. package/Dev/i18n/fr/Common/rules/12-context-management.md +10 -8
  106. package/Dev/i18n/fr/Common/templates/settings.json.template +4 -0
  107. package/Dev/i18n/fr/React/commands/check-compliance.md +1 -1
  108. package/Dev/i18n/fr/React/commands/check-security.md +2 -2
  109. package/Dev/i18n/fr/Symfony/commands/check-security.md +20 -20
  110. package/Dev/i18n/fr/Symfony/skills/aggregates/SKILL.md +1 -1
  111. package/Dev/i18n/fr/Symfony/skills/async/SKILL.md +1 -1
  112. package/Dev/i18n/fr/Symfony/skills/cqrs/SKILL.md +1 -1
  113. package/Dev/i18n/fr/Symfony/skills/domain-events/SKILL.md +1 -1
  114. package/Dev/i18n/fr/Symfony/skills/i18n/SKILL.md +1 -1
  115. package/Dev/i18n/fr/Symfony/skills/multitenant/SKILL.md +1 -1
  116. package/Dev/i18n/fr/Symfony/skills/value-objects/SKILL.md +1 -1
  117. package/Dev/i18n/fr/Team/commands/audit.md +29 -4
  118. package/Dev/i18n/fr/Team/commands/delivery.md +29 -4
  119. package/Dev/i18n/fr/Team/commands/security.md +31 -4
  120. package/Dev/i18n/fr/Team/commands/sprint.md +30 -5
  121. package/Dev/i18n/fr/UIUX/commands/audit.md +1 -30
  122. package/Dev/i18n/fr/UIUX/commands/component-spec.md +1 -5
  123. package/Dev/i18n/fr/UIUX/commands/orchestrator.md +5 -98
  124. package/Dev/i18n/fr/Workflow/commands/auto-sprint.md +7 -4
  125. package/Dev/i18n/fr/Workflow/commands/plan.md +1 -2
  126. package/Dev/i18n/pt/Common/agents/devops-engineer.md +19 -14
  127. package/Dev/i18n/pt/Common/agents/migration-specialist.md +10 -15
  128. package/Dev/i18n/pt/Common/agents/mlops-engineer.md +19 -15
  129. package/Dev/i18n/pt/Common/agents/ralph-conductor.md +4 -15
  130. package/Dev/i18n/pt/Common/agents/refactoring-specialist.md +0 -9
  131. package/Dev/i18n/pt/Common/agents/tdd-coach.md +0 -9
  132. package/Dev/i18n/pt/Common/agents/uiux-orchestrator.md +0 -9
  133. package/Dev/i18n/pt/Common/commands/ralph-run.md +52 -0
  134. package/Dev/i18n/pt/Common/commands/research-context7.md +5 -253
  135. package/Dev/i18n/pt/Common/rules/12-context-management.md +9 -7
  136. package/Dev/i18n/pt/Common/templates/settings.json.template +4 -0
  137. package/Dev/i18n/pt/Python/skills/coding-standards/SKILL.md +1 -1
  138. package/Dev/i18n/pt/Python/skills/testing-python/SKILL.md +1 -1
  139. package/Dev/i18n/pt/Python/skills/tooling/SKILL.md +1 -1
  140. package/Dev/i18n/pt/Symfony/commands/check-security.md +20 -20
  141. package/Dev/i18n/pt/Symfony/skills/aggregates/SKILL.md +1 -1
  142. package/Dev/i18n/pt/Symfony/skills/async/SKILL.md +1 -1
  143. package/Dev/i18n/pt/Symfony/skills/cqrs/SKILL.md +1 -1
  144. package/Dev/i18n/pt/Symfony/skills/domain-events/SKILL.md +1 -1
  145. package/Dev/i18n/pt/Symfony/skills/i18n/SKILL.md +1 -1
  146. package/Dev/i18n/pt/Symfony/skills/multitenant/SKILL.md +1 -1
  147. package/Dev/i18n/pt/Symfony/skills/value-objects/SKILL.md +1 -1
  148. package/Dev/i18n/pt/Team/commands/audit.md +29 -4
  149. package/Dev/i18n/pt/Team/commands/delivery.md +29 -4
  150. package/Dev/i18n/pt/Team/commands/security.md +31 -4
  151. package/Dev/i18n/pt/Team/commands/sprint.md +30 -5
  152. package/Dev/i18n/pt/UIUX/commands/audit.md +1 -30
  153. package/Dev/i18n/pt/UIUX/commands/component-spec.md +1 -5
  154. package/Dev/i18n/pt/UIUX/commands/orchestrator.md +5 -98
  155. package/Dev/i18n/pt/Workflow/commands/auto-sprint.md +7 -4
  156. package/Dev/i18n/pt/Workflow/commands/plan.md +1 -2
  157. package/Dev/scripts/install-common-rules.sh +8 -0
  158. package/README.md +12 -8
  159. package/Tools/Ralph/lib/checkpoint.sh +3 -3
  160. package/Tools/Ralph/lib/circuit-breaker.sh +10 -10
  161. package/Tools/Ralph/lib/context-manager.sh +56 -65
  162. package/Tools/Ralph/lib/context-reconstruction.sh +46 -79
  163. package/Tools/Ralph/lib/dod-templates.sh +2 -2
  164. package/Tools/Ralph/lib/dod-validator.sh +18 -18
  165. package/Tools/Ralph/lib/escalation-service.sh +9 -7
  166. package/Tools/Ralph/lib/hooks-generator.sh +2 -1
  167. package/Tools/Ralph/lib/loop-finalizer.sh +1 -1
  168. package/Tools/Ralph/lib/loop.sh +44 -10
  169. package/Tools/Ralph/lib/metrics-exporter.sh +1 -1
  170. package/Tools/Ralph/lib/parallel-manager.sh +173 -88
  171. package/Tools/Ralph/lib/project-detector.sh +3 -3
  172. package/Tools/Ralph/lib/recovery-engine.sh +8 -8
  173. package/Tools/Ralph/lib/session.sh +2 -2
  174. package/Tools/Ralph/lib/sprint-conductor.sh +167 -124
  175. package/Tools/Ralph/lib/sprint-progress.sh +9 -9
  176. package/Tools/Ralph/ralph.sh +66 -38
  177. package/Tools/StatusLine/statusline.sh +0 -0
  178. package/Tools/i18n/ralph/de.sh +165 -33
  179. package/Tools/i18n/ralph/en.sh +132 -0
  180. package/Tools/i18n/ralph/es.sh +209 -77
  181. package/Tools/i18n/ralph/fr.sh +234 -102
  182. package/Tools/i18n/ralph/pt.sh +227 -95
  183. package/bundles/cursor/.cursorrules +3 -3
  184. package/bundles/windsurf/.windsurfrules +3 -3
  185. package/cli/lib/doctor.js +1 -1
  186. package/config/removed-commands.yaml +61 -1
  187. package/package.json +1 -1
package/README.md CHANGED
@@ -26,7 +26,11 @@ Plus **11 stack-specific reviewers** (@symfony-reviewer, @react-reviewer, @pytho
26
26
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
27
27
  [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2FTheBeardedBearSAS%2Fclaude-craft%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/TheBeardedBearSAS/claude-craft/main)
28
28
 
29
- A comprehensive framework for AI-assisted development with [Claude Code](https://claude.ai/code). Install standardized rules, agents, and commands for your projects across multiple technology stacks — **33 specialized agents (+39 infra agents on-demand), 139 commands across 17 namespaces (238 total, including deprecated redirect stubs kept until 9.0), 55 skills**, all token-optimized via `context: fork` and sub-agent model routing.
29
+ A comprehensive framework for AI-assisted development with [Claude Code](https://claude.ai/code). Install standardized rules, agents, and commands for your projects across multiple technology stacks — **33 specialized agents (+39 infra agents on-demand), 140 commands across 18 namespaces (238 total, including deprecated redirect stubs kept until 9.0), 55 skills**, all token-optimized via `context: fork` and sub-agent model routing.
30
+
31
+ ## What's New in v8.27.0
32
+
33
+ **Les commandes `/team:*` sans Agent Teams (2026-10-28, v8.27.0) :** `/team:audit`, `/team:security`, `/team:sprint` et `/team:delivery` délèguent par défaut à des sous-agents (`--engine=subagents`, compatible `claude -p` et CI) ; Agent Teams devient optionnel (`--engine=teams`, repli automatique si `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` est absent). `/common:research-context7` et `/uiux:orchestrator` sont dépréciées au profit du MCP context7 / `/deep-research` et de l'agent `@uiux-orchestrator`. Ralph est fiabilisé en mode parallèle (sessions et worktrees isolés). Claude Code recommandé : 2.1.312. Dernière version 8.x avant la 9.0. Détails : [CHANGELOG](CHANGELOG.md#8270---2026-10-28).
30
34
 
31
35
  ## What's New in v8.26.0
32
36
 
@@ -69,7 +73,7 @@ A comprehensive framework for AI-assisted development with [Claude Code](https:/
69
73
 
70
74
  - **Sécurité** : classement OWASP Top 10:2025 officiel (A01–A10) dans la règle 11 et ses miroirs, avec test de régression ; FrankenPHP 1.13.0 et PgBouncer 1.26.0 (versions précédentes vulnérables) ; types de serveurs Hetzner et `datacenter` retirés corrigés.
71
75
  - **Versions vérifiées sur registres** : React 19.3, Flutter 3.47, React Native 0.87 / Expo 57, Pinia 4, Vite 8.3 (`rolldownOptions`), Vercel CLI 63, Python 3.15, Paperclip 2026.1012.0, Docker 29.9, Kubernetes 1.37 (Gateway API), Vitest 5, Pest 5, pytest 9, PER-CS 3.0.
72
- - **Claude Code** : minimum 2.1.260, recommandé 2.1.296, modèles 5.5. Détails : [CHANGELOG](CHANGELOG.md#8230---2026-10-13).
76
+ - **Claude Code** : minimum 2.1.260, recommandé 2.1.312, modèles 5.5. Détails : [CHANGELOG](CHANGELOG.md#8230---2026-10-13).
73
77
 
74
78
  ## What's New in v8.18.0
75
79
 
@@ -147,8 +151,8 @@ A comprehensive framework for AI-assisted development with [Claude Code](https:/
147
151
  - **MIT-only strict (v8.8.0)** -- Claude Craft est 100 % open-source MIT, aucune licence commerciale ou enterprise. Stratégie open-core abandonnée.
148
152
  - **Parité i18n stricte (v8.8.2)** -- la CI bloque désormais si un fichier traduit est à < 80 % de la taille de l'anglais. Dette i18n résorbée (gap 101 → 0).
149
153
  - **Branding the-bearded-bear.com (v8.10.1)** -- migration complète des domaines vers `the-bearded-bear.com`, normalisation de l'organisation GitHub.
150
- - **126 commandes sur 15 namespaces** (220 total avec infra/projet) -- namespace `/paperclip:*` (8 commandes) ajouté, 55 skills disponibles.
151
- - **Claude Code 2.1.296** -- version recommandée (minimum sécurité 2.1.260 ; Opus 5.5 / Sonnet 5.5 / Haiku 5.5, MCP 2026-07-28, hooks `onFailure: "block"`).
154
+ - **126 commandes sur 15 namespaces (v8.10.x)** (220 total avec infra/projet) -- namespace `/paperclip:*` (8 commandes) ajouté, 55 skills disponibles.
155
+ - **Claude Code 2.1.312** -- version recommandée (minimum sécurité 2.1.260 ; Opus 5.5 / Sonnet 5.5 / Haiku 5.5, MCP 2026-07-28, hooks `onFailure: "block"`).
152
156
 
153
157
  > ← Versions antérieures (v8.0 → v8.7) : voir le [CHANGELOG](CHANGELOG.md) et [.claude/COMPATIBILITY.md](.claude/COMPATIBILITY.md).
154
158
 
@@ -187,7 +191,7 @@ Claude Code is powerful on its own. Claude Craft makes it **consistent and team-
187
191
 
188
192
  - **Standardized rules** -- SOLID, Clean Architecture, TDD enforced across your team, not just suggested
189
193
  - **33 default agents + 39 infra agents on-demand** -- reviewers, architects, coaches that know your stack deeply (72 total potentially installable)
190
- - **139 slash commands across 17 namespaces** -- repeatable workflows for audits, code generation, sprint management
194
+ - **140 slash commands across 18 namespaces** -- repeatable workflows for audits, code generation, sprint management
191
195
  - **Quality gates** -- automated checks at every stage from PRD to deployment
192
196
  - **5 languages** -- English, French, Spanish, German, Portuguese
193
197
 
@@ -225,7 +229,7 @@ See [Technologies](docs/TECHNOLOGIES.md) for full details.
225
229
  | Category | Count | Examples |
226
230
  |----------|-------|---------|
227
231
  | **Agents** | 31 default (+ 39 infra on-demand) | `@tdd-coach`, `@api-designer`, `@symfony-reviewer`, `@kubernetes-architect`, `@hcloud-architect` |
228
- | **Commands** | 126 across 15 namespaces (220 total with infra/project) | `/workflow:init`, `/team:audit`, `/react:generate-component` |
232
+ | **Commands** | 140 across 18 namespaces (238 total with infra/project) | `/workflow:init`, `/team:audit`, `/react:generate-component` |
229
233
  | **Skills** | 55 | Architecture, testing, security, DDD best practices |
230
234
  | **Templates** | 21 | Code generation patterns, BMAD project templates |
231
235
  | **Checklists** | 10 | Commit, feature, release quality gates |
@@ -267,7 +271,7 @@ These are the commands you'll use most:
267
271
  | `/common:ralph-run "task"` | Run Claude in continuous loop until task is done |
268
272
  | `/qa:recette` | Automated acceptance testing via Chrome |
269
273
 
270
- See [CLI Reference](docs/CLI-REFERENCE.md) for all 126 commands across 15 core namespaces (220 total including infra and project management).
274
+ See [CLI Reference](docs/CLI-REFERENCE.md) for all 140 commands across 18 namespaces (238 total including infra, project management and deprecated redirect stubs kept until 9.0).
271
275
 
272
276
  ## Installation
273
277
 
@@ -350,7 +354,7 @@ Context usage is optimized: ~3,500 tokens always loaded vs ~70,000 if everything
350
354
  | [Installation](docs/INSTALLATION.md) | All installation methods |
351
355
  | [Configuration](docs/CONFIGURATION.md) | Project configuration |
352
356
  | [CLI Reference](docs/CLI-REFERENCE.md) | Full CLI documentation |
353
- | [Commands](docs/COMMANDS.md) | All 126 commands |
357
+ | [Commands](docs/COMMANDS.md) | All 140 commands |
354
358
  | [Agents](docs/AGENTS.md) | All 31 default agents (+ 39 infra on-demand) |
355
359
  | [Skills](docs/SKILLS.md) | Best practices reference |
356
360
  | [Technologies](docs/TECHNOLOGIES.md) | Stack-specific guides |
@@ -207,12 +207,12 @@ list_checkpoints() {
207
207
 
208
208
  # Find commits matching the checkpoint pattern
209
209
  local commits
210
- commits=$(git log --oneline --grep="checkpoint: Ralph" 2>/dev/null | head -20)
210
+ commits=$(git log --oneline --grep="checkpoint: Ralph" 2>/dev/null | head -20) || true
211
211
 
212
212
  if [[ -n "$commits" ]]; then
213
213
  echo "$commits" | while read -r line; do
214
- local hash=$(echo "$line" | cut -d' ' -f1)
215
- local msg=$(echo "$line" | cut -d' ' -f2-)
214
+ local hash=$(echo "$line" | cut -d' ' -f1) || true
215
+ local msg=$(echo "$line" | cut -d' ' -f2-) || true
216
216
  echo "{\"hash\":\"$hash\",\"message\":\"$msg\"}"
217
217
  done | jq -s '.'
218
218
  else
@@ -30,35 +30,35 @@ CB_LEARNING_MIN_SAMPLES=5
30
30
  # =============================================================================
31
31
  # Each profile defines thresholds optimized for different task types
32
32
 
33
- declare -A CB_PROFILE_QUICK_FIX=(
33
+ declare -gA CB_PROFILE_QUICK_FIX=(
34
34
  ["no_changes"]=2
35
35
  ["errors"]=3
36
36
  ["max_iterations"]=10
37
37
  ["keywords"]="fix bug typo hotfix patch"
38
38
  )
39
39
 
40
- declare -A CB_PROFILE_SMALL_FEATURE=(
40
+ declare -gA CB_PROFILE_SMALL_FEATURE=(
41
41
  ["no_changes"]=3
42
42
  ["errors"]=4
43
43
  ["max_iterations"]=15
44
44
  ["keywords"]="add implement small simple"
45
45
  )
46
46
 
47
- declare -A CB_PROFILE_MEDIUM_FEATURE=(
47
+ declare -gA CB_PROFILE_MEDIUM_FEATURE=(
48
48
  ["no_changes"]=4
49
49
  ["errors"]=6
50
50
  ["max_iterations"]=25
51
51
  ["keywords"]="feature create with tests"
52
52
  )
53
53
 
54
- declare -A CB_PROFILE_LARGE_FEATURE=(
54
+ declare -gA CB_PROFILE_LARGE_FEATURE=(
55
55
  ["no_changes"]=5
56
56
  ["errors"]=8
57
57
  ["max_iterations"]=50
58
58
  ["keywords"]="refactor migrate complex large"
59
59
  )
60
60
 
61
- declare -A CB_PROFILE_EXPLORATION=(
61
+ declare -gA CB_PROFILE_EXPLORATION=(
62
62
  ["no_changes"]=10
63
63
  ["errors"]=15
64
64
  ["max_iterations"]=100
@@ -66,7 +66,7 @@ declare -A CB_PROFILE_EXPLORATION=(
66
66
  )
67
67
 
68
68
  # Autonomous profile for overnight/unattended runs
69
- declare -A CB_PROFILE_AUTONOMOUS=(
69
+ declare -gA CB_PROFILE_AUTONOMOUS=(
70
70
  ["no_changes"]=5
71
71
  ["errors"]=8
72
72
  ["max_iterations"]=50
@@ -162,7 +162,7 @@ init_circuit_breaker() {
162
162
  detect_task_profile() {
163
163
  local prompt="$1"
164
164
  local prompt_lower
165
- prompt_lower=$(echo "$prompt" | tr '[:upper:]' '[:lower:]')
165
+ prompt_lower=$(echo "$prompt" | tr '[:upper:]' '[:lower:]') || true
166
166
 
167
167
  # Check each profile's keywords
168
168
  local profiles=("quick_fix" "small_feature" "medium_feature" "large_feature" "exploration" "autonomous")
@@ -265,7 +265,7 @@ apply_learned_adjustments() {
265
265
  ' "$history_file" 2>/dev/null)
266
266
 
267
267
  local samples
268
- samples=$(echo "$profile_data" | jq -r '.samples // 0')
268
+ samples=$(echo "$profile_data" | jq -r '.samples // 0') || samples=0
269
269
 
270
270
  if [[ $samples -lt $CB_LEARNING_MIN_SAMPLES ]]; then
271
271
  print_verbose "Not enough samples for learning ($samples < $CB_LEARNING_MIN_SAMPLES)"
@@ -274,10 +274,10 @@ apply_learned_adjustments() {
274
274
 
275
275
  # Apply adjustments based on historical success rate
276
276
  local success_rate
277
- success_rate=$(echo "$profile_data" | jq -r '.success_rate // 0')
277
+ success_rate=$(echo "$profile_data" | jq -r '.success_rate // 0') || success_rate=0
278
278
 
279
279
  local avg_iterations
280
- avg_iterations=$(echo "$profile_data" | jq -r '.avg_iterations // 0')
280
+ avg_iterations=$(echo "$profile_data" | jq -r '.avg_iterations // 0') || avg_iterations=0
281
281
 
282
282
  # If success rate is low, increase thresholds
283
283
  if [[ $success_rate -lt 50 ]]; then
@@ -32,6 +32,9 @@ IFS=' ' read -r -a CLAUDE_CMD <<< "$CLAUDE_COMMAND"
32
32
  CONTEXT_COMPACT_COUNT=0
33
33
  CONTEXT_CONTINUATION_COUNT=0
34
34
  CONTEXT_CONTINUATION_PROMPT=""
35
+ # Set by run_auto_compact (return 3) / handle_max_compacts_reached: call them
36
+ # in this shell, never in `$(...)`, or the counters above are lost.
37
+ CONTEXT_NEW_SESSION_ID=""
35
38
 
36
39
  # =============================================================================
37
40
  # Context Limit Detection
@@ -106,6 +109,17 @@ init_context_manager() {
106
109
  print_verbose " - Smart reconstruction: $CONTEXT_SMART_RECONSTRUCTION"
107
110
  }
108
111
 
112
+ # Print the first lines of `/context` for a Claude session UUID.
113
+ # Best effort: prints nothing on failure, always succeeds (set -e safe).
114
+ probe_context_usage() {
115
+ local claude_uuid="$1"
116
+ if command -v timeout &> /dev/null; then
117
+ timeout 10s "${CLAUDE_CMD[@]}" --resume "$claude_uuid" -p "/context" 2>/dev/null | head -5 || true
118
+ else
119
+ "${CLAUDE_CMD[@]}" --resume "$claude_uuid" -p "/context" 2>/dev/null | head -5 || true
120
+ fi
121
+ }
122
+
109
123
  # =============================================================================
110
124
  # Auto-Compact
111
125
  # =============================================================================
@@ -120,20 +134,27 @@ run_auto_compact() {
120
134
  return 1
121
135
  fi
122
136
 
137
+ # /context and /compact must target this Ralph session's Claude session,
138
+ # never "the most recent conversation in this directory" (--continue).
139
+ local claude_uuid
140
+ claude_uuid=$(get_claude_session_uuid "$session_id")
141
+ if [[ -z "$claude_uuid" ]]; then
142
+ log_session "$session_id" "WARN" "No Claude session yet, nothing to compact"
143
+ return 1
144
+ fi
145
+
123
146
  # Check if context is above minimum threshold before compacting
124
147
  if [[ "$CONTEXT_MIN_THRESHOLD" -gt 0 ]]; then
125
148
  local context_info
126
- if command -v timeout &> /dev/null; then
127
- context_info=$(timeout 10s "${CLAUDE_CMD[@]}" -p "/context" 2>/dev/null | head -5)
128
- else
129
- context_info=$("${CLAUDE_CMD[@]}" -p "/context" 2>/dev/null | head -5)
130
- fi
149
+ context_info=$(probe_context_usage "$claude_uuid")
131
150
  local current_usage
132
- current_usage=$(echo "$context_info" | grep -oP '\d+(?=%)' | head -1)
151
+ current_usage=$(echo "$context_info" | grep -oP '\d+(?=%)' | head -1 || true)
133
152
 
134
153
  if [[ -n "$current_usage" && "$current_usage" -lt "$CONTEXT_MIN_THRESHOLD" ]]; then
135
154
  log_session "$session_id" "INFO" "Context at ${current_usage}% - below minimum threshold (${CONTEXT_MIN_THRESHOLD}%), skipping compact"
136
- print_verbose "Context at ${current_usage}% - below min threshold (${CONTEXT_MIN_THRESHOLD}%), skipping compact"
155
+ local msg="${MSG_CONTEXT_BELOW_MIN:-"Context at {0}% - below minimum threshold ({1}%), skipping compact"}"
156
+ msg="${msg//\{0\}/"$current_usage"}"
157
+ print_verbose "${msg//\{1\}/"$CONTEXT_MIN_THRESHOLD"}"
137
158
  return 1
138
159
  fi
139
160
  fi
@@ -144,13 +165,12 @@ run_auto_compact() {
144
165
  print_warning "${MSG_CONTEXT_MAX_REACHED:-Maximum compacts reached} ($CONTEXT_MAX_COMPACTS)"
145
166
 
146
167
  # Handle overflow strategy
147
- local overflow_result
148
- overflow_result=$(handle_max_compacts_reached "$session_id")
149
- local overflow_status=$?
168
+ local overflow_status=0
169
+ CONTEXT_NEW_SESSION_ID=""
170
+ handle_max_compacts_reached "$session_id" || overflow_status=$?
150
171
 
151
- if [[ $overflow_status -eq 0 && -n "$overflow_result" ]]; then
152
- # New session ID returned - signal continuation
153
- echo "$overflow_result"
172
+ if [[ $overflow_status -eq 0 && -n "$CONTEXT_NEW_SESSION_ID" ]]; then
173
+ # New session ID in CONTEXT_NEW_SESSION_ID - signal continuation
154
174
  return 3 # Special return code for session continuation
155
175
  fi
156
176
 
@@ -185,11 +205,10 @@ run_auto_compact() {
185
205
 
186
206
  # Execute /compact via Claude CLI
187
207
  local compact_output
188
- local compact_status
208
+ local compact_status=0
189
209
 
190
210
  if command -v timeout &> /dev/null; then
191
- compact_output=$(timeout 60s "${CLAUDE_CMD[@]}" --continue -p "/compact" 2>&1)
192
- compact_status=$?
211
+ compact_output=$(timeout 60s "${CLAUDE_CMD[@]}" --resume "$claude_uuid" -p "/compact" 2>&1) || compact_status=$?
193
212
 
194
213
  # Handle timeout specifically (exit code 124)
195
214
  if [[ $compact_status -eq 124 ]]; then
@@ -198,8 +217,7 @@ run_auto_compact() {
198
217
  return 1
199
218
  fi
200
219
  else
201
- compact_output=$("${CLAUDE_CMD[@]}" --continue -p "/compact" 2>&1)
202
- compact_status=$?
220
+ compact_output=$("${CLAUDE_CMD[@]}" --resume "$claude_uuid" -p "/compact" 2>&1) || compact_status=$?
203
221
  fi
204
222
 
205
223
  if [[ $compact_status -eq 0 ]]; then
@@ -313,10 +331,12 @@ handle_max_compacts_reached() {
313
331
  new_session_id=$(create_continuation_session "$session_id")
314
332
 
315
333
  if [[ -n "$new_session_id" ]]; then
334
+ # Reset here: create_continuation_session ran in a subshell
335
+ CONTEXT_COMPACT_COUNT=0
316
336
  CONTEXT_CONTINUATION_COUNT=$((CONTEXT_CONTINUATION_COUNT + 1))
317
337
  print_success "${MSG_CONTEXT_CONTINUATION_CREATED:-Continuation session created}: $new_session_id"
318
338
  log_session "$session_id" "INFO" "Created continuation session: $new_session_id"
319
- echo "$new_session_id"
339
+ CONTEXT_NEW_SESSION_ID="$new_session_id"
320
340
  return 0
321
341
  else
322
342
  print_error "Failed to create continuation session"
@@ -349,30 +369,11 @@ handle_max_compacts_reached() {
349
369
  create_continuation_session() {
350
370
  local previous_session="$1"
351
371
 
352
- # Generate new session ID with portable random suffix generation
353
- local timestamp=$(date +%Y%m%d_%H%M%S)
354
- local random_suffix
355
-
356
- # Use utils function if available, otherwise fallback
357
- if type generate_random_suffix &>/dev/null; then
358
- random_suffix=$(generate_random_suffix 4)
359
- elif command -v xxd &>/dev/null; then
360
- random_suffix=$(head -c 4 /dev/urandom | xxd -p)
361
- elif command -v od &>/dev/null; then
362
- random_suffix=$(head -c 4 /dev/urandom | od -An -tx1 | tr -d ' \n')
363
- else
364
- # Fallback: use $RANDOM (less entropy but portable)
365
- random_suffix=$(printf '%04x%04x' $RANDOM $RANDOM | head -c 8)
366
- fi
367
-
368
- local new_session_id="ralph-cont-${timestamp}-${random_suffix}"
369
-
370
- # Create session directory if create_session is available
371
- if type create_session &>/dev/null; then
372
- if ! create_session "$new_session_id" 2>/dev/null; then
373
- print_warning "Failed to create session directory for $new_session_id"
374
- fi
375
- fi
372
+ # create_session takes a prompt and prints the id it created (with its
373
+ # state.json and session.log): the id must come from it, or the session
374
+ # directory is an orphan and the continuation id has no state.
375
+ local new_session_id
376
+ new_session_id=$(create_session "Continuation of $previous_session") || return 1
376
377
 
377
378
  # Link sessions in state files (with error handling)
378
379
  if type update_session_state &>/dev/null; then
@@ -385,10 +386,6 @@ create_continuation_session() {
385
386
  link_session_to_progress "$new_session_id" || print_verbose "Failed to link session to progress"
386
387
  fi
387
388
 
388
- # Reset context manager for new session
389
- CONTEXT_COMPACT_COUNT=0
390
- CONTEXT_CONTINUATION_COUNT=$((CONTEXT_CONTINUATION_COUNT)) # Keep continuation count
391
-
392
389
  echo "$new_session_id"
393
390
  }
394
391
 
@@ -404,26 +401,28 @@ check_preventive_compact() {
404
401
  return 1
405
402
  fi
406
403
 
404
+ # Nothing to measure before the first Claude call of this session.
405
+ local claude_uuid
406
+ claude_uuid=$(get_claude_session_uuid "$session_id")
407
+ [[ -z "$claude_uuid" ]] && return 1
408
+
407
409
  # Try to get context usage from Claude CLI
408
410
  # Note: This is a best-effort check, Claude may not always report usage
409
411
  local context_info
410
- if command -v timeout &> /dev/null; then
411
- context_info=$(timeout 10s "${CLAUDE_CMD[@]}" -p "/context" 2>/dev/null | head -5)
412
- else
413
- context_info=$("${CLAUDE_CMD[@]}" -p "/context" 2>/dev/null | head -5)
414
- fi
412
+ context_info=$(probe_context_usage "$claude_uuid")
415
413
 
416
414
  # Try to extract percentage from output
417
415
  local usage
418
- usage=$(echo "$context_info" | grep -oP '\d+(?=%)' | head -1)
416
+ usage=$(echo "$context_info" | grep -oP '\d+(?=%)' | head -1 || true)
419
417
 
420
418
  if [[ -n "$usage" && "$usage" -ge "$CONTEXT_PREVENTIVE_THRESHOLD" ]]; then
421
- print_warning "${MSG_CONTEXT_PREVENTIVE:-Context at ${usage}% - running preventive compact}"
419
+ local msg="${MSG_CONTEXT_PREVENTIVE:-Context at ${usage}% - running preventive compact}"
420
+ print_warning "${msg//\{0\}/$usage}"
422
421
  log_session "$session_id" "INFO" "Preventive compact triggered at ${usage}%"
423
422
 
424
423
  # Save progress before preventive compact
425
424
  if type save_sprint_progress &>/dev/null; then
426
- save_sprint_progress "$session_id"
425
+ save_sprint_progress "$session_id" || print_verbose "No sprint progress file to save"
427
426
  fi
428
427
 
429
428
  run_auto_compact "$session_id"
@@ -437,23 +436,15 @@ check_preventive_compact() {
437
436
  # Context Continuation Prompt
438
437
  # =============================================================================
439
438
 
439
+ # Print the continuation prompt stored by a real compaction, if any.
440
+ # Callers using `$(...)` must reset CONTEXT_CONTINUATION_PROMPT themselves.
440
441
  get_context_continuation_prompt() {
441
- # Return the stored continuation prompt if available
442
442
  if [[ -n "$CONTEXT_CONTINUATION_PROMPT" ]]; then
443
443
  echo "$CONTEXT_CONTINUATION_PROMPT"
444
- # Clear after use
445
444
  CONTEXT_CONTINUATION_PROMPT=""
446
445
  return 0
447
446
  fi
448
447
 
449
- # Generate fresh if smart reconstruction is enabled
450
- if [[ "$CONTEXT_SMART_RECONSTRUCTION" == "true" ]]; then
451
- if type generate_continuation_prompt &>/dev/null; then
452
- generate_continuation_prompt
453
- return 0
454
- fi
455
- fi
456
-
457
448
  return 1
458
449
  }
459
450
 
@@ -56,71 +56,75 @@ reconstruct_context() {
56
56
  # Section Builders
57
57
  # =============================================================================
58
58
 
59
+ # Headings and sentences come from Tools/i18n/ralph/<lang>.sh (MSG_SECTION_*):
60
+ # these sections are sent to Claude and must follow --lang.
61
+
59
62
  build_progress_section() {
60
- echo "## Sprint Progress"
63
+ echo "${MSG_SECTION_PROGRESS:-## Sprint Progress}"
61
64
  echo ""
62
65
 
63
66
  if [[ -f "$SPRINT_PROGRESS_FILE" ]]; then
64
67
  # Extract key sections only (not the entire file)
65
- echo "### Current State"
66
- grep -A4 "^## Current State" "$SPRINT_PROGRESS_FILE" 2>/dev/null | tail -n +2 || echo "- Unknown"
68
+ echo "${MSG_SECTION_CURRENT_STATE:-### Current State}"
69
+ grep -A4 "^## Current State" "$SPRINT_PROGRESS_FILE" 2>/dev/null | tail -n +2 || echo "- ${MSG_SECTION_UNKNOWN:-Unknown}"
67
70
 
68
71
  echo ""
69
- echo "### Completed Tasks"
72
+ echo "${MSG_SECTION_COMPLETED_TASKS:-### Completed Tasks}"
70
73
  # Show last 5 completed tasks
71
- grep '^\- \[x\]' "$SPRINT_PROGRESS_FILE" 2>/dev/null | tail -5 || echo "- None yet"
74
+ grep '^\- \[x\]' "$SPRINT_PROGRESS_FILE" 2>/dev/null | tail -5 || echo "- ${MSG_SECTION_NONE_YET:-None yet}"
72
75
 
73
76
  echo ""
74
- echo "### Key Decisions"
75
- grep -A10 "^## Key Decisions" "$SPRINT_PROGRESS_FILE" 2>/dev/null | grep '^-' | head -5 || echo "- None recorded"
77
+ echo "${MSG_SECTION_KEY_DECISIONS:-### Key Decisions}"
78
+ grep -A10 "^## Key Decisions" "$SPRINT_PROGRESS_FILE" 2>/dev/null | grep '^-' | head -5 || echo "- ${MSG_SECTION_NONE_RECORDED:-None recorded}"
76
79
  else
77
- echo "No sprint progress file found."
80
+ echo "${MSG_SECTION_NO_PROGRESS_FILE:-No sprint progress file found.}"
78
81
  fi
79
82
  }
80
83
 
81
84
  build_git_section() {
82
- echo "## Recent Changes"
85
+ echo "${MSG_SECTION_GIT:-## Recent Changes}"
83
86
  echo ""
84
87
 
85
88
  # Check if we're in a git repository
86
89
  if ! git rev-parse --git-dir > /dev/null 2>&1; then
87
- echo "Not in a git repository."
90
+ echo "${MSG_SECTION_NOT_GIT:-Not in a git repository.}"
88
91
  return
89
92
  fi
90
93
 
91
94
  # Get summary of changes - check commit count first
92
- echo "### Modified Files (recent commits)"
95
+ echo "${MSG_SECTION_MODIFIED_FILES:-### Modified Files (recent commits)}"
93
96
  local commit_count
94
97
  commit_count=$(git rev-list --count HEAD 2>/dev/null || echo "0")
95
98
 
99
+ local no_changes="${MSG_SECTION_NO_RECENT_CHANGES:-No recent changes}"
96
100
  if [[ "$commit_count" -ge 5 ]]; then
97
- git diff --stat HEAD~5 2>/dev/null | tail -15 || echo "No recent changes"
101
+ git diff --stat HEAD~5 2>/dev/null | tail -15 || echo "$no_changes"
98
102
  elif [[ "$commit_count" -gt 0 ]]; then
99
103
  # Show diff from initial commit if less than 5 commits
100
- git diff --stat "$(git rev-list --max-parents=0 HEAD 2>/dev/null)" 2>/dev/null | tail -15 || echo "No recent changes"
104
+ git diff --stat "$(git rev-list --max-parents=0 HEAD 2>/dev/null)" 2>/dev/null | tail -15 || echo "$no_changes"
101
105
  else
102
- echo "No commits yet"
106
+ echo "${MSG_SECTION_NO_COMMITS:-No commits yet}"
103
107
  fi
104
108
 
105
109
  echo ""
106
- echo "### Recent Commits"
107
- git log --oneline -5 2>/dev/null || echo "No commits found"
110
+ echo "${MSG_SECTION_RECENT_COMMITS:-### Recent Commits}"
111
+ git log --oneline -5 2>/dev/null || echo "${MSG_SECTION_NO_COMMITS:-No commits yet}"
108
112
 
109
113
  echo ""
110
- echo "### Uncommitted Changes"
114
+ echo "${MSG_SECTION_UNCOMMITTED:-### Uncommitted Changes}"
111
115
  local status
112
- status=$(git status --porcelain 2>/dev/null | head -10)
116
+ status=$(git status --porcelain 2>/dev/null | head -10) || true
113
117
  if [[ -n "$status" ]]; then
114
118
  echo "\`\`\`"
115
119
  echo "$status"
116
120
  echo "\`\`\`"
117
121
  else
118
- echo "No uncommitted changes."
122
+ echo "${MSG_SECTION_NO_UNCOMMITTED:-No uncommitted changes.}"
119
123
  fi
120
124
  }
121
125
 
122
126
  build_test_section() {
123
- echo "## Test Status"
127
+ echo "${MSG_SECTION_TESTS:-## Test Status}"
124
128
  echo ""
125
129
 
126
130
  # Try to detect test framework
@@ -149,7 +153,7 @@ build_test_section() {
149
153
  fi
150
154
 
151
155
  if [[ "$framework_detected" == "false" ]]; then
152
- echo "- Framework: Unknown"
156
+ echo "- Framework: ${MSG_SECTION_UNKNOWN:-Unknown}"
153
157
  fi
154
158
 
155
159
  # Check sprint progress for recorded test status
@@ -158,13 +162,13 @@ build_test_section() {
158
162
  unit_status=$(grep -oP 'Unit: \K.*' "$SPRINT_PROGRESS_FILE" 2>/dev/null || echo "unknown")
159
163
  local integration_status
160
164
  integration_status=$(grep -oP 'Integration: \K.*' "$SPRINT_PROGRESS_FILE" 2>/dev/null || echo "unknown")
161
- echo "- Unit Tests: $unit_status"
162
- echo "- Integration Tests: $integration_status"
165
+ echo "- ${MSG_SECTION_UNIT_TESTS:-Unit Tests}: $unit_status"
166
+ echo "- ${MSG_SECTION_INTEGRATION_TESTS:-Integration Tests}: $integration_status"
163
167
  fi
164
168
  }
165
169
 
166
170
  build_current_task_section() {
167
- echo "## Current Task"
171
+ echo "${MSG_SECTION_TASK:-## Current Task}"
168
172
  echo ""
169
173
 
170
174
  # Check for current task file
@@ -179,15 +183,16 @@ build_current_task_section() {
179
183
  local phase=$(grep -oP '\*\*Phase\*\*: \K.*' "$SPRINT_PROGRESS_FILE" 2>/dev/null)
180
184
 
181
185
  if [[ -n "$current_task" && "$current_task" != "none" ]]; then
182
- echo "**Task**: $current_task"
183
- echo "**Phase**: ${phase:-unknown}"
186
+ echo "**${MSG_SECTION_TASK_LABEL:-Task}**: $current_task"
187
+ echo "**${MSG_SPRINT_PHASE:-Phase}**: ${phase:-unknown}"
184
188
  echo ""
185
- echo "Continue from where you left off in the $phase phase."
189
+ local msg="${MSG_SECTION_CONTINUE_PHASE:-"Continue from where you left off in the {0} phase."}"
190
+ echo "${msg//\{0\}/"$phase"}"
186
191
  else
187
- echo "No current task in progress."
192
+ echo "${MSG_SECTION_NO_TASK:-No current task in progress.}"
188
193
  fi
189
194
  else
190
- echo "No current task information available."
195
+ echo "${MSG_SECTION_NO_TASK_INFO:-No current task information available.}"
191
196
  fi
192
197
  }
193
198
 
@@ -195,34 +200,16 @@ build_current_task_section() {
195
200
  # Continuation Prompt Generation
196
201
  # =============================================================================
197
202
 
203
+ # Templates come from Tools/i18n/ralph/<lang>.sh (MSG_PROMPT_*), so the
204
+ # prompt sent to Claude follows --lang. Replacements are quoted: bash 5.2
205
+ # would otherwise expand `&` in the context to the matched placeholder.
198
206
  generate_continuation_prompt() {
199
207
  local session_id="${SESSION_ID:-unknown}"
200
- local context=$(reconstruct_context "$session_id")
201
-
202
- cat << EOF
203
- # Continuation du Sprint
204
-
205
- Vous reprenez le travail sur ce sprint apres une compaction de contexte.
206
- Le fichier sprint-progress.md contient l'etat complet du travail effectue.
207
-
208
- $context
208
+ local context
209
+ context=$(reconstruct_context "$session_id")
209
210
 
210
- ## Instructions
211
-
212
- 1. **Lisez** le progres ci-dessus pour comprendre l'etat actuel
213
- 2. **Verifiez** les fichiers modifies si necessaire
214
- 3. **Reprenez** la tache en cours la ou elle s'est arretee
215
- 4. **Continuez** le workflow TDD (RED -> GREEN -> REFACTOR)
216
- 5. **Mettez a jour** sprint-progress.md apres chaque tache terminee
217
-
218
- ## Commandes Importantes
219
-
220
- - Apres chaque tache: mettre a jour sprint-progress.md
221
- - Si blocker: noter dans la section Blockers
222
- - Si decision importante: ajouter dans Key Decisions
223
-
224
- Continuez l'implementation.
225
- EOF
211
+ local prompt="${MSG_PROMPT_CONTINUATION:-"{0}"}"
212
+ echo "${prompt//\{0\}/"$context"}"
226
213
  }
227
214
 
228
215
  # =============================================================================
@@ -231,32 +218,12 @@ EOF
231
218
 
232
219
  generate_session_handoff_prompt() {
233
220
  local previous_session="$1"
234
- local context=$(reconstruct_context "$previous_session")
221
+ local context
222
+ context=$(reconstruct_context "$previous_session")
235
223
 
236
- cat << EOF
237
- # Nouvelle Session de Continuation
238
-
239
- Cette session continue le travail de la session precedente ($previous_session).
240
- Le contexte a ete reinitialise mais le fichier sprint-progress.md contient tout le progres.
241
-
242
- $context
243
-
244
- ## Contexte de la Transition
245
-
246
- - Session precedente: $previous_session
247
- - Raison: Limite de contexte atteinte (max compacts)
248
- - Le travail a ete sauvegarde dans sprint-progress.md
249
- - Les fichiers sont dans l'etat du dernier checkpoint git
250
-
251
- ## Instructions
252
-
253
- 1. **Verifiez** l'etat actuel via git status
254
- 2. **Lisez** sprint-progress.md pour le contexte complet
255
- 3. **Identifiez** la tache en cours et son etat
256
- 4. **Continuez** exactement ou la session precedente s'est arretee
257
-
258
- Reprenez le travail.
259
- EOF
224
+ local prompt="${MSG_PROMPT_HANDOFF:-"{1}"}"
225
+ prompt="${prompt//\{0\}/"$previous_session"}"
226
+ echo "${prompt//\{1\}/"$context"}"
260
227
  }
261
228
 
262
229
  # =============================================================================
@@ -18,7 +18,7 @@ get_dod_template() {
18
18
 
19
19
  # Normalize project type (remove version suffixes)
20
20
  local base_type
21
- base_type=$(echo "$project_type" | sed 's/-[0-9.]*$//' | sed 's/-typescript$//')
21
+ base_type=$(echo "$project_type" | sed 's/-[0-9.]*$//' | sed 's/-typescript$//') || true
22
22
 
23
23
  # Map to template file
24
24
  local template_file=""
@@ -69,7 +69,7 @@ get_dod_template_path() {
69
69
  local templates_dir="${2:-$DOD_TEMPLATES_DIR}"
70
70
 
71
71
  local base_type
72
- base_type=$(echo "$project_type" | sed 's/-[0-9.]*$//' | sed 's/-typescript$//')
72
+ base_type=$(echo "$project_type" | sed 's/-[0-9.]*$//' | sed 's/-typescript$//') || true
73
73
 
74
74
  case "$base_type" in
75
75
  symfony|laravel|php)