devloop 0.10.0__tar.gz → 0.10.2__tar.gz
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.
- {devloop-0.10.0 → devloop-0.10.2}/PKG-INFO +1 -1
- {devloop-0.10.0 → devloop-0.10.2}/pyproject.toml +1 -1
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/release.py +16 -22
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/main.py +65 -32
- {devloop-0.10.0 → devloop-0.10.2}/LICENSE +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/README.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/agent_health_monitor.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/ci_monitor.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/code_rabbit.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/doc_lifecycle.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/echo.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/file_logger.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/formatter.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/git_commit_assistant.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/linter.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/performance_profiler.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/sandbox_helper.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/security_scanner.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/snyk.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/test_runner.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/agents/type_checker.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/agent_rules.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/coderabbit_installer.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/agent_publish.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/audit.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/custom_agents.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/feedback.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/insights.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/marketplace.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/marketplace_server.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/mcp_server.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/metrics.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/summary.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/telemetry.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/commands/tools.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/main_v1.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/pre_push_check.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/prerequisites.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/pyodide_installer.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/snyk_installer.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/.devloop/tools-registry.json +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/README.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/agent-summary.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/devloop-findings.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/devloop-status.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/extract-findings.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/verify-work.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/devloop_agents_template.md +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/git_hooks/post-commit +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/git_hooks/pre-commit +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/git_hooks/pre-commit-checks +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/git_hooks/pre-push +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/supervisor/devloop.conf +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/systemd/devloop.service +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/base.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/filesystem.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/git.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/process.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/collectors/system.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/action_logger.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/agent.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/agent_audit_logger.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/agent_template.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/amp_integration.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/amp_thread_mapper.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/auto_fix.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/backup_manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/claude_adapter.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/config.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/config_schema.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/context.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/context_store.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/contextual_feedback.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/custom_agent.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/daemon_health.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/debug_trace.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/error_handler.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/error_notifier.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/event.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/event_replayer.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/event_store.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/feedback.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/file_lock_manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/learning.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/operational_health.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/pattern_analyzer.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/pattern_detector.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/performance.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/proactive_feedback.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/project_context.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/summary_formatter.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/summary_generator.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/telemetry.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/tool_dependencies.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/tool_registry.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/tool_runner.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/core/transactional_io.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/integrations/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/integrations/beads_integration.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/lsp/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/lsp/__main__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/lsp/mapper.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/lsp/server.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/api.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/cache.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/http_server.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/installer.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/metadata.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/publisher.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/registry.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/registry_client.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/reviews.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/search.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/marketplace/signing.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/mcp/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/mcp/resources.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/mcp/server.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/mcp/subscriptions.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/mcp/tools.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/metrics/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/metrics/dora.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/metrics/value_metrics.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/artifactory_registry.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/ci_provider.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/circleci_provider.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/github_actions_provider.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/gitlab_ci_provider.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/jenkins_provider.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/provider_manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/pypi_registry.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/providers/registry_provider.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/release/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/release/release_manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/audit_logger.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/bubblewrap_sandbox.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/cgroups_helper.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/factory.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/no_sandbox.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/package.json +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/path_validator.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/pyodide_runner.js +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/pyodide_sandbox.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/sandbox.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/security/token_manager.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/telemetry/__init__.py +0 -0
- {devloop-0.10.0 → devloop-0.10.2}/src/devloop/telemetry/telemetry_manager.py +0 -0
|
@@ -37,11 +37,10 @@ def publish(
|
|
|
37
37
|
) -> int:
|
|
38
38
|
"""Publish a new release.
|
|
39
39
|
|
|
40
|
-
Performs the
|
|
40
|
+
Performs the release workflow:
|
|
41
41
|
1. Pre-release checks (git clean, branch, CI passes, registry credentials)
|
|
42
42
|
2. Create git tag (v{version} by default)
|
|
43
|
-
3.
|
|
44
|
-
4. Push tag to remote
|
|
43
|
+
3. Push tag to remote (CI handles the actual PyPI publish)
|
|
45
44
|
|
|
46
45
|
Example:
|
|
47
46
|
devloop release publish 1.2.3
|
|
@@ -57,12 +56,12 @@ def publish(
|
|
|
57
56
|
console.print("[yellow]Dry-run mode[/yellow] - no changes will be made")
|
|
58
57
|
console.print()
|
|
59
58
|
|
|
60
|
-
# Create config
|
|
59
|
+
# Create config — publish=False because CI handles PyPI on tag push
|
|
61
60
|
config = ReleaseConfig(
|
|
62
61
|
version=version,
|
|
63
62
|
branch=branch,
|
|
64
63
|
create_tag=not skip_tag,
|
|
65
|
-
publish=
|
|
64
|
+
publish=False,
|
|
66
65
|
ci_provider=ci_provider,
|
|
67
66
|
registry_provider=registry_provider,
|
|
68
67
|
)
|
|
@@ -111,30 +110,25 @@ def publish(
|
|
|
111
110
|
return 1
|
|
112
111
|
console.print()
|
|
113
112
|
|
|
114
|
-
#
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
f"[green]✓ Published to:[/green] {pub_result.registry_provider_name}"
|
|
121
|
-
)
|
|
122
|
-
if pub_result.url:
|
|
123
|
-
console.print(f"[cyan]URL:[/cyan] {pub_result.url}")
|
|
124
|
-
else:
|
|
125
|
-
console.print(f"[red]✗ Publishing failed:[/red] {pub_result.error}")
|
|
126
|
-
return 1
|
|
113
|
+
# Push tag — CI release workflow handles the actual PyPI publish
|
|
114
|
+
tag_name = f"v{version}"
|
|
115
|
+
if config.create_tag:
|
|
116
|
+
console.print(f"[bold]Pushing tag {tag_name} to remote...[/bold]")
|
|
117
|
+
manager._push_tag_to_remote(tag_name)
|
|
118
|
+
console.print("[green]✓ Tag pushed[/green] — CI will publish to PyPI")
|
|
127
119
|
console.print()
|
|
128
120
|
|
|
129
121
|
# Summary
|
|
130
|
-
console.print("[bold][green]✓ Release
|
|
122
|
+
console.print("[bold][green]✓ Release initiated![/green][/bold]")
|
|
131
123
|
if checks_result.ci_provider_name:
|
|
132
124
|
console.print(f" CI Provider: {checks_result.ci_provider_name}")
|
|
133
|
-
if checks_result.registry_provider_name:
|
|
134
|
-
console.print(f" Registry: {checks_result.registry_provider_name}")
|
|
135
125
|
console.print(f" Version: {version}")
|
|
136
126
|
if config.create_tag:
|
|
137
|
-
console.print(f" Tag:
|
|
127
|
+
console.print(f" Tag: {tag_name}")
|
|
128
|
+
console.print(
|
|
129
|
+
" PyPI: CI will publish automatically — monitor at "
|
|
130
|
+
"https://github.com/wioota/devloop/actions"
|
|
131
|
+
)
|
|
138
132
|
|
|
139
133
|
return 0
|
|
140
134
|
|
|
@@ -7,7 +7,7 @@ import subprocess
|
|
|
7
7
|
import sys
|
|
8
8
|
import time
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Optional
|
|
10
|
+
from typing import Any, Optional
|
|
11
11
|
|
|
12
12
|
import typer
|
|
13
13
|
from rich.console import Console
|
|
@@ -641,7 +641,7 @@ def _setup_devloop_directory(path: Path) -> Path:
|
|
|
641
641
|
return claude_dir
|
|
642
642
|
|
|
643
643
|
|
|
644
|
-
def _read_init_manifest(claude_dir: Path) -> dict:
|
|
644
|
+
def _read_init_manifest(claude_dir: Path) -> dict[str, Any]:
|
|
645
645
|
"""Read .devloop/.init-manifest.json, returning defaults if missing or invalid."""
|
|
646
646
|
import json
|
|
647
647
|
|
|
@@ -649,7 +649,8 @@ def _read_init_manifest(claude_dir: Path) -> dict:
|
|
|
649
649
|
if not manifest_path.exists():
|
|
650
650
|
return {"version": None, "managed": []}
|
|
651
651
|
try:
|
|
652
|
-
|
|
652
|
+
result: dict[str, Any] = json.loads(manifest_path.read_text())
|
|
653
|
+
return result
|
|
653
654
|
except (json.JSONDecodeError, OSError):
|
|
654
655
|
return {"version": None, "managed": []}
|
|
655
656
|
|
|
@@ -1027,7 +1028,7 @@ def _setup_git_hooks(path: Path) -> None:
|
|
|
1027
1028
|
checker.show_installation_guide(missing)
|
|
1028
1029
|
|
|
1029
1030
|
|
|
1030
|
-
def _create_claude_hooks(agents_hooks_dir: Path) -> list:
|
|
1031
|
+
def _create_claude_hooks(agents_hooks_dir: Path) -> tuple[list[str], int]:
|
|
1031
1032
|
"""Create Claude Code hook scripts."""
|
|
1032
1033
|
hooks = {
|
|
1033
1034
|
"claude-session-start": """#!/bin/bash
|
|
@@ -1066,33 +1067,65 @@ exit 0
|
|
|
1066
1067
|
#
|
|
1067
1068
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
1068
1069
|
cd "$PROJECT_DIR" || exit 0
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
exit
|
|
1070
|
+
|
|
1071
|
+
INPUT_FILE=$(mktemp)
|
|
1072
|
+
cat > "$INPUT_FILE"
|
|
1073
|
+
export INPUT_FILE PROJECT_DIR
|
|
1074
|
+
|
|
1075
|
+
python3 << 'PYTHON_EOF'
|
|
1076
|
+
import json
|
|
1077
|
+
import os
|
|
1078
|
+
import sys
|
|
1079
|
+
from pathlib import Path
|
|
1080
|
+
|
|
1081
|
+
protected_patterns = [
|
|
1082
|
+
".beads/", ".devloop/", ".git/", ".agents/hooks/", ".claude/",
|
|
1083
|
+
"AGENTS.md", "CODING_RULES.md", "AMP_ONBOARDING.md",
|
|
1084
|
+
]
|
|
1085
|
+
|
|
1086
|
+
input_file = os.environ.get("INPUT_FILE", "")
|
|
1087
|
+
if not input_file:
|
|
1088
|
+
sys.exit(0)
|
|
1089
|
+
try:
|
|
1090
|
+
with open(input_file) as f:
|
|
1091
|
+
input_data = f.read()
|
|
1092
|
+
if not input_data.strip():
|
|
1093
|
+
sys.exit(0)
|
|
1094
|
+
hook_input = json.loads(input_data)
|
|
1095
|
+
except (json.JSONDecodeError, OSError):
|
|
1096
|
+
sys.exit(0)
|
|
1097
|
+
|
|
1098
|
+
tool_name = hook_input.get("tool_name", "")
|
|
1099
|
+
if tool_name not in ("Write", "Edit"):
|
|
1100
|
+
sys.exit(0)
|
|
1101
|
+
|
|
1102
|
+
tool_input = hook_input.get("tool_input", {})
|
|
1103
|
+
if not isinstance(tool_input, dict):
|
|
1104
|
+
sys.exit(0)
|
|
1105
|
+
|
|
1106
|
+
file_path = tool_input.get("file_path") or tool_input.get("path", "")
|
|
1107
|
+
if not file_path:
|
|
1108
|
+
sys.exit(0)
|
|
1109
|
+
|
|
1110
|
+
try:
|
|
1111
|
+
file_path = os.path.realpath(file_path)
|
|
1112
|
+
except OSError:
|
|
1113
|
+
pass
|
|
1114
|
+
|
|
1115
|
+
is_protected = any(pat in file_path for pat in protected_patterns)
|
|
1116
|
+
if is_protected:
|
|
1117
|
+
sys.stderr.write(
|
|
1118
|
+
f"\\U0001f6ab Protected file: {file_path}\\n"
|
|
1119
|
+
"This file is protected by DevLoop to prevent accidental modifications.\\n"
|
|
1120
|
+
"If you need to modify this file, use manual editing or ask the user.\\n"
|
|
1121
|
+
)
|
|
1122
|
+
sys.exit(2)
|
|
1123
|
+
sys.exit(0)
|
|
1124
|
+
PYTHON_EOF
|
|
1125
|
+
|
|
1126
|
+
EXIT_CODE=$?
|
|
1127
|
+
rm -f "$INPUT_FILE"
|
|
1128
|
+
exit $EXIT_CODE
|
|
1096
1129
|
""",
|
|
1097
1130
|
"check-devloop-context": """#!/bin/bash
|
|
1098
1131
|
#
|
|
@@ -1425,7 +1458,7 @@ def _setup_mcp_server(path: Path) -> None:
|
|
|
1425
1458
|
|
|
1426
1459
|
def _setup_claude_hooks(
|
|
1427
1460
|
path: Path, agents_hooks_dir: Path, non_interactive: bool, upgrade: bool = False
|
|
1428
|
-
) -> list:
|
|
1461
|
+
) -> list[str]:
|
|
1429
1462
|
"""Setup Claude Code hooks.
|
|
1430
1463
|
|
|
1431
1464
|
Args:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/agent-summary.md
RENAMED
|
File without changes
|
{devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/devloop-findings.md
RENAMED
|
File without changes
|
{devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/devloop-status.md
RENAMED
|
File without changes
|
{devloop-0.10.0 → devloop-0.10.2}/src/devloop/cli/templates/claude_commands/extract-findings.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|