Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/reference/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ specify init [<project_name>]

Creates a new Spec Kit project with the necessary directory structure, templates, scripts, and AI coding agent integration files.

> [!NOTE]
> The git extension is currently enabled by default during `specify init`.
> Starting in `v0.10.0`, it will require explicit opt-in. To add it after init, run `specify extension add git`.

Use `<project_name>` to create a new directory, or `--here` (or `.`) to initialize in the current directory. If the directory already has files, use `--force` to merge without confirmation.

### Examples
Expand Down
15 changes: 15 additions & 0 deletions src/specify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,8 @@ def init(
]:
tracker.add(key, label)

git_default_notice = False

with Live(tracker.render(), console=console, refresh_per_second=8, transient=True) as live:
tracker.attach_refresh(lambda: live.update(tracker.render()))
try:
Expand Down Expand Up @@ -1349,6 +1351,7 @@ def init(
manager.install_from_directory(
bundled_path, get_speckit_version()
)
git_default_notice = True
git_messages.append("extension installed")
else:
git_has_error = True
Expand Down Expand Up @@ -1519,6 +1522,18 @@ def init(
console.print()
console.print(deprecation_notice)

if git_default_notice:
default_change_notice = Panel(
"The git extension is currently enabled by default during [bold]specify init[/bold].\n"
"Starting in [bold]v0.10.0[/bold], this will require explicit opt-in.\n"
"Use [bold]specify extension add git[/bold] after init when needed.",
title="[yellow]Notice: Git Default Changing[/yellow]",
border_style="yellow",
padding=(1, 2),
)
console.print()
console.print(default_change_notice)

steps_lines = []
if not here:
steps_lines.append(f"1. Go to the project folder: [cyan]cd {project_name}[/cyan]")
Expand Down
26 changes: 26 additions & 0 deletions tests/integrations/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,32 @@ def test_no_git_emits_deprecation_warning(self, tmp_path):
assert "will be removed" in normalized_output
assert "git extension will no longer be enabled by default" in normalized_output

def test_default_git_auto_enable_emits_notice(self, tmp_path):
"""Default git auto-enable emits notice about the v0.10.0 opt-in change."""
from typer.testing import CliRunner
from specify_cli import app

project = tmp_path / "git-default-notice"
project.mkdir()
old_cwd = os.getcwd()
try:
os.chdir(project)
runner = CliRunner()
result = runner.invoke(app, [
"init", "--here", "--ai", "claude", "--script", "sh",
"--ignore-agent-tools",
], catch_exceptions=False)
finally:
os.chdir(old_cwd)

normalized_output = _normalize_cli_output(result.output)
assert result.exit_code == 0, result.output
# Check for key message components (notice may have box-drawing chars)
assert "git extension is currently enabled by default" in normalized_output
assert "v0.10.0" in normalized_output
assert "explicit opt-in" in normalized_output
assert "specify extension add git" in normalized_output

def test_git_extension_commands_registered(self, tmp_path):
"""Git extension commands are registered with the agent during init."""
from typer.testing import CliRunner
Expand Down
Loading