doit-toolkit-cli 0.1.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of doit-toolkit-cli might be problematic. Click here for more details.

Files changed (135) hide show
  1. doit_cli/__init__.py +1356 -0
  2. doit_cli/cli/__init__.py +26 -0
  3. doit_cli/cli/analytics_command.py +616 -0
  4. doit_cli/cli/context_command.py +213 -0
  5. doit_cli/cli/diagram_command.py +304 -0
  6. doit_cli/cli/fixit_command.py +641 -0
  7. doit_cli/cli/hooks_command.py +211 -0
  8. doit_cli/cli/init_command.py +613 -0
  9. doit_cli/cli/memory_command.py +293 -0
  10. doit_cli/cli/roadmapit_command.py +10 -0
  11. doit_cli/cli/status_command.py +117 -0
  12. doit_cli/cli/sync_prompts_command.py +248 -0
  13. doit_cli/cli/validate_command.py +196 -0
  14. doit_cli/cli/verify_command.py +204 -0
  15. doit_cli/cli/workflow_mixin.py +224 -0
  16. doit_cli/cli/xref_command.py +555 -0
  17. doit_cli/formatters/__init__.py +8 -0
  18. doit_cli/formatters/base.py +38 -0
  19. doit_cli/formatters/json_formatter.py +126 -0
  20. doit_cli/formatters/markdown_formatter.py +97 -0
  21. doit_cli/formatters/rich_formatter.py +257 -0
  22. doit_cli/main.py +51 -0
  23. doit_cli/models/__init__.py +139 -0
  24. doit_cli/models/agent.py +74 -0
  25. doit_cli/models/analytics_models.py +384 -0
  26. doit_cli/models/context_config.py +464 -0
  27. doit_cli/models/crossref_models.py +182 -0
  28. doit_cli/models/diagram_models.py +363 -0
  29. doit_cli/models/fixit_models.py +355 -0
  30. doit_cli/models/hook_config.py +125 -0
  31. doit_cli/models/project.py +91 -0
  32. doit_cli/models/results.py +121 -0
  33. doit_cli/models/search_models.py +228 -0
  34. doit_cli/models/status_models.py +195 -0
  35. doit_cli/models/sync_models.py +146 -0
  36. doit_cli/models/template.py +77 -0
  37. doit_cli/models/validation_models.py +175 -0
  38. doit_cli/models/workflow_models.py +319 -0
  39. doit_cli/prompts/__init__.py +5 -0
  40. doit_cli/prompts/fixit_prompts.py +344 -0
  41. doit_cli/prompts/interactive.py +390 -0
  42. doit_cli/rules/__init__.py +5 -0
  43. doit_cli/rules/builtin_rules.py +160 -0
  44. doit_cli/services/__init__.py +79 -0
  45. doit_cli/services/agent_detector.py +168 -0
  46. doit_cli/services/analytics_service.py +218 -0
  47. doit_cli/services/architecture_generator.py +290 -0
  48. doit_cli/services/backup_service.py +204 -0
  49. doit_cli/services/config_loader.py +113 -0
  50. doit_cli/services/context_loader.py +1123 -0
  51. doit_cli/services/coverage_calculator.py +142 -0
  52. doit_cli/services/crossref_service.py +237 -0
  53. doit_cli/services/cycle_time_calculator.py +134 -0
  54. doit_cli/services/date_inferrer.py +349 -0
  55. doit_cli/services/diagram_service.py +337 -0
  56. doit_cli/services/drift_detector.py +109 -0
  57. doit_cli/services/entity_parser.py +301 -0
  58. doit_cli/services/er_diagram_generator.py +197 -0
  59. doit_cli/services/fixit_service.py +699 -0
  60. doit_cli/services/github_service.py +192 -0
  61. doit_cli/services/hook_manager.py +258 -0
  62. doit_cli/services/hook_validator.py +528 -0
  63. doit_cli/services/input_validator.py +322 -0
  64. doit_cli/services/memory_search.py +527 -0
  65. doit_cli/services/mermaid_validator.py +334 -0
  66. doit_cli/services/prompt_transformer.py +91 -0
  67. doit_cli/services/prompt_writer.py +133 -0
  68. doit_cli/services/query_interpreter.py +428 -0
  69. doit_cli/services/report_exporter.py +219 -0
  70. doit_cli/services/report_generator.py +256 -0
  71. doit_cli/services/requirement_parser.py +112 -0
  72. doit_cli/services/roadmap_summarizer.py +209 -0
  73. doit_cli/services/rule_engine.py +443 -0
  74. doit_cli/services/scaffolder.py +215 -0
  75. doit_cli/services/score_calculator.py +172 -0
  76. doit_cli/services/section_parser.py +204 -0
  77. doit_cli/services/spec_scanner.py +327 -0
  78. doit_cli/services/state_manager.py +355 -0
  79. doit_cli/services/status_reporter.py +143 -0
  80. doit_cli/services/task_parser.py +347 -0
  81. doit_cli/services/template_manager.py +710 -0
  82. doit_cli/services/template_reader.py +158 -0
  83. doit_cli/services/user_journey_generator.py +214 -0
  84. doit_cli/services/user_story_parser.py +232 -0
  85. doit_cli/services/validation_service.py +188 -0
  86. doit_cli/services/validator.py +232 -0
  87. doit_cli/services/velocity_tracker.py +173 -0
  88. doit_cli/services/workflow_engine.py +405 -0
  89. doit_cli/templates/agent-file-template.md +28 -0
  90. doit_cli/templates/checklist-template.md +39 -0
  91. doit_cli/templates/commands/doit.checkin.md +363 -0
  92. doit_cli/templates/commands/doit.constitution.md +187 -0
  93. doit_cli/templates/commands/doit.documentit.md +485 -0
  94. doit_cli/templates/commands/doit.fixit.md +181 -0
  95. doit_cli/templates/commands/doit.implementit.md +265 -0
  96. doit_cli/templates/commands/doit.planit.md +262 -0
  97. doit_cli/templates/commands/doit.reviewit.md +355 -0
  98. doit_cli/templates/commands/doit.roadmapit.md +389 -0
  99. doit_cli/templates/commands/doit.scaffoldit.md +458 -0
  100. doit_cli/templates/commands/doit.specit.md +521 -0
  101. doit_cli/templates/commands/doit.taskit.md +304 -0
  102. doit_cli/templates/commands/doit.testit.md +277 -0
  103. doit_cli/templates/config/context.yaml +134 -0
  104. doit_cli/templates/config/hooks.yaml +93 -0
  105. doit_cli/templates/config/validation-rules.yaml +64 -0
  106. doit_cli/templates/github-issue-templates/epic.yml +78 -0
  107. doit_cli/templates/github-issue-templates/feature.yml +116 -0
  108. doit_cli/templates/github-issue-templates/task.yml +129 -0
  109. doit_cli/templates/hooks/.gitkeep +0 -0
  110. doit_cli/templates/hooks/post-commit.sh +25 -0
  111. doit_cli/templates/hooks/post-merge.sh +75 -0
  112. doit_cli/templates/hooks/pre-commit.sh +17 -0
  113. doit_cli/templates/hooks/pre-push.sh +18 -0
  114. doit_cli/templates/memory/completed_roadmap.md +50 -0
  115. doit_cli/templates/memory/constitution.md +125 -0
  116. doit_cli/templates/memory/roadmap.md +61 -0
  117. doit_cli/templates/plan-template.md +146 -0
  118. doit_cli/templates/scripts/bash/check-prerequisites.sh +166 -0
  119. doit_cli/templates/scripts/bash/common.sh +156 -0
  120. doit_cli/templates/scripts/bash/create-new-feature.sh +297 -0
  121. doit_cli/templates/scripts/bash/setup-plan.sh +61 -0
  122. doit_cli/templates/scripts/bash/update-agent-context.sh +675 -0
  123. doit_cli/templates/scripts/powershell/check-prerequisites.ps1 +148 -0
  124. doit_cli/templates/scripts/powershell/common.ps1 +137 -0
  125. doit_cli/templates/scripts/powershell/create-new-feature.ps1 +283 -0
  126. doit_cli/templates/scripts/powershell/setup-plan.ps1 +61 -0
  127. doit_cli/templates/scripts/powershell/update-agent-context.ps1 +406 -0
  128. doit_cli/templates/spec-template.md +159 -0
  129. doit_cli/templates/tasks-template.md +313 -0
  130. doit_cli/templates/vscode-settings.json +14 -0
  131. doit_toolkit_cli-0.1.10.dist-info/METADATA +324 -0
  132. doit_toolkit_cli-0.1.10.dist-info/RECORD +135 -0
  133. doit_toolkit_cli-0.1.10.dist-info/WHEEL +4 -0
  134. doit_toolkit_cli-0.1.10.dist-info/entry_points.txt +2 -0
  135. doit_toolkit_cli-0.1.10.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,211 @@
