From 6bf1c0378f0817dc566bd9331f95db166435edbd Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 14:24:58 +0000 Subject: [PATCH 1/3] feat: enhance and stabilize CLI tool This commit delivers a comprehensive set of fixes and enhancements to the `codesage` CLI tool, addressing multiple bugs and improving overall usability and maintainability. Key improvements include: - **Repaired All CLI Commands:** Systematically tested and fixed runtime errors in all commands, including `snapshot`, `diff`, `report`, `governance-plan`, `history-*`, `org-report`, and `web-console`. - **Robust Snapshot Management:** - The `snapshot cleanup` command is now timezone-aware, preventing `TypeError` crashes. - The `snapshot create --output` flag is fully functional and the command's internal logic has been refactored to remove duplication. - **Enhanced `diff` Command:** The `diff` command can now compare snapshots directly from file paths, in addition to version names. - **Improved Configuration:** - Shared constants have been centralized to `codesage/config/defaults.py`, resolving a circular dependency that crashed the `web-console`. - The `.gitignore` file has been updated to exclude all generated artifacts. - **Code Quality:** - Refactored command handler functions for consistency and fixed all registration issues in `codesage/cli/main.py`. - Removed dead and duplicated code from the `snapshot create` command. This commit ensures that the entire `codesage` CLI suite is functional, stable, and ready for use. --- .codesage.yaml | 92 ++++--- .codesage/snapshots/index.json | 284 ---------------------- .codesage/snapshots/v1.json | 1 - .codesage/snapshots/v10.json | 1 - .codesage/snapshots/v11.json | 1 - .codesage/snapshots/v12.json | 1 - .codesage/snapshots/v13.json | 1 - .codesage/snapshots/v14.json | 1 - .codesage/snapshots/v15.json | 1 - .codesage/snapshots/v16.json | 1 - .codesage/snapshots/v17.json | 1 - .codesage/snapshots/v18.json | 1 - .codesage/snapshots/v19.json | 1 - .codesage/snapshots/v2.json | 1 - .codesage/snapshots/v20.json | 1 - .codesage/snapshots/v21.json | 1 - .codesage/snapshots/v22.json | 1 - .codesage/snapshots/v23.json | 1 - .codesage/snapshots/v24.json | 1 - .codesage/snapshots/v25.json | 1 - .codesage/snapshots/v26.json | 1 - .codesage/snapshots/v27.json | 1 - .codesage/snapshots/v28.json | 1 - .codesage/snapshots/v29.json | 1 - .codesage/snapshots/v3.json | 1 - .codesage/snapshots/v30.json | 1 - .codesage/snapshots/v31.json | 1 - .codesage/snapshots/v32.json | 1 - .codesage/snapshots/v33.json | 1 - .codesage/snapshots/v34.json | 1 - .codesage/snapshots/v35.json | 1 - .codesage/snapshots/v36.json | 1 - .codesage/snapshots/v37.json | 1 - .codesage/snapshots/v38.json | 1 - .codesage/snapshots/v39.json | 1 - .codesage/snapshots/v4.json | 1 - .codesage/snapshots/v40.json | 1 - .codesage/snapshots/v41.json | 1 - .codesage/snapshots/v42.json | 1 - .codesage/snapshots/v43.json | 1 - .codesage/snapshots/v44.json | 1 - .codesage/snapshots/v45.json | 1 - .codesage/snapshots/v46.json | 1 - .codesage/snapshots/v5.json | 1 - .codesage/snapshots/v6.json | 1 - .codesage/snapshots/v7.json | 1 - .codesage/snapshots/v8.json | 1 - .codesage/snapshots/v9.json | 1 - .gitignore | 5 + codesage/cli/commands/diff.py | 16 +- codesage/cli/commands/governance_plan.py | 4 +- codesage/cli/commands/history_diff.py | 2 +- codesage/cli/commands/history_snapshot.py | 2 +- codesage/cli/commands/history_trend.py | 2 +- codesage/cli/commands/jules_prompt.py | 2 +- codesage/cli/commands/snapshot.py | 141 +++++------ codesage/cli/commands/web_console.py | 5 +- codesage/cli/main.py | 24 +- codesage/config/defaults.py | 11 + codesage/org/aggregator.py | 3 +- codesage/snapshot/versioning.py | 17 +- codesage/web/server.py | 4 +- 62 files changed, 192 insertions(+), 468 deletions(-) delete mode 100644 .codesage/snapshots/index.json delete mode 100644 .codesage/snapshots/v1.json delete mode 100644 .codesage/snapshots/v10.json delete mode 100644 .codesage/snapshots/v11.json delete mode 100644 .codesage/snapshots/v12.json delete mode 100644 .codesage/snapshots/v13.json delete mode 100644 .codesage/snapshots/v14.json delete mode 100644 .codesage/snapshots/v15.json delete mode 100644 .codesage/snapshots/v16.json delete mode 100644 .codesage/snapshots/v17.json delete mode 100644 .codesage/snapshots/v18.json delete mode 100644 .codesage/snapshots/v19.json delete mode 100644 .codesage/snapshots/v2.json delete mode 100644 .codesage/snapshots/v20.json delete mode 100644 .codesage/snapshots/v21.json delete mode 100644 .codesage/snapshots/v22.json delete mode 100644 .codesage/snapshots/v23.json delete mode 100644 .codesage/snapshots/v24.json delete mode 100644 .codesage/snapshots/v25.json delete mode 100644 .codesage/snapshots/v26.json delete mode 100644 .codesage/snapshots/v27.json delete mode 100644 .codesage/snapshots/v28.json delete mode 100644 .codesage/snapshots/v29.json delete mode 100644 .codesage/snapshots/v3.json delete mode 100644 .codesage/snapshots/v30.json delete mode 100644 .codesage/snapshots/v31.json delete mode 100644 .codesage/snapshots/v32.json delete mode 100644 .codesage/snapshots/v33.json delete mode 100644 .codesage/snapshots/v34.json delete mode 100644 .codesage/snapshots/v35.json delete mode 100644 .codesage/snapshots/v36.json delete mode 100644 .codesage/snapshots/v37.json delete mode 100644 .codesage/snapshots/v38.json delete mode 100644 .codesage/snapshots/v39.json delete mode 100644 .codesage/snapshots/v4.json delete mode 100644 .codesage/snapshots/v40.json delete mode 100644 .codesage/snapshots/v41.json delete mode 100644 .codesage/snapshots/v42.json delete mode 100644 .codesage/snapshots/v43.json delete mode 100644 .codesage/snapshots/v44.json delete mode 100644 .codesage/snapshots/v45.json delete mode 100644 .codesage/snapshots/v46.json delete mode 100644 .codesage/snapshots/v5.json delete mode 100644 .codesage/snapshots/v6.json delete mode 100644 .codesage/snapshots/v7.json delete mode 100644 .codesage/snapshots/v8.json delete mode 100644 .codesage/snapshots/v9.json diff --git a/.codesage.yaml b/.codesage.yaml index 01711eb..28b1c55 100644 --- a/.codesage.yaml +++ b/.codesage.yaml @@ -1,52 +1,66 @@ -languages: - python: - extensions: [".py"] - go: - extensions: [".go"] - javascript: - extensions: [".js", ".jsx"] - typescript: - extensions: [".ts", ".tsx"] - -thresholds: - complexity: 20 - duplication: 10 - -ignore_paths: - - "node_modules/" - - "vendor/" - - "tests/" - analyzers: complexity: - function_threshold: 10 file_threshold: 200 + function_threshold: 10 dependency: - max_depth: 5 detect_cycles: true + max_depth: 5 patterns: - enabled_rules: ["singleton", "factory", "god_class"] - + enabled_rules: + - singleton + - factory + - god_class +ignore_paths: +- node_modules/ +- vendor/ +- tests/ +languages: + go: + extensions: + - .go + javascript: + extensions: + - .js + - .jsx + python: + extensions: + - .py + typescript: + extensions: + - .ts + - .tsx +llm: + api_key: ${OPENAI_API_KEY} + enabled: true + model: gpt-4 + provider: openai + retries: 3 + temperature: 0.0 + timeout: 60 snapshot: - output_dir: ".codesage/snapshots" - formats: ["json", "markdown"] compression: enabled: true - exclude_patterns: ["*.test.go", "*_test.py"] + exclude_patterns: + - '*.test.go' + - '*_test.py' + formats: + - json + - markdown + markdown: + include_source_code: false + max_code_lines: 20 + template: default_report + output_dir: .codesage/snapshots versioning: enabled: true max_versions: 10 retention_days: 30 - markdown: - template: "default_report" - include_source_code: false - max_code_lines: 20 - -llm: - enabled: true - provider: "openai" # "openai" or "anthropic" - model: "gpt-4" - api_key: "${OPENAI_API_KEY}" # Supports env var expansion in loader if implemented, otherwise use explicit key - temperature: 0.0 - timeout: 60 - retries: 3 +thresholds: + complexity: 20 + duplication: 10 +org: + projects: + - id: codesage + name: codesage + path: . + snapshot_path: v1.json diff --git a/.codesage/snapshots/index.json b/.codesage/snapshots/index.json deleted file mode 100644 index 37a68c8..0000000 --- a/.codesage/snapshots/index.json +++ /dev/null @@ -1,284 +0,0 @@ -[ - { - "version": "v1", - "timestamp": "2025-11-23T14:09:37.420472", - "path": ".codesage/snapshots/v1.json", - "git_commit": null - }, - { - "version": "v2", - "timestamp": "2025-11-25T04:21:39.559962", - "path": ".codesage/snapshots/v2.json", - "git_commit": null - }, - { - "version": "v3", - "timestamp": "2025-11-25T04:24:00.711615", - "path": ".codesage/snapshots/v3.json", - "git_commit": null - }, - { - "version": "v4", - "timestamp": "2025-11-25T04:28:47.355799", - "path": ".codesage/snapshots/v4.json", - "git_commit": null - }, - { - "version": "v5", - "timestamp": "2025-11-25T04:30:10.619591", - "path": ".codesage/snapshots/v5.json", - "git_commit": null - }, - { - "version": "v6", - "timestamp": "2025-11-25T04:30:11.264485", - "path": ".codesage/snapshots/v6.json", - "git_commit": null - }, - { - "version": "v7", - "timestamp": "2025-11-25T04:32:04.166257", - "path": ".codesage/snapshots/v7.json", - "git_commit": null - }, - { - "version": "v8", - "timestamp": "2025-11-25T04:32:04.781621", - "path": ".codesage/snapshots/v8.json", - "git_commit": null - }, - { - "version": "v9", - "timestamp": "2025-11-25T04:33:37.187839", - "path": ".codesage/snapshots/v9.json", - "git_commit": null - }, - { - "version": "v10", - "timestamp": "2025-11-25T04:33:37.842891", - "path": ".codesage/snapshots/v10.json", - "git_commit": null - }, - { - "version": "v11", - "timestamp": "2025-11-25T04:36:15.082563", - "path": ".codesage/snapshots/v11.json", - "git_commit": null - }, - { - "version": "v12", - "timestamp": "2025-11-25T04:36:15.709401", - "path": ".codesage/snapshots/v12.json", - "git_commit": null - }, - { - "version": "v13", - "timestamp": "2025-11-25T04:38:09.454288", - "path": ".codesage/snapshots/v13.json", - "git_commit": null - }, - { - "version": "v14", - "timestamp": "2025-11-25T04:38:10.093066", - "path": ".codesage/snapshots/v14.json", - "git_commit": null - }, - { - "version": "v15", - "timestamp": "2025-11-25T04:40:15.680065", - "path": ".codesage/snapshots/v15.json", - "git_commit": null - }, - { - "version": "v16", - "timestamp": "2025-11-25T04:40:16.312136", - "path": ".codesage/snapshots/v16.json", - "git_commit": null - }, - { - "version": "v17", - "timestamp": "2025-11-25T04:42:10.275275", - "path": ".codesage/snapshots/v17.json", - "git_commit": null - }, - { - "version": "v18", - "timestamp": "2025-11-25T04:42:10.909066", - "path": ".codesage/snapshots/v18.json", - "git_commit": null - }, - { - "version": "v19", - "timestamp": "2025-11-25T04:43:59.179533", - "path": ".codesage/snapshots/v19.json", - "git_commit": null - }, - { - "version": "v20", - "timestamp": "2025-11-25T04:43:59.847730", - "path": ".codesage/snapshots/v20.json", - "git_commit": null - }, - { - "version": "v21", - "timestamp": "2025-11-25T04:45:44.168145", - "path": ".codesage/snapshots/v21.json", - "git_commit": null - }, - { - "version": "v22", - "timestamp": "2025-11-25T04:45:44.852722", - "path": ".codesage/snapshots/v22.json", - "git_commit": null - }, - { - "version": "v23", - "timestamp": "2025-11-25T04:50:31.825692", - "path": ".codesage/snapshots/v23.json", - "git_commit": null - }, - { - "version": "v24", - "timestamp": "2025-11-25T04:50:32.463125", - "path": ".codesage/snapshots/v24.json", - "git_commit": null - }, - { - "version": "v25", - "timestamp": "2025-11-25T05:01:14.890149", - "path": ".codesage/snapshots/v25.json", - "git_commit": null - }, - { - "version": "v26", - "timestamp": "2025-11-25T05:01:15.461499", - "path": ".codesage/snapshots/v26.json", - "git_commit": null - }, - { - "version": "v27", - "timestamp": "2025-11-25T05:03:21.183017", - "path": ".codesage/snapshots/v27.json", - "git_commit": null - }, - { - "version": "v28", - "timestamp": "2025-11-25T05:03:21.770417", - "path": ".codesage/snapshots/v28.json", - "git_commit": null - }, - { - "version": "v29", - "timestamp": "2025-11-25T05:06:22.051834", - "path": ".codesage/snapshots/v29.json", - "git_commit": null - }, - { - "version": "v30", - "timestamp": "2025-11-25T05:06:22.667723", - "path": ".codesage/snapshots/v30.json", - "git_commit": null - }, - { - "version": "v31", - "timestamp": "2025-11-25T05:09:03.854139", - "path": ".codesage/snapshots/v31.json", - "git_commit": null - }, - { - "version": "v32", - "timestamp": "2025-11-25T05:09:04.450657", - "path": ".codesage/snapshots/v32.json", - "git_commit": null - }, - { - "version": "v33", - "timestamp": "2025-11-25T05:11:15.843910", - "path": ".codesage/snapshots/v33.json", - "git_commit": null - }, - { - "version": "v34", - "timestamp": "2025-11-25T05:11:16.639005", - "path": ".codesage/snapshots/v34.json", - "git_commit": null - }, - { - "version": "v35", - "timestamp": "2025-11-25T05:14:06.613920", - "path": ".codesage/snapshots/v35.json", - "git_commit": null - }, - { - "version": "v36", - "timestamp": "2025-11-25T05:14:07.231591", - "path": ".codesage/snapshots/v36.json", - "git_commit": null - }, - { - "version": "v37", - "timestamp": "2025-11-25T05:27:19.842583", - "path": ".codesage/snapshots/v37.json", - "git_commit": null - }, - { - "version": "v38", - "timestamp": "2025-11-25T05:27:20.538230", - "path": ".codesage/snapshots/v38.json", - "git_commit": null - }, - { - "version": "v39", - "timestamp": "2025-11-25T05:31:10.639024", - "path": ".codesage/snapshots/v39.json", - "git_commit": null - }, - { - "version": "v40", - "timestamp": "2025-11-25T05:31:11.294129", - "path": ".codesage/snapshots/v40.json", - "git_commit": null - }, - { - "version": "v41", - "timestamp": "2025-11-25T05:32:43.758546", - "path": ".codesage/snapshots/v41.json", - "git_commit": null - }, - { - "version": "v42", - "timestamp": "2025-11-25T05:32:44.395369", - "path": ".codesage/snapshots/v42.json", - "git_commit": null - }, - { - "version": "v43", - "timestamp": "2025-11-25T05:38:52.603654", - "path": ".codesage/snapshots/v43.json", - "git_commit": null - }, - { - "version": "v44", - "timestamp": "2025-11-25T05:38:53.420694", - "path": ".codesage/snapshots/v44.json", - "git_commit": null - }, - { - "version": "v45", - "timestamp": "2025-11-25T05:53:15.334756", - "path": ".codesage/snapshots/v45.json", - "git_commit": null - }, - { - "version": "v46", - "timestamp": "2025-11-25T05:53:15.980323", - "path": ".codesage/snapshots/v46.json", - "git_commit": null - }, - { - "version": "v47", - "timestamp": "2025-11-25T06:00:03.637259", - "path": ".codesage/snapshots/v47.json", - "git_commit": null - } -] \ No newline at end of file diff --git a/.codesage/snapshots/v1.json b/.codesage/snapshots/v1.json deleted file mode 100644 index 055b898..0000000 --- a/.codesage/snapshots/v1.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v1","timestamp":"2025-11-23T14:09:37.420472","project_name":"my_project","file_count":2,"total_size":263,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-12/test_e2e_lifecycle0/my_project/script.py","language":"python","metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-12/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"dea0e8f0430295fd5ae50d3f7b9797162f0f3e67b81c2dfe3ec2ac160328605f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v10.json b/.codesage/snapshots/v10.json deleted file mode 100644 index d0da3d6..0000000 --- a/.codesage/snapshots/v10.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v10","timestamp":"2025-11-25T04:33:37.842891","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-5/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v11.json b/.codesage/snapshots/v11.json deleted file mode 100644 index 76aa40b..0000000 --- a/.codesage/snapshots/v11.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v11","timestamp":"2025-11-25T04:36:15.082563","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-6/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-6/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v12.json b/.codesage/snapshots/v12.json deleted file mode 100644 index c35a2bb..0000000 --- a/.codesage/snapshots/v12.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v12","timestamp":"2025-11-25T04:36:15.709401","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-6/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v13.json b/.codesage/snapshots/v13.json deleted file mode 100644 index 2a1af6b..0000000 --- a/.codesage/snapshots/v13.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v13","timestamp":"2025-11-25T04:38:09.454288","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-7/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-7/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v14.json b/.codesage/snapshots/v14.json deleted file mode 100644 index 21d6ffd..0000000 --- a/.codesage/snapshots/v14.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v14","timestamp":"2025-11-25T04:38:10.093066","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-7/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v15.json b/.codesage/snapshots/v15.json deleted file mode 100644 index b01fc76..0000000 --- a/.codesage/snapshots/v15.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v15","timestamp":"2025-11-25T04:40:15.680065","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-8/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-8/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v16.json b/.codesage/snapshots/v16.json deleted file mode 100644 index 99071ab..0000000 --- a/.codesage/snapshots/v16.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v16","timestamp":"2025-11-25T04:40:16.312136","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-8/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v17.json b/.codesage/snapshots/v17.json deleted file mode 100644 index 5d4af05..0000000 --- a/.codesage/snapshots/v17.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v17","timestamp":"2025-11-25T04:42:10.275275","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-9/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-9/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v18.json b/.codesage/snapshots/v18.json deleted file mode 100644 index f710694..0000000 --- a/.codesage/snapshots/v18.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v18","timestamp":"2025-11-25T04:42:10.909066","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-9/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v19.json b/.codesage/snapshots/v19.json deleted file mode 100644 index 296ef21..0000000 --- a/.codesage/snapshots/v19.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v19","timestamp":"2025-11-25T04:43:59.179533","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-10/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-10/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v2.json b/.codesage/snapshots/v2.json deleted file mode 100644 index c3bcb4c..0000000 --- a/.codesage/snapshots/v2.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v2","timestamp":"2025-11-25T04:21:39.559962","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-0/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v20.json b/.codesage/snapshots/v20.json deleted file mode 100644 index 3e5e0cc..0000000 --- a/.codesage/snapshots/v20.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v20","timestamp":"2025-11-25T04:43:59.847730","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-10/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v21.json b/.codesage/snapshots/v21.json deleted file mode 100644 index e9d659a..0000000 --- a/.codesage/snapshots/v21.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v21","timestamp":"2025-11-25T04:45:44.168145","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-11/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-11/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v22.json b/.codesage/snapshots/v22.json deleted file mode 100644 index 1a12657..0000000 --- a/.codesage/snapshots/v22.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v22","timestamp":"2025-11-25T04:45:44.852722","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-11/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v23.json b/.codesage/snapshots/v23.json deleted file mode 100644 index 0e82fc5..0000000 --- a/.codesage/snapshots/v23.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v23","timestamp":"2025-11-25T04:50:31.825692","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-12/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-12/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v24.json b/.codesage/snapshots/v24.json deleted file mode 100644 index cc9b2b0..0000000 --- a/.codesage/snapshots/v24.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v24","timestamp":"2025-11-25T04:50:32.463125","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-12/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v25.json b/.codesage/snapshots/v25.json deleted file mode 100644 index 99b60ce..0000000 --- a/.codesage/snapshots/v25.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v25","timestamp":"2025-11-25T05:01:14.890149","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-12/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-12/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v26.json b/.codesage/snapshots/v26.json deleted file mode 100644 index 4c9e9db..0000000 --- a/.codesage/snapshots/v26.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v26","timestamp":"2025-11-25T05:01:15.461499","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-12/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v27.json b/.codesage/snapshots/v27.json deleted file mode 100644 index ae3c040..0000000 --- a/.codesage/snapshots/v27.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v27","timestamp":"2025-11-25T05:03:21.183017","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-13/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-13/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v28.json b/.codesage/snapshots/v28.json deleted file mode 100644 index 18fac7b..0000000 --- a/.codesage/snapshots/v28.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v28","timestamp":"2025-11-25T05:03:21.770417","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-13/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v29.json b/.codesage/snapshots/v29.json deleted file mode 100644 index d2e8ed7..0000000 --- a/.codesage/snapshots/v29.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v29","timestamp":"2025-11-25T05:06:22.051834","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-14/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-14/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v3.json b/.codesage/snapshots/v3.json deleted file mode 100644 index e77c338..0000000 --- a/.codesage/snapshots/v3.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v3","timestamp":"2025-11-25T04:24:00.711615","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-1/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v30.json b/.codesage/snapshots/v30.json deleted file mode 100644 index d8dea59..0000000 --- a/.codesage/snapshots/v30.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v30","timestamp":"2025-11-25T05:06:22.667723","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-14/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v31.json b/.codesage/snapshots/v31.json deleted file mode 100644 index 97b793f..0000000 --- a/.codesage/snapshots/v31.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v31","timestamp":"2025-11-25T05:09:03.854139","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-15/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-15/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v32.json b/.codesage/snapshots/v32.json deleted file mode 100644 index 21a450a..0000000 --- a/.codesage/snapshots/v32.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v32","timestamp":"2025-11-25T05:09:04.450657","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-15/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v33.json b/.codesage/snapshots/v33.json deleted file mode 100644 index 03a4959..0000000 --- a/.codesage/snapshots/v33.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v33","timestamp":"2025-11-25T05:11:15.843910","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-16/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-16/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v34.json b/.codesage/snapshots/v34.json deleted file mode 100644 index 753eb98..0000000 --- a/.codesage/snapshots/v34.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v34","timestamp":"2025-11-25T05:11:16.639005","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-16/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v35.json b/.codesage/snapshots/v35.json deleted file mode 100644 index 237abfa..0000000 --- a/.codesage/snapshots/v35.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v35","timestamp":"2025-11-25T05:14:06.613920","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-17/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-17/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v36.json b/.codesage/snapshots/v36.json deleted file mode 100644 index aa31057..0000000 --- a/.codesage/snapshots/v36.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v36","timestamp":"2025-11-25T05:14:07.231591","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-17/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v37.json b/.codesage/snapshots/v37.json deleted file mode 100644 index 7a7ec29..0000000 --- a/.codesage/snapshots/v37.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v37","timestamp":"2025-11-25T05:27:19.842583","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-18/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-18/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v38.json b/.codesage/snapshots/v38.json deleted file mode 100644 index 95960a1..0000000 --- a/.codesage/snapshots/v38.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v38","timestamp":"2025-11-25T05:27:20.538230","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-18/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v39.json b/.codesage/snapshots/v39.json deleted file mode 100644 index 3a68854..0000000 --- a/.codesage/snapshots/v39.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v39","timestamp":"2025-11-25T05:31:10.639024","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-19/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-19/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v4.json b/.codesage/snapshots/v4.json deleted file mode 100644 index 35bd748..0000000 --- a/.codesage/snapshots/v4.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v4","timestamp":"2025-11-25T04:28:47.355799","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-2/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v40.json b/.codesage/snapshots/v40.json deleted file mode 100644 index 12b14f5..0000000 --- a/.codesage/snapshots/v40.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v40","timestamp":"2025-11-25T05:31:11.294129","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-19/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v41.json b/.codesage/snapshots/v41.json deleted file mode 100644 index eeec305..0000000 --- a/.codesage/snapshots/v41.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v41","timestamp":"2025-11-25T05:32:43.758546","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-20/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-20/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v42.json b/.codesage/snapshots/v42.json deleted file mode 100644 index 2e090c5..0000000 --- a/.codesage/snapshots/v42.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v42","timestamp":"2025-11-25T05:32:44.395369","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-20/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v43.json b/.codesage/snapshots/v43.json deleted file mode 100644 index c2f5e6f..0000000 --- a/.codesage/snapshots/v43.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v43","timestamp":"2025-11-25T05:38:52.603654","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-21/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-21/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v44.json b/.codesage/snapshots/v44.json deleted file mode 100644 index c5fafbf..0000000 --- a/.codesage/snapshots/v44.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v44","timestamp":"2025-11-25T05:38:53.420694","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-21/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v45.json b/.codesage/snapshots/v45.json deleted file mode 100644 index c34ff87..0000000 --- a/.codesage/snapshots/v45.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v45","timestamp":"2025-11-25T05:53:15.334756","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-22/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-22/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v46.json b/.codesage/snapshots/v46.json deleted file mode 100644 index de45e8a..0000000 --- a/.codesage/snapshots/v46.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v46","timestamp":"2025-11-25T05:53:15.980323","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-22/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v5.json b/.codesage/snapshots/v5.json deleted file mode 100644 index e06dee9..0000000 --- a/.codesage/snapshots/v5.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v5","timestamp":"2025-11-25T04:30:10.619591","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-3/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-3/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v6.json b/.codesage/snapshots/v6.json deleted file mode 100644 index 8a62f2e..0000000 --- a/.codesage/snapshots/v6.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v6","timestamp":"2025-11-25T04:30:11.264485","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-3/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v7.json b/.codesage/snapshots/v7.json deleted file mode 100644 index 8b07ec1..0000000 --- a/.codesage/snapshots/v7.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v7","timestamp":"2025-11-25T04:32:04.166257","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-4/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-4/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v8.json b/.codesage/snapshots/v8.json deleted file mode 100644 index 7ae0482..0000000 --- a/.codesage/snapshots/v8.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v8","timestamp":"2025-11-25T04:32:04.781621","project_name":"project","file_count":1,"total_size":14,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-4/test_legacy_snapshot_command0/project/file.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"96f43d529af3430cb6b0e2c02f6b38ef1a121e8a31d2d09a3ebb716f2f35c9de","lines":1,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":1},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.codesage/snapshots/v9.json b/.codesage/snapshots/v9.json deleted file mode 100644 index cec4731..0000000 --- a/.codesage/snapshots/v9.json +++ /dev/null @@ -1 +0,0 @@ -{"metadata":{"version":"v9","timestamp":"2025-11-25T04:33:37.187839","project_name":"my_project","file_count":2,"total_size":261,"git_commit":null,"tool_version":"0.2.0","config_hash":"not_implemented"},"files":[{"path":"/tmp/pytest-of-jules/pytest-5/test_e2e_lifecycle0/my_project/script.py","language":"python","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"9a257e5c622b07b72881e37ad9e6ff479332827d1a871aab1bdae8a6347729f5","lines":5,"ast_summary":{"function_count":1,"class_count":0,"import_count":0,"comment_lines":1},"complexity_metrics":{"cyclomatic":2},"detected_patterns":[],"analysis_issues":[]},{"path":"/tmp/pytest-of-jules/pytest-5/test_e2e_lifecycle0/my_project/Complex.java","language":"unknown","content":null,"size":null,"metrics":null,"symbols":{},"risk":null,"issues":[],"compression_level":"full","hash":"c0bf98aa7370af235a7c2057ad7bf9c2c5ad277f9b417918c227abb20f004d1f","lines":7,"ast_summary":{"function_count":0,"class_count":0,"import_count":0,"comment_lines":0},"complexity_metrics":{"cyclomatic":0},"detected_patterns":[],"analysis_issues":[]}],"dependencies":null,"risk_summary":null,"issues_summary":null,"llm_stats":null,"languages":[],"language_stats":{},"global_metrics":{},"dependency_graph":{"internal":[],"external":[],"edges":[]},"detected_patterns":[],"issues":[]} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9924e44..61a8573 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,8 @@ dmypy.json .pyre/ /ai/ /.ai/ + +# CodeSage files +.codesage/ +report.md +report.json diff --git a/codesage/cli/commands/diff.py b/codesage/cli/commands/diff.py index e463025..e0b4966 100644 --- a/codesage/cli/commands/diff.py +++ b/codesage/cli/commands/diff.py @@ -25,12 +25,24 @@ def diff(version1, version2, output, format): """ manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_CONFIG['snapshot']) - snapshot1 = manager.load_snapshot(version1) + from codesage.snapshot.models import ProjectSnapshot + import json + from pathlib import Path + + def load_snapshot_from_path_or_version(path_or_version: str): + path = Path(path_or_version) + if path.is_file() and path.exists(): + with open(path, 'r') as f: + data = json.load(f) + return ProjectSnapshot.model_validate(data) + return manager.load_snapshot(path_or_version) + + snapshot1 = load_snapshot_from_path_or_version(version1) if not snapshot1: click.echo(f"Snapshot {version1} not found.", err=True) return - snapshot2 = manager.load_snapshot(version2) + snapshot2 = load_snapshot_from_path_or_version(version2) if not snapshot2: click.echo(f"Snapshot {version2} not found.", err=True) return diff --git a/codesage/cli/commands/governance_plan.py b/codesage/cli/commands/governance_plan.py index c38bfb5..96fe2e4 100644 --- a/codesage/cli/commands/governance_plan.py +++ b/codesage/cli/commands/governance_plan.py @@ -28,7 +28,7 @@ @click.option("--group-by", type=click.Choice(["rule", "file", "risk_level"]), help="Override the grouping strategy.") @click.option("--max-tasks-per-file", type=int, help="Override the max tasks per file limit.") @click.pass_context -def governance_plan_command( +def governance_plan( ctx, input_path: str, output_path: str, @@ -84,4 +84,4 @@ def governance_plan_command( def register(cli: click.Group) -> None: """Registers the governance-plan command with the main CLI group.""" - cli.add_command(governance_plan_command) + cli.add_command(governance_plan) diff --git a/codesage/cli/commands/history_diff.py b/codesage/cli/commands/history_diff.py index b211ae3..f29a43c 100644 --- a/codesage/cli/commands/history_diff.py +++ b/codesage/cli/commands/history_diff.py @@ -19,7 +19,7 @@ @click.option('--output', type=click.Path(dir_okay=False, writable=True), help="Path to save the diff output YAML file.") @click.option('--config-file', help="Path to the codesage config file.") @click.pass_context -def history_diff_command(ctx, project_name, from_id, to_id, output, config_file): +def history_diff(ctx, project_name, from_id, to_id, output, config_file): audit_logger = ctx.obj.audit_logger try: if config_file: diff --git a/codesage/cli/commands/history_snapshot.py b/codesage/cli/commands/history_snapshot.py index ac72c53..a9caa2f 100644 --- a/codesage/cli/commands/history_snapshot.py +++ b/codesage/cli/commands/history_snapshot.py @@ -19,7 +19,7 @@ @click.option('--trigger', default='manual', help="The trigger for the snapshot (e.g., 'ci', 'manual').") @click.option('--config-file', help="Path to the codesage config file.") @click.pass_context -def history_snapshot_command(ctx, snapshot_path, project_name, commit, branch, trigger, config_file): +def history_snapshot(ctx, snapshot_path, project_name, commit, branch, trigger, config_file): audit_logger = ctx.obj.audit_logger try: if config_file: diff --git a/codesage/cli/commands/history_trend.py b/codesage/cli/commands/history_trend.py index 26b1e25..f3ddf2c 100644 --- a/codesage/cli/commands/history_trend.py +++ b/codesage/cli/commands/history_trend.py @@ -17,7 +17,7 @@ @click.option('--format', 'output_format', type=click.Choice(['json', 'yaml']), default='json', help="Output format.") @click.option('--config-file', help="Path to the codesage config file.") @click.pass_context -def history_trend_command(ctx, project_name, output, output_format, config_file): +def history_trend(ctx, project_name, output, output_format, config_file): audit_logger = ctx.obj.audit_logger try: if config_file: diff --git a/codesage/cli/commands/jules_prompt.py b/codesage/cli/commands/jules_prompt.py index 357e2d2..d447694 100644 --- a/codesage/cli/commands/jules_prompt.py +++ b/codesage/cli/commands/jules_prompt.py @@ -18,7 +18,7 @@ @click.option('--task-id', help="The ID of the task within the governance plan.") @click.option('--task', 'task_path', type=click.Path(exists=True), help="Path to a single GovernanceTask YAML/JSON file.") @click.pass_context -def jules_prompt_command(ctx, plan_path: Optional[str], task_id: Optional[str], task_path: Optional[str]): +def jules_prompt(ctx, plan_path: Optional[str], task_id: Optional[str], task_path: Optional[str]): """ Generates a prompt for Jules from a governance task. """ diff --git a/codesage/cli/commands/snapshot.py b/codesage/cli/commands/snapshot.py index dc5875a..34fa0a7 100644 --- a/codesage/cli/commands/snapshot.py +++ b/codesage/cli/commands/snapshot.py @@ -19,15 +19,7 @@ "__pycache__", "node_modules", "vendor", "dist", "build", "target", } -DEFAULT_CONFIG = { - "snapshot": { - "versioning": { - "max_versions": 10, - "retention_days": 30 - } - } -} -SNAPSHOT_DIR = ".codesage/snapshots" +from codesage.config.defaults import SNAPSHOT_DIR, DEFAULT_SNAPSHOT_CONFIG def get_file_hash(path): with open(path, 'rb') as f: @@ -53,6 +45,56 @@ def snapshot(): from codesage.audit.models import AuditEvent + +def _create_snapshot_data(path): + file_snapshots = [] + for root, dirs, files in os.walk(path): + dirs[:] = [d for d in dirs if d not in DEFAULT_EXCLUDE_DIRS] + for file in files: + file_path = os.path.join(root, file) + language = detect_language(file_path) + + if language: + parser = create_parser(language) + with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: + source_code = f.read() + + ast_summary = parser.get_ast_summary(source_code) + complexity_metrics = parser.get_complexity_metrics(source_code) + else: + language = "unknown" + ast_summary=ASTSummary(function_count=0, class_count=0, import_count=0, comment_lines=0) + complexity_metrics=ComplexityMetrics(cyclomatic=0) + + file_snapshots.append(FileSnapshot( + path=file_path, + language=language, + hash=get_file_hash(file_path), + lines=len(open(file_path, encoding='utf-8', errors='ignore').readlines()), + ast_summary=ast_summary, + complexity_metrics=complexity_metrics, + )) + + total_size = sum(os.path.getsize(fs.path) for fs in file_snapshots) + + return ProjectSnapshot( + metadata=SnapshotMetadata( + version="", + timestamp=datetime.now(), + project_name=os.path.basename(os.path.abspath(path)), + file_count=len(file_snapshots), + total_size=total_size, + tool_version=tool_version, + config_hash="not_implemented", + git_commit=None + ), + files=file_snapshots, + global_metrics={}, + dependency_graph=DependencyGraph(edges=[]), + detected_patterns=[], + issues=[] + ) + @snapshot.command('create') @click.argument('path', type=click.Path(exists=True, dir_okay=True)) @click.option('--format', '-f', type=click.Choice(['json', 'python-semantic-digest']), default='json', help='Snapshot format.') @@ -126,66 +168,27 @@ def create(ctx, path, format, output, compress, language): click.echo(f"{language.capitalize()} semantic digest created at {output}") return - manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_CONFIG['snapshot']) + snapshot_data = _create_snapshot_data(path) - file_snapshots = [] - for root, dirs, files in os.walk(path): - dirs[:] = [d for d in dirs if d not in DEFAULT_EXCLUDE_DIRS] - for file in files: - file_path = os.path.join(root, file) - language = detect_language(file_path) + if output: + output_path = Path(output) + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, 'w') as f: + f.write(snapshot_data.model_dump_json(indent=2)) - if language: - parser = create_parser(language) - with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: - source_code = f.read() - - ast_summary = parser.get_ast_summary(source_code) - complexity_metrics = parser.get_complexity_metrics(source_code) - else: - language = "unknown" - ast_summary=ASTSummary(function_count=0, class_count=0, import_count=0, comment_lines=0) - complexity_metrics=ComplexityMetrics(cyclomatic=0) - - file_snapshots.append(FileSnapshot( - path=file_path, - language=language, - hash=get_file_hash(file_path), - lines=len(open(file_path, encoding='utf-8', errors='ignore').readlines()), - ast_summary=ast_summary, - complexity_metrics=complexity_metrics, - )) - - total_size = sum(os.path.getsize(fs.path) for fs in file_snapshots) - - snapshot_data = ProjectSnapshot( - metadata=SnapshotMetadata( - version="", - timestamp=datetime.now(), - project_name=os.path.basename(os.path.abspath(path)), - file_count=len(file_snapshots), - total_size=total_size, - tool_version=tool_version, - config_hash="not_implemented", - git_commit=None - ), - files=file_snapshots, - global_metrics={}, - dependency_graph=DependencyGraph(edges=[]), - detected_patterns=[], - issues=[] - ) - - if compress: - snapshot_path = manager.save_snapshot(snapshot_data, format) - with open(snapshot_path, 'rb') as f_in: - with gzip.open(f"{snapshot_path}.gz", 'wb') as f_out: - f_out.writelines(f_in) - os.remove(snapshot_path) - click.echo(f"Compressed snapshot created at {snapshot_path}.gz") + click.echo(f"Snapshot created at {output}") else: - snapshot_path = manager.save_snapshot(snapshot_data, format) - click.echo(f"Snapshot created at {snapshot_path}") + manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_SNAPSHOT_CONFIG['snapshot']) + if compress: + snapshot_path = manager.save_snapshot(snapshot_data, format) + with open(snapshot_path, 'rb') as f_in: + with gzip.open(f"{snapshot_path}.gz", 'wb') as f_out: + f_out.writelines(f_in) + os.remove(snapshot_path) + click.echo(f"Compressed snapshot created at {snapshot_path}.gz") + else: + snapshot_path = manager.save_snapshot(snapshot_data, format) + click.echo(f"Snapshot created at {snapshot_path}") finally: audit_logger.log( AuditEvent( @@ -206,7 +209,7 @@ def create(ctx, path, format, output, compress, language): @snapshot.command('list') def list_snapshots(): """List all available snapshots.""" - manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_CONFIG['snapshot']) + manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_SNAPSHOT_CONFIG['snapshot']) snapshots = manager.list_snapshots() if not snapshots: click.echo("No snapshots found.") @@ -218,7 +221,7 @@ def list_snapshots(): @click.argument('version') def show(version): """Show details of a specific snapshot.""" - manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_CONFIG['snapshot']) + manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_SNAPSHOT_CONFIG['snapshot']) snapshot_data = manager.load_snapshot(version) if not snapshot_data: click.echo(f"Snapshot {version} not found.", err=True) @@ -231,7 +234,7 @@ def cleanup(dry_run): """Clean up old snapshots.""" from datetime import timedelta - manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_CONFIG['snapshot']) + manager = SnapshotVersionManager(SNAPSHOT_DIR, DEFAULT_SNAPSHOT_CONFIG['snapshot']) if dry_run: index = manager._load_index() diff --git a/codesage/cli/commands/web_console.py b/codesage/cli/commands/web_console.py index b60c43f..9290303 100644 --- a/codesage/cli/commands/web_console.py +++ b/codesage/cli/commands/web_console.py @@ -1,6 +1,7 @@ import click import uvicorn from typing import Optional +from pathlib import Path from codesage.config.loader import load_config from codesage.config.web import WebConsoleConfig @@ -12,10 +13,12 @@ @click.command("web-console") @click.option("--config", "config_path", help="Path to a custom .codesage.yaml config file.") @click.pass_context -def web_console_command(ctx, config_path: Optional[str]) -> None: +def web_console(ctx, config_path: Optional[str]) -> None: """Launch the CodeSage web console.""" audit_logger = ctx.obj.audit_logger try: + if config_path is None: + config_path = str(Path.cwd()) loaded_config = load_config(config_path) web_config_dict = loaded_config.get("web", {}) web_config = WebConsoleConfig.model_validate(web_config_dict) diff --git a/codesage/cli/main.py b/codesage/cli/main.py index 37c06ad..b42705f 100644 --- a/codesage/cli/main.py +++ b/codesage/cli/main.py @@ -9,12 +9,12 @@ from .commands.config import config from .commands.report import report from .commands.llm_suggest import llm_suggest -from .commands.governance_plan import governance_plan_command -from .commands.jules_prompt import jules_prompt_command -from .commands.web_console import web_console_command -from .commands.history_snapshot import history_snapshot_command -from .commands.history_diff import history_diff_command -from .commands.history_trend import history_trend_command +from .commands.governance_plan import governance_plan +from .commands.jules_prompt import jules_prompt +from .commands.web_console import web_console +from .commands.history_snapshot import history_snapshot +from .commands.history_diff import history_diff +from .commands.history_trend import history_trend from .commands.org_report import org_report from .plugin_loader import load_plugins @@ -55,12 +55,12 @@ def main(ctx, config_path, verbose, no_color): main.add_command(config) main.add_command(report) main.add_command(llm_suggest) -main.add_command(governance_plan_command) -main.add_command(jules_prompt_command) -main.add_command(web_console_command) -main.add_command(history_snapshot_command) -main.add_command(history_diff_command) -main.add_command(history_trend_command) +main.add_command(governance_plan) +main.add_command(jules_prompt) +main.add_command(web_console) +main.add_command(history_snapshot) +main.add_command(history_diff) +main.add_command(history_trend) main.add_command(org_report) # Load plugin commands diff --git a/codesage/config/defaults.py b/codesage/config/defaults.py index 25f431f..10978f2 100644 --- a/codesage/config/defaults.py +++ b/codesage/config/defaults.py @@ -38,3 +38,14 @@ "audit": AuditConfig().model_dump(), "integrations": IntegrationsConfig().model_dump(), } + +SNAPSHOT_DIR = ".codesage/snapshots" + +DEFAULT_SNAPSHOT_CONFIG = { + "snapshot": { + "versioning": { + "max_versions": 10, + "retention_days": 30 + } + } +} diff --git a/codesage/org/aggregator.py b/codesage/org/aggregator.py index 86705c1..888d6b6 100644 --- a/codesage/org/aggregator.py +++ b/codesage/org/aggregator.py @@ -74,8 +74,7 @@ def _load_artifacts( if not report_summary: logger.info(f"No report found for {ref.name}, generating one from snapshot.") - generator = ReportGenerator.from_snapshot(snapshot, Path.cwd()) - report_summary = generator.get_summary() + report_summary, _ = ReportGenerator.from_snapshot(snapshot) regressions = [] if ref.history_root and Path(ref.history_root).exists(): diff --git a/codesage/snapshot/versioning.py b/codesage/snapshot/versioning.py index 9cce69b..47289e1 100644 --- a/codesage/snapshot/versioning.py +++ b/codesage/snapshot/versioning.py @@ -73,7 +73,7 @@ def _update_index(self, snapshot_path: str, metadata: SnapshotMetadata): index.append( { "version": metadata.version, - "timestamp": metadata.timestamp.isoformat(), + "timestamp": metadata.timestamp.astimezone(timezone.utc).isoformat(), "path": snapshot_path, "git_commit": metadata.git_commit, } @@ -85,10 +85,17 @@ def cleanup_expired_snapshots(self): index = self._load_index() now = datetime.now(timezone.utc) - valid_snapshots = [ - s for s in index - if now - datetime.fromisoformat(s["timestamp"]) <= timedelta(days=self.retention_days) - ] + valid_snapshots = [] + for s in index: + try: + ts = datetime.fromisoformat(s["timestamp"]) + if ts.tzinfo is None: + ts = ts.replace(tzinfo=timezone.utc) + if now - ts <= timedelta(days=self.retention_days): + valid_snapshots.append(s) + except ValueError: + # Skip malformed timestamps + continue if len(valid_snapshots) > self.max_versions: valid_snapshots = sorted( diff --git a/codesage/web/server.py b/codesage/web/server.py index 58ed96c..3ad7723 100644 --- a/codesage/web/server.py +++ b/codesage/web/server.py @@ -56,7 +56,7 @@ async def upload_snapshot(file: UploadFile = File(...)): snapshot_dir = Path(config.snapshot_path).parent # Or use default snapshot dir - from codesage.cli.commands.snapshot import SNAPSHOT_DIR, DEFAULT_CONFIG + from codesage.config.defaults import SNAPSHOT_DIR, DEFAULT_SNAPSHOT_CONFIG # We try to respect the configured path if it looks like a directory, otherwise default if Path(config.snapshot_path).is_dir(): @@ -64,7 +64,7 @@ async def upload_snapshot(file: UploadFile = File(...)): else: save_dir = SNAPSHOT_DIR - manager = SnapshotVersionManager(save_dir, DEFAULT_CONFIG['snapshot']) + manager = SnapshotVersionManager(save_dir, DEFAULT_SNAPSHOT_CONFIG['snapshot']) # SnapshotVersionManager expects a ProjectSnapshot object, so we need to parse the dict from codesage.snapshot.models import ProjectSnapshot From 77f0c7117aad09b0d628f06ebc34ff3b433c16d8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 14:44:11 +0000 Subject: [PATCH 2/3] fix: Ensure Python 3.10 compatibility This commit resolves an `ImportError` that occurred on Python 3.10 due to the use of `datetime.UTC`. The `datetime.UTC` constant was introduced in Python 3.11. To ensure backwards compatibility with Python 3.10 and earlier, this commit replaces all instances of `datetime.UTC` with the recommended `datetime.timezone.utc`. This change fixes the crash in the `codesage` CLI tool when running on older Python versions and has been verified by running the full test suite. --- codesage.db | Bin 32768 -> 32768 bytes codesage/audit/logger.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/codesage.db b/codesage.db index e52d9a69f6690b228cdd4e18f70b2443a086da66..cd330639b3c66b09815319d67b6def4a4136b8d7 100644 GIT binary patch delta 112 zcmV-$0FVEGfC7Mk0+1U4GLalZ0Wz^*q(1`|3Ko+GKq~?Y7O{ci2@6CP2mk>e0Tmxr z7n4y;JF{F$s3jB#2lxOE{|){O{R{jG`w998`3Ly1f#3%Nfqoa00e%z+F*G_eI65;h SlM!U(0Tz=1eiyS7dF=)_<09q& delta 72 zcmV-O0Jr~ufC7Mk0+1U4Fp(TX0Wh&(q(1`{3S5&1Kr69G#r;|K$ReioAfeiyS7dF=*cycysC diff --git a/codesage/audit/logger.py b/codesage/audit/logger.py index d440ad6..bfbfae7 100644 --- a/codesage/audit/logger.py +++ b/codesage/audit/logger.py @@ -1,5 +1,5 @@ import json -from datetime import datetime, UTC +from datetime import datetime, timezone from pathlib import Path from typing import Optional @@ -59,7 +59,7 @@ def _open_new_file(self) -> None: self._log_dir.mkdir(parents=True, exist_ok=True) self._log_dir_created = True - ts = datetime.now(UTC).strftime("%Y%m%d%H%M%S") + ts = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S") self._current_file = self._log_dir / f"audit_{ts}.log" self._current_file.touch() self._current_size = 0 From d87d2e1cfb13d23f84b604c876bce064c5cc8d65 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 15:15:18 +0000 Subject: [PATCH 3/3] chore: Revert .codesage.yaml to original state This commit reverts the `.codesage.yaml` file to its original state, removing the temporary modifications made for testing purposes. --- .codesage.yaml | 92 +++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 53 deletions(-) diff --git a/.codesage.yaml b/.codesage.yaml index 28b1c55..01711eb 100644 --- a/.codesage.yaml +++ b/.codesage.yaml @@ -1,66 +1,52 @@ +languages: + python: + extensions: [".py"] + go: + extensions: [".go"] + javascript: + extensions: [".js", ".jsx"] + typescript: + extensions: [".ts", ".tsx"] + +thresholds: + complexity: 20 + duplication: 10 + +ignore_paths: + - "node_modules/" + - "vendor/" + - "tests/" + analyzers: complexity: - file_threshold: 200 function_threshold: 10 + file_threshold: 200 dependency: - detect_cycles: true max_depth: 5 + detect_cycles: true patterns: - enabled_rules: - - singleton - - factory - - god_class -ignore_paths: -- node_modules/ -- vendor/ -- tests/ -languages: - go: - extensions: - - .go - javascript: - extensions: - - .js - - .jsx - python: - extensions: - - .py - typescript: - extensions: - - .ts - - .tsx -llm: - api_key: ${OPENAI_API_KEY} - enabled: true - model: gpt-4 - provider: openai - retries: 3 - temperature: 0.0 - timeout: 60 + enabled_rules: ["singleton", "factory", "god_class"] + snapshot: + output_dir: ".codesage/snapshots" + formats: ["json", "markdown"] compression: enabled: true - exclude_patterns: - - '*.test.go' - - '*_test.py' - formats: - - json - - markdown - markdown: - include_source_code: false - max_code_lines: 20 - template: default_report - output_dir: .codesage/snapshots + exclude_patterns: ["*.test.go", "*_test.py"] versioning: enabled: true max_versions: 10 retention_days: 30 -thresholds: - complexity: 20 - duplication: 10 -org: - projects: - - id: codesage - name: codesage - path: . - snapshot_path: v1.json + markdown: + template: "default_report" + include_source_code: false + max_code_lines: 20 + +llm: + enabled: true + provider: "openai" # "openai" or "anthropic" + model: "gpt-4" + api_key: "${OPENAI_API_KEY}" # Supports env var expansion in loader if implemented, otherwise use explicit key + temperature: 0.0 + timeout: 60 + retries: 3