Skip to content

Commit 5df378d

Browse files
committed
fix script command hints for agent separators
1 parent 68a031c commit 5df378d

7 files changed

Lines changed: 241 additions & 20 deletions

File tree

scripts/bash/check-prerequisites.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,20 @@ fi
115115
# Validate required directories and files
116116
if [[ ! -d "$FEATURE_DIR" ]]; then
117117
echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
118-
echo "Run /speckit.specify first to create the feature structure." >&2
118+
echo "Run $(format_speckit_command specify "$REPO_ROOT") first to create the feature structure." >&2
119119
exit 1
120120
fi
121121

122122
if [[ ! -f "$IMPL_PLAN" ]]; then
123123
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
124-
echo "Run /speckit.plan first to create the implementation plan." >&2
124+
echo "Run $(format_speckit_command plan "$REPO_ROOT") first to create the implementation plan." >&2
125125
exit 1
126126
fi
127127

128128
# Check for tasks.md if required
129129
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
130130
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
131-
echo "Run /speckit.tasks first to create the task list." >&2
131+
echo "Run $(format_speckit_command tasks "$REPO_ROOT") first to create the task list." >&2
132132
exit 1
133133
fi
134134

scripts/bash/common.sh

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,67 @@ has_jq() {
307307
command -v jq >/dev/null 2>&1
308308
}
309309

310+
get_invoke_separator() {
311+
local repo_root="${1:-$(get_repo_root)}"
312+
local integration_json="$repo_root/.specify/integration.json"
313+
local separator="."
314+
315+
if [[ ! -f "$integration_json" ]]; then
316+
printf '%s\n' "$separator"
317+
return 0
318+
fi
319+
320+
if command -v jq >/dev/null 2>&1; then
321+
if separator=$(jq -r '(.default_integration // .integration // "") as $k | if $k == "" then "." else (.integration_settings[$k].invoke_separator // ".") end' "$integration_json" 2>/dev/null); then
322+
case "$separator" in
323+
"."|"-") printf '%s\n' "$separator"; return 0 ;;
324+
esac
325+
fi
326+
fi
327+
328+
if command -v python3 >/dev/null 2>&1; then
329+
if separator=$(python3 - "$integration_json" <<'PY' 2>/dev/null
330+
import json
331+
import sys
332+
333+
try:
334+
with open(sys.argv[1], encoding="utf-8") as fh:
335+
state = json.load(fh)
336+
key = state.get("default_integration") or state.get("integration") or ""
337+
settings = state.get("integration_settings")
338+
separator = "."
339+
if isinstance(key, str) and isinstance(settings, dict):
340+
entry = settings.get(key)
341+
if isinstance(entry, dict) and entry.get("invoke_separator") in {".", "-"}:
342+
separator = entry["invoke_separator"]
343+
print(separator)
344+
except Exception:
345+
print(".")
346+
PY
347+
); then
348+
case "$separator" in
349+
"."|"-") printf '%s\n' "$separator"; return 0 ;;
350+
esac
351+
fi
352+
fi
353+
354+
printf '.\n'
355+
}
356+
357+
format_speckit_command() {
358+
local command_name="$1"
359+
local repo_root="${2:-$(get_repo_root)}"
360+
local separator
361+
separator=$(get_invoke_separator "$repo_root")
362+
363+
command_name="${command_name#/}"
364+
command_name="${command_name#speckit.}"
365+
command_name="${command_name#speckit-}"
366+
command_name="${command_name//./$separator}"
367+
368+
printf '/speckit%s%s\n' "$separator" "$command_name"
369+
}
370+
310371
# Escape a string for safe embedding in a JSON value (fallback when jq is unavailable).
311372
# Handles backslash, double-quote, and JSON-required control character escapes (RFC 8259).
312373
json_escape() {
@@ -642,4 +703,3 @@ except Exception:
642703
printf '%s' "$content"
643704
return 0
644705
}
645-

scripts/bash/setup-tasks.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ fi
3535

3636
if [[ ! -f "$IMPL_PLAN" ]]; then
3737
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
38-
echo "Run /speckit.plan first to create the implementation plan." >&2
38+
echo "Run $(format_speckit_command plan "$REPO_ROOT") first to create the implementation plan." >&2
3939
exit 1
4040
fi
4141

4242
if [[ ! -f "$FEATURE_SPEC" ]]; then
4343
echo "ERROR: spec.md not found in $FEATURE_DIR" >&2
44-
echo "Run /speckit.specify first to create the feature structure." >&2
44+
echo "Run $(format_speckit_command specify "$REPO_ROOT") first to create the feature structure." >&2
4545
exit 1
4646
fi
4747

