feat(i18n): add response_language config for cross-phase language consistency (#1412)
* feat(i18n): add response_language config for cross-phase language consistency Adds `response_language` config key that propagates through all init outputs via withProjectRoot(). Workflows read this field and instruct agents to present user-facing questions in the configured language, solving the problem of language preference resetting at phase boundaries. Usage: gsd-tools config-set response_language "Portuguese" Closes #1399 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test(security): allowlist discuss-phase.md for size threshold discuss-phase.md legitimately exceeds 50K chars due to power mode and i18n directives — not prompt stuffing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ const VALID_CONFIG_KEYS = new Set([
|
||||
'hooks.context_warnings',
|
||||
'project_code', 'phase_naming',
|
||||
'manager.flags.discuss', 'manager.flags.plan', 'manager.flags.execute',
|
||||
'response_language',
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -357,6 +357,7 @@ function loadConfig(cwd) {
|
||||
model_overrides: parsed.model_overrides || null,
|
||||
agent_skills: parsed.agent_skills || {},
|
||||
manager: parsed.manager || {},
|
||||
response_language: get('response_language') || null,
|
||||
};
|
||||
} catch {
|
||||
return defaults;
|
||||
|
||||
@@ -37,6 +37,13 @@ function withProjectRoot(cwd, result) {
|
||||
const agentStatus = checkAgentsInstalled();
|
||||
result.agents_installed = agentStatus.agents_installed;
|
||||
result.missing_agents = agentStatus.missing_agents;
|
||||
// Inject response_language into all init outputs (#1399).
|
||||
// Workflows propagate this to subagent prompts so user-facing questions
|
||||
// stay in the configured language across phase boundaries.
|
||||
const config = loadConfig(cwd);
|
||||
if (config.response_language) {
|
||||
result.response_language = config.response_language;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ Configuration options for `.planning/` directory behavior.
|
||||
| `manager.flags.discuss` | `""` | Flags passed to `/gsd:discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) |
|
||||
| `manager.flags.plan` | `""` | Flags passed to plan workflow when dispatched from manager |
|
||||
| `manager.flags.execute` | `""` | Flags passed to execute workflow when dispatched from manager |
|
||||
| `response_language` | `null` | Language for user-facing questions and prompts across all phases/subagents (e.g. `"Portuguese"`, `"Japanese"`, `"Spanish"`). When set, all spawned agents include a directive to respond in this language. |
|
||||
</config_schema>
|
||||
|
||||
<commit_docs_behavior>
|
||||
|
||||
@@ -137,7 +137,9 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS_ADVISOR=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" agent-skills gsd-advisor 2>/dev/null)
|
||||
```
|
||||
|
||||
Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `has_verification`, `plan_count`, `roadmap_exists`, `planning_exists`.
|
||||
Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `has_verification`, `plan_count`, `roadmap_exists`, `planning_exists`, `response_language`.
|
||||
|
||||
**If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. This includes AskUserQuestion labels, option text, gray area descriptions, and discussion summaries. Technical terms, code, and file paths remain in English. Subagent prompts stay in English — only user-facing output is translated.
|
||||
|
||||
**If `phase_found` is false:**
|
||||
```
|
||||
|
||||
@@ -66,7 +66,9 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
AGENT_SKILLS=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" agent-skills gsd-executor 2>/dev/null)
|
||||
```
|
||||
|
||||
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`.
|
||||
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`, `response_language`.
|
||||
|
||||
**If `response_language` is set:** Include `response_language: {value}` in all spawned subagent prompts so any user-facing output stays in the configured language.
|
||||
|
||||
Read worktree config:
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ CONTEXT_WINDOW=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get
|
||||
|
||||
When `CONTEXT_WINDOW >= 500000`, the planner prompt includes prior phase CONTEXT.md files so cross-phase decisions are consistent (e.g., "use library X for all data fetching" from Phase 2 is visible to Phase 5's planner).
|
||||
|
||||
Parse JSON for: `researcher_model`, `planner_model`, `checker_model`, `research_enabled`, `plan_checker_enabled`, `nyquist_validation_enabled`, `commit_docs`, `text_mode`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_reviews`, `has_plans`, `plan_count`, `planning_exists`, `roadmap_exists`, `phase_req_ids`.
|
||||
Parse JSON for: `researcher_model`, `planner_model`, `checker_model`, `research_enabled`, `plan_checker_enabled`, `nyquist_validation_enabled`, `commit_docs`, `text_mode`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_reviews`, `has_plans`, `plan_count`, `planning_exists`, `roadmap_exists`, `phase_req_ids`, `response_language`.
|
||||
|
||||
**If `response_language` is set:** Include `response_language: {value}` in all spawned subagent prompts so any user-facing output stays in the configured language.
|
||||
|
||||
**File paths (for <files_to_read> blocks):** `state_path`, `roadmap_path`, `requirements_path`, `context_path`, `research_path`, `verification_path`, `uat_path`, `reviews_path`. These are null if files don't exist.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user