feat(system): fix(cli): remove vestigial hooks/ dir from aipass init scaffold — closes #497
Co-Authored-By: @devpulse <devpulse@aipass>
This commit is contained in:
@@ -19,9 +19,8 @@ Business logic for `aipass init`. Creates the project scaffold:
|
||||
7. STATUS.local.md — project status
|
||||
8. .gitignore — standard AIPass ignores
|
||||
9. .claude/settings.json — Claude Code hooks configuration
|
||||
10. hooks/ — directory for user hooks
|
||||
11. src/ — directory where agents live
|
||||
12. .ai_mail.local/inbox.json — empty project mailbox
|
||||
10. src/ — directory where agents live
|
||||
11. .ai_mail.local/inbox.json — empty project mailbox
|
||||
|
||||
Projects are NOT citizens — no .trinity/ directory. Identity lives in the
|
||||
registry JSON. Init is re-runnable: existing files are skipped, not errors.
|
||||
@@ -338,13 +337,7 @@ def init_project(target: Path, project_name: str | None = None) -> dict:
|
||||
shipped = _ship_hooks(aipass_home, target)
|
||||
created.extend(shipped)
|
||||
|
||||
# 10. hooks/ directory
|
||||
hooks_dir = target / "hooks"
|
||||
if not hooks_dir.exists():
|
||||
hooks_dir.mkdir()
|
||||
created.append(str(hooks_dir))
|
||||
|
||||
# 11. src/ directory (where agents live)
|
||||
# 10. src/ directory (where agents live)
|
||||
src_dir = target / "src"
|
||||
if not src_dir.exists():
|
||||
src_dir.mkdir()
|
||||
@@ -373,7 +366,7 @@ def update_project(target: Path) -> dict:
|
||||
|
||||
Overwrites managed prompt and config files with the latest templates while
|
||||
leaving all user-owned files (registry, README, STATUS.local.md, .gitignore,
|
||||
hooks/, src/) untouched.
|
||||
src/) untouched.
|
||||
|
||||
Args:
|
||||
target: Directory containing the AIPass project to update.
|
||||
|
||||
@@ -122,9 +122,8 @@ def print_help():
|
||||
[green]7.[/green] [yellow]STATUS.local.md[/yellow] Project status
|
||||
[green]8.[/green] [yellow].gitignore[/yellow] Standard AIPass ignores
|
||||
[green]9.[/green] [yellow].claude/settings.json[/yellow] Claude Code hooks + AIPASS_HOME
|
||||
[green]10.[/green] [yellow]hooks/[/yellow] User hooks directory
|
||||
[green]11.[/green] [yellow]src/[/yellow] Agent directories live here
|
||||
[green]12.[/green] [yellow].ai_mail.local/inbox.json[/yellow] Empty project mailbox"""
|
||||
[green]10.[/green] [yellow]src/[/yellow] Agent directories live here
|
||||
[green]11.[/green] [yellow].ai_mail.local/inbox.json[/yellow] Empty project mailbox"""
|
||||
|
||||
console.print(Panel(files_text, border_style="green", padding=(1, 2), box=box.ROUNDED))
|
||||
console.print()
|
||||
@@ -354,7 +353,7 @@ def _handle_init_update(args: List[str]) -> bool:
|
||||
console.print(" CLAUDE.md, AGENTS.md, GEMINI.md")
|
||||
console.print()
|
||||
console.print("[bold cyan]What is never touched:[/bold cyan]")
|
||||
console.print(" *_REGISTRY.json, README.md, STATUS.local.md, .gitignore, hooks/, src/")
|
||||
console.print(" *_REGISTRY.json, README.md, STATUS.local.md, .gitignore, src/")
|
||||
console.print()
|
||||
console.print("[dim]Commands: init update, init update --help[/dim]")
|
||||
console.print()
|
||||
@@ -482,9 +481,8 @@ def _print_init_help():
|
||||
[green]7.[/green] [yellow]STATUS.local.md[/yellow] Project status
|
||||
[green]8.[/green] [yellow].gitignore[/yellow] Standard AIPass ignores
|
||||
[green]9.[/green] [yellow].claude/settings.json[/yellow] Claude Code hooks + AIPASS_HOME
|
||||
[green]10.[/green] [yellow]hooks/[/yellow] User hooks directory
|
||||
[green]11.[/green] [yellow]src/[/yellow] Agent directories live here
|
||||
[green]12.[/green] [yellow].ai_mail.local/inbox.json[/yellow] Empty project mailbox"""
|
||||
[green]10.[/green] [yellow]src/[/yellow] Agent directories live here
|
||||
[green]11.[/green] [yellow].ai_mail.local/inbox.json[/yellow] Empty project mailbox"""
|
||||
|
||||
console.print(Panel(files_text, border_style="green", padding=(1, 2), box=box.ROUNDED))
|
||||
console.print()
|
||||
|
||||
@@ -99,8 +99,7 @@ def test_init_project_creates_all_expected_files(tmp_path):
|
||||
for f in expected_files:
|
||||
assert f.exists(), f"Expected file not created: {f}"
|
||||
|
||||
# hooks/ and src/ are directories, not files
|
||||
assert (target / "hooks").is_dir(), "Expected hooks/ directory"
|
||||
# src/ is a directory, not a file
|
||||
assert (target / "src").is_dir(), "Expected src/ directory"
|
||||
|
||||
# No .trinity/ should be created (projects are not citizens)
|
||||
@@ -109,8 +108,8 @@ def test_init_project_creates_all_expected_files(tmp_path):
|
||||
# No local prompt at project level (belongs in agent dirs only)
|
||||
assert not (target / ".aipass" / "aipass_local_prompt.md").exists()
|
||||
|
||||
# 12 files + 2 dirs + 7 shipped hooks (when AIPASS_HOME detected) = 21
|
||||
assert len(result["created_files"]) == 21
|
||||
# 11 items + 2 commands + 7 shipped hooks (when AIPASS_HOME detected) = 20
|
||||
assert len(result["created_files"]) == 20
|
||||
|
||||
|
||||
def test_init_project_return_dict_structure(tmp_path):
|
||||
@@ -348,7 +347,7 @@ def test_init_project_auto_creates_target_dir(tmp_path):
|
||||
|
||||
assert target.is_dir()
|
||||
assert result["project_name"] == "NESTED"
|
||||
assert len(result["created_files"]) == 21
|
||||
assert len(result["created_files"]) == 20
|
||||
|
||||
|
||||
def test_init_project_defaults_name_from_directory(tmp_path):
|
||||
@@ -395,9 +394,6 @@ def test_init_project_skips_existing_optional_files(tmp_path):
|
||||
claude_dir.mkdir()
|
||||
(claude_dir / "settings.json").write_text("{}\n", encoding="utf-8")
|
||||
|
||||
hooks_dir = target / "hooks"
|
||||
hooks_dir.mkdir()
|
||||
|
||||
src_dir = target / "src"
|
||||
src_dir.mkdir()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user