scripts/powershell/check-prerequisites.ps1

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,23 @@ if ($PathsOnly) {
8888
# Validate required directories and files
8989
if (-not (Test-Path $paths.FEATURE_DIR -PathType Container)) {
9090
Write-Output "ERROR: Feature directory not found: $($paths.FEATURE_DIR)"
91-
Write-Output "Run /speckit.specify first to create the feature structure."
91+
$specifyCommand = Format-SpecKitCommand -CommandName 'specify' -RepoRoot $paths.REPO_ROOT
92+
Write-Output "Run $specifyCommand first to create the feature structure."
9293
exit 1
9394
}
9495

9596
if (-not (Test-Path $paths.IMPL_PLAN -PathType Leaf)) {
9697
Write-Output "ERROR: plan.md not found in $($paths.FEATURE_DIR)"
97-
Write-Output "Run /speckit.plan first to create the implementation plan."
98+
$planCommand = Format-SpecKitCommand -CommandName 'plan' -RepoRoot $paths.REPO_ROOT
99+
Write-Output "Run $planCommand first to create the implementation plan."
98100
exit 1
99101
}
100102

101103
# Check for tasks.md if required
102104
if ($RequireTasks -and -not (Test-Path $paths.TASKS -PathType Leaf)) {
103105
Write-Output "ERROR: tasks.md not found in $($paths.FEATURE_DIR)"
104-
Write-Output "Run /speckit.tasks first to create the task list."
106+
$tasksCommand = Format-SpecKitCommand -CommandName 'tasks' -RepoRoot $paths.REPO_ROOT
107+
Write-Output "Run $tasksCommand first to create the task list."
105108
exit 1
106109
}
107110

scripts/powershell/common.ps1

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,48 @@ function Test-DirHasFiles {
355355
}
356356
}
357357

358+
function Get-InvokeSeparator {
359+
param([string]$RepoRoot = (Get-RepoRoot))
360+
361+
$integrationJson = Join-Path $RepoRoot '.specify/integration.json'
362+
if (-not (Test-Path -LiteralPath $integrationJson -PathType Leaf)) {
363+
return '.'
364+
}
365+
366+
try {
367+
$state = Get-Content -LiteralPath $integrationJson -Raw | ConvertFrom-Json
368+
$key = if ($state.default_integration) { [string]$state.default_integration } elseif ($state.integration) { [string]$state.integration } else { '' }
369+
if ($key -and $state.integration_settings) {
370+
$setting = $state.integration_settings.PSObject.Properties[$key].Value
371+
if ($setting -and ($setting.invoke_separator -eq '.' -or $setting.invoke_separator -eq '-')) {
372+
return [string]$setting.invoke_separator
373+
}
374+
}
375+
} catch {
376+
return '.'
377+
}
378+
379+
return '.'
380+
}
381+
382+
function Format-SpecKitCommand {
383+
param(
384+
[Parameter(Mandatory = $true)][string]$CommandName,
385+
[string]$RepoRoot = (Get-RepoRoot)
386+
)
387+
388+
$separator = Get-InvokeSeparator -RepoRoot $RepoRoot
389+
$name = $CommandName.TrimStart('/')
390+
if ($name.StartsWith('speckit.')) {
391+
$name = $name.Substring(8)
392+
} elseif ($name.StartsWith('speckit-')) {
393+
$name = $name.Substring(8)
394+
}
395+
$name = $name -replace '\.', $separator
396+
397+
return "/speckit$separator$name"
398+
}
399+
358400
# Find a usable Python 3 executable (python3, python, or py -3).
359401
# Returns the command/arguments as an array, or $null if none found.
360402
function Get-Python3Command {
@@ -640,4 +682,4 @@ except Exception:
640682
}
641683

642684
return $content
643-
}
685+
}

scripts/powershell/setup-tasks.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ if (-not (Test-FeatureJsonMatchesFeatureDir -RepoRoot $paths.REPO_ROOT -ActiveFe
2828

2929
if (-not (Test-Path $paths.IMPL_PLAN -PathType Leaf)) {
3030
[Console]::Error.WriteLine("ERROR: plan.md not found in $($paths.FEATURE_DIR)")
31-
[Console]::Error.WriteLine("Run /speckit.plan first to create the implementation plan.")
31+
$planCommand = Format-SpecKitCommand -CommandName 'plan' -RepoRoot $paths.REPO_ROOT
32+
[Console]::Error.WriteLine("Run $planCommand first to create the implementation plan.")
3233
exit 1
3334
}
3435

3536
if (-not (Test-Path $paths.FEATURE_SPEC -PathType Leaf)) {
3637
[Console]::Error.WriteLine("ERROR: spec.md not found in $($paths.FEATURE_DIR)")
37-
[Console]::Error.WriteLine("Run /speckit.specify first to create the feature structure.")
38+
$specifyCommand = Format-SpecKitCommand -CommandName 'specify' -RepoRoot $paths.REPO_ROOT
39+
[Console]::Error.WriteLine("Run $specifyCommand first to create the feature structure.")
3840
exit 1
3941
}
4042

0 commit comments

Comments
 (0)