diff --git a/devloop b/devloop index 99a5e3d..cd57806 100755 --- a/devloop +++ b/devloop @@ -5307,9 +5307,8 @@ spec_command() { skill-path) printf '%s\n' "$skill"; return ;; esac - local context today prompt spec_dir target_path target_dir + local context prompt spec_dir target_path target_dir context="$(resolve_spec_context ${context_items[@]+"${context_items[@]}"})" - today="$(date +%F)" spec_dir="$(devloop_spec_dir)" if [ -n "$output" ]; then target_path="$(absolute_path "$output")" || return 1 @@ -5323,7 +5322,7 @@ spec_command() { target_dir="$(absolute_dir_path "$spec_dir")" || return 1 fi - prompt="$(spec_prompt "$context" "$target_path" "$force" "$skill" "$today" "$target_dir")" + prompt="$(spec_prompt "$context" "$target_path" "$force" "$skill" "$target_dir")" printf 'agent: %s\n' "$(agent_label "$agent")" printf 'mode: interactive spec session\n' printf 'write: %s\n' "$target_dir" @@ -5331,10 +5330,7 @@ spec_command() { } resolve_spec_context() { - if [ "$#" -eq 0 ]; then - printf '%s\n' "No source material was provided. Use the cold-start interview path in the bundled skill to discover intent before writing the spec." - return - fi + if [ "$#" -eq 0 ]; then return; fi local first=true local item file for item in "$@"; do @@ -5345,7 +5341,7 @@ resolve_spec_context() { printf 'Source file: %s\n\n' "$file" cat "$file" else - printf 'Context:\n%s\n' "$item" + printf '%s\n' "$item" fi done } @@ -5355,51 +5351,23 @@ spec_prompt() { local output="$2" local force="$3" local skill="$4" - local today="$5" - local target_dir="$6" - local target_line overwrite_line + local target_dir="$5" + local target_line if [ -n "$output" ]; then - target_line="Requested spec path: $output" + target_line="Output path: $output" else - target_line="Requested spec path: choose $target_dir/$today-.md" + target_line="Output directory: $target_dir" fi + + printf "Use the installed \`devloop-spec\` skill.\n" + printf 'If unavailable, read the bundled skill at: %s\n\n' "$skill" + printf '%s\n' "$target_line" if [ "$force" = true ]; then - overwrite_line="Overwrite policy: overwriting the requested path is allowed." - else - overwrite_line="Overwrite policy: do not overwrite an existing spec; choose a non-conflicting path instead." + printf '\n%s\n' "Overwrite allowed: true" + fi + if [ -n "$context" ]; then + printf '\nContext:\n%s\n' "$context" fi - cat < - -Do not implement the change directly in this session unless the user explicitly -asks you to leave the devloop flow. - -Bundled skill path, for fallback only: $skill - -Context: -$context -EOF } launch_spec_agent() { diff --git a/scripts/devloop_test.sh b/scripts/devloop_test.sh index 62e61d7..43cdf63 100755 --- a/scripts/devloop_test.sh +++ b/scripts/devloop_test.sh @@ -2784,13 +2784,19 @@ repo_specs_real="$(cd "$repo_specs" && pwd -P)" contains "$(cat /tmp/devloop-spec-test.out)" "interactive spec session" "spec command" contains "$(cat /tmp/devloop-spec-test.out)" "write: $repo_specs_real" "spec command target" if [ -f "$repo_specs/$(date +%F)-shell-migration-spec.md" ]; then fail "spec command wrote the spec instead of launching the agent"; fi -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "Skill: use the installed devloop-spec skill." "spec prompt skill" -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "Keep devloop as Bash." "spec prompt" -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "Requested spec path: choose $repo_specs_real/$(date +%F)-.md" "spec prompt configured output" -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "has open questions that could change the work" "spec prompt interview gate" -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "Do not turn a conversation" "spec prompt interview gate" -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "Devloop owns the implementation" "spec prompt ownership" -contains "$(cat /tmp/devloop-spec-agent-prompt.txt)" "devloop --create-pr " "spec prompt handoff" +spec_prompt_text="$(cat /tmp/devloop-spec-agent-prompt.txt)" +expected_spec_prompt="$(printf "Use the installed \`devloop-spec\` skill.\nIf unavailable, read the bundled skill at: %s/skills/devloop-spec/SKILL.md\n\nOutput directory: %s\n\nContext:\nKeep devloop as Bash." "$REPO_ROOT" "$repo_specs_real")" +equals "$spec_prompt_text" "$expected_spec_prompt" "spec prompt" +contains "$spec_prompt_text" "$REPO_ROOT/skills/devloop-spec/SKILL.md" "spec prompt fallback skill" + +( + cd "$repo" + HOME="$spec_home" main spec --agent "$agent" >/tmp/devloop-spec-test.out +) +spec_prompt_text="$(cat /tmp/devloop-spec-agent-prompt.txt)" +expected_spec_prompt="$(printf "Use the installed \`devloop-spec\` skill.\nIf unavailable, read the bundled skill at: %s/skills/devloop-spec/SKILL.md\n\nOutput directory: %s" "$REPO_ROOT" "$repo_specs_real")" +equals "$spec_prompt_text" "$expected_spec_prompt" "cold-start spec prompt" +not_contains "$spec_prompt_text" "Context:" "cold-start spec prompt" contains "$(absolute_path "$work/absolute-path/nested.md")" "/absolute-path/nested.md" "absolute path" existing_spec="$repo/existing.md" existing_spec_real="$(cd "$repo" && pwd -P)/existing.md" @@ -2799,6 +2805,14 @@ rm -f /tmp/devloop-spec-agent-prompt.txt if (cd "$repo" && HOME="$spec_home" main spec --agent "$agent" --output "$existing_spec" "Replace me") >/tmp/devloop-spec-existing.out 2>/tmp/devloop-spec-existing.err; then fail "spec command allowed existing output without force"; fi contains "$(cat /tmp/devloop-spec-existing.err)" "spec already exists: $existing_spec_real" "spec existing output" if [ -f /tmp/devloop-spec-agent-prompt.txt ]; then fail "spec command launched agent for existing output"; fi + +( + cd "$repo" + HOME="$spec_home" main spec --agent "$agent" --output "$existing_spec" --force "Replace me" >/tmp/devloop-spec-test.out +) +spec_prompt_text="$(cat /tmp/devloop-spec-agent-prompt.txt)" +expected_spec_prompt="$(printf "Use the installed \`devloop-spec\` skill.\nIf unavailable, read the bundled skill at: %s/skills/devloop-spec/SKILL.md\n\nOutput path: %s\n\nOverwrite allowed: true\n\nContext:\nReplace me" "$REPO_ROOT" "$existing_spec_real")" +equals "$spec_prompt_text" "$expected_spec_prompt" "forced spec prompt" ok "spec launch" cat > "$fake_bin/codex" <<'AGENT'