1
+ """CLI commands for Git hook management."""
2
+
3
+ import sys
4
+
5
+ import typer
6
+ from rich.console import Console
7
+
8
+ from ..services.hook_manager import HookManager
9
+ from ..services.hook_validator import HookValidator
10
+
11
+ console = Console()
12
+
13
+ # Create the hooks command group
14
+ hooks_app = typer.Typer(
15
+ name="hooks",
16
+ help="Manage Git hooks for workflow enforcement.",
17
+ no_args_is_help=True,
18
+ )
19
+
20
+
21
+ @hooks_app.command("install")
22
+ def install_hooks(
23
+ backup: bool = typer.Option(
24
+ False, "--backup", "-b", help="Backup existing hooks before installing"
25
+ ),
26
+ force: bool = typer.Option(
27
+ False, "--force", "-f", help="Overwrite existing hooks without prompting"
28
+ ),
29
+ ) -> None:
30
+ """Install pre-commit and pre-push Git hooks."""
31
+ manager = HookManager()
32
+
33
+ # Check if in git repo
34
+ if not manager.is_git_repo():
35
+ console.print("[red]Error: Not a Git repository.[/red]")
36
+ console.print("Run 'git init' first to initialize a Git repository.")
37
+ raise typer.Exit(1)
38
+
39
+ try:
40
+ installed, skipped = manager.install_hooks(backup=backup, force=force)
41
+
42
+ if installed:
43
+ console.print("[green]Successfully installed hooks:[/green]")
44
+ for hook in installed:
45
+ console.print(f" - {hook}")
46
+
47
+ if skipped:
48
+ console.print("\n[yellow]Skipped hooks (already exist):[/yellow]")
49
+ for hook in skipped:
50
+ console.print(f" - {hook}")
51
+ console.print("\nUse --backup to backup existing hooks, or --force to overwrite.")
52
+
53
+ if not installed and not skipped:
54
+ console.print("[yellow]No hooks to install.[/yellow]")
55
+
56
+ except RuntimeError as e:
57
+ console.print(f"[red]Error: {e}[/red]")
58
+ raise typer.Exit(1)
59
+
60
+
61
+ @hooks_app.command("uninstall")
62
+ def uninstall_hooks() -> None:
63
+ """Remove installed Git hooks."""
64
+ manager = HookManager()
65
+
66
+ removed = manager.uninstall_hooks()
67
+
68
+ if removed:
69
+ console.print("[green]Successfully removed hooks:[/green]")
70
+ for hook in removed:
71
+ console.print(f" - {hook}")
72
+ else:
73
+ console.print("[yellow]No doit hooks found to remove.[/yellow]")
74
+
75
+
76
+ @hooks_app.command("status")
77
+ def hooks_status() -> None:
78
+ """Show current hook installation and configuration status."""
79
+ from ..models.hook_config import HookConfig
80
+
81
+ manager = HookManager()
82
+ config = HookConfig.load_default()
83
+
84
+ console.print("[bold]Git Hooks Status[/bold]")
85
+ console.print("=" * 40)
86
+
87
+ if not manager.is_git_repo():
88
+ console.print("[red]Not a Git repository[/red]")
89
+ raise typer.Exit(1)
90
+
91
+ installed = manager.get_installed_hooks()
92
+
93
+ console.print("\n[bold]Installed Hooks:[/bold]")
94
+ if installed:
95
+ for hook in installed:
96
+ console.print(f" [green]\u2713[/green] {hook}")
97
+ else:
98
+ console.print(" [dim]No doit hooks installed[/dim]")
99
+
100
+ # Show configuration
101
+ config_path = HookConfig.get_default_config_path()
102
+ console.print(f"\n[bold]Configuration:[/bold] {config_path}")
103
+
104
+ pre_commit_status = "[green]enabled[/green]" if config.pre_commit.enabled else "[red]disabled[/red]"
105
+ pre_push_status = "[green]enabled[/green]" if config.pre_push.enabled else "[red]disabled[/red]"
106
+ bypass_status = "[green]enabled[/green]" if config.logging.log_bypasses else "[red]disabled[/red]"
107
+
108
+ console.print(f" Pre-commit validation: {pre_commit_status}")
109
+ console.print(f" Pre-push validation: {pre_push_status}")
110
+ console.print(f" Bypass logging: {bypass_status}")
111
+
112
+ # Show exempt branches
113
+ if config.pre_commit.exempt_branches:
114
+ console.print(f"\n[bold]Exempt Branches:[/bold] {', '.join(config.pre_commit.exempt_branches)}")
115
+
116
+ # Show exempt paths
117
+ if config.pre_commit.exempt_paths:
118
+ console.print(f"[bold]Exempt Paths:[/bold] {', '.join(config.pre_commit.exempt_paths)}")
119
+
120
+ console.print("\n[dim]Use 'doit hooks install' to install hooks[/dim]")
121
+
122
+
123
+ @hooks_app.command("restore")
124
+ def restore_hooks(
125
+ timestamp: str = typer.Option(
126
+ None, "--timestamp", "-t", help="Specific backup timestamp to restore"
127
+ ),
128
+ ) -> None:
129
+ """Restore previously backed up hooks."""
130
+ manager = HookManager()
131
+
132
+ try:
133
+ restored = manager.restore_hooks(timestamp=timestamp)
134
+
135
+ if restored:
136
+ console.print("[green]Successfully restored hooks:[/green]")
137
+ for hook in restored:
138
+ console.print(f" - {hook}")
139
+ else:
140
+ console.print("[yellow]No hooks were restored.[/yellow]")
141
+
142
+ except RuntimeError as e:
143
+ console.print(f"[red]Error: {e}[/red]")
144
+ raise typer.Exit(1)
145
+
146
+
147
+ @hooks_app.command("validate")
148
+ def validate_hook(
149
+ hook_type: str = typer.Argument(
150
+ ..., help="Type of hook to validate (pre-commit or pre-push)"
151
+ ),
152
+ ) -> None:
153
+ """Validate workflow compliance for the specified hook type."""
154
+ valid_types = ["pre-commit", "pre-push"]
155
+ if hook_type not in valid_types:
156
+ console.print(f"[red]Invalid hook type: {hook_type}[/red]")
157
+ console.print(f"Valid types: {', '.join(valid_types)}")
158
+ raise typer.Exit(1)
159
+
160
+ validator = HookValidator()
161
+
162
+ if hook_type == "pre-commit":
163
+ result = validator.validate_pre_commit()
164
+ else:
165
+ result = validator.validate_pre_push()
166
+
167
+ if result.success:
168
+ # Silent success for normal workflow
169
+ sys.exit(0)
170
+ else:
171
+ # Show error and suggestion
172
+ console.print(f"[red]\u2717 {hook_type.title().replace('-', '-')} validation failed[/red]")
173
+ console.print()
174
+ console.print(result.message)
175
+ if result.suggestion:
176
+ console.print()
177
+ console.print(f"[dim]{result.suggestion}[/dim]")
178
+ sys.exit(1)
179
+
180
+
181
+ @hooks_app.command("report")
182
+ def hooks_report() -> None:
183
+ """Show bypass audit log report."""
184
+ validator = HookValidator()
185
+ events = validator.get_bypass_report()
186
+
187
+ console.print("[bold]Hook Bypass Report[/bold]")
188
+ console.print("=" * 40)
189
+
190
+ if not events:
191
+ console.print("\n[dim]No bypass events recorded.[/dim]")
192
+ console.print("[dim]Bypass events are logged when --no-verify is used.[/dim]")
193
+ return
194
+
195
+ console.print(f"\n[bold]Total bypasses:[/bold] {len(events)}")
196
+ console.print()
197
+
198
+ for event in events:
199
+ timestamp = event.get("timestamp", "Unknown")
200
+ hook = event.get("hook", "Unknown")
201
+ branch = event.get("branch", "Unknown")
202
+ user = event.get("user", "Unknown")
203
+ commit = event.get("commit", "")
204
+
205
+ line = f"[dim]{timestamp}[/dim] | [yellow]{hook}[/yellow] | branch: {branch}"
206
+ if commit:
207
+ line += f" | commit: {commit}"
208
+ if user:
209
+ line += f" | user: {user}"
210
+
211
+ console.print(line)