forgeoptimizer 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. forgecli/__init__.py +4 -0
  2. forgecli/build/__init__.py +135 -0
  3. forgecli/build/apply.py +218 -0
  4. forgecli/build/caveman_optimize.py +37 -0
  5. forgecli/build/diff_extract.py +218 -0
  6. forgecli/build/llm.py +167 -0
  7. forgecli/build/optimize.py +37 -0
  8. forgecli/build/pipeline.py +76 -0
  9. forgecli/build/retrieval.py +157 -0
  10. forgecli/build/summarize.py +76 -0
  11. forgecli/build/test_run.py +75 -0
  12. forgecli/builder/__init__.py +11 -0
  13. forgecli/builder/builder.py +53 -0
  14. forgecli/builder/editor.py +36 -0
  15. forgecli/builder/formatter.py +31 -0
  16. forgecli/cli/__init__.py +5 -0
  17. forgecli/cli/bootstrap.py +281 -0
  18. forgecli/cli/commands_graph.py +149 -0
  19. forgecli/cli/commands_wrappers.py +80 -0
  20. forgecli/cli/daemon.py +744 -0
  21. forgecli/cli/main.py +234 -0
  22. forgecli/cli/ui.py +56 -0
  23. forgecli/config/__init__.py +28 -0
  24. forgecli/config/loader.py +85 -0
  25. forgecli/config/settings.py +206 -0
  26. forgecli/config/writer.py +90 -0
  27. forgecli/core/__init__.py +35 -0
  28. forgecli/core/container.py +68 -0
  29. forgecli/core/context.py +54 -0
  30. forgecli/core/credentials.py +114 -0
  31. forgecli/core/errors.py +27 -0
  32. forgecli/core/events.py +67 -0
  33. forgecli/core/logging.py +47 -0
  34. forgecli/core/models.py +214 -0
  35. forgecli/core/plugins.py +54 -0
  36. forgecli/core/service.py +22 -0
  37. forgecli/docs/__init__.py +5 -0
  38. forgecli/docs/generator.py +115 -0
  39. forgecli/engine/__init__.py +105 -0
  40. forgecli/engine/context.py +163 -0
  41. forgecli/engine/defaults.py +89 -0
  42. forgecli/engine/events.py +185 -0
  43. forgecli/engine/execution.py +519 -0
  44. forgecli/engine/plugins.py +145 -0
  45. forgecli/engine/runner.py +158 -0
  46. forgecli/engine/stages/__init__.py +33 -0
  47. forgecli/engine/stages/caveman_optimizer.py +47 -0
  48. forgecli/engine/stages/context_optimizer.py +44 -0
  49. forgecli/engine/stages/execution_engine_stage.py +102 -0
  50. forgecli/engine/stages/git_engine.py +30 -0
  51. forgecli/engine/stages/intent_analyzer.py +38 -0
  52. forgecli/engine/stages/model_router.py +65 -0
  53. forgecli/engine/stages/planning_engine.py +45 -0
  54. forgecli/engine/stages/repository_analyzer.py +54 -0
  55. forgecli/engine/stages/validation_engine.py +87 -0
  56. forgecli/git/__init__.py +9 -0
  57. forgecli/git/repo.py +55 -0
  58. forgecli/git/service.py +45 -0
  59. forgecli/graph/__init__.py +56 -0
  60. forgecli/graph/backend_graphify.py +448 -0
  61. forgecli/graph/edge.py +19 -0
  62. forgecli/graph/graph.py +85 -0
  63. forgecli/graph/graphify.py +405 -0
  64. forgecli/graph/indexer.py +82 -0
  65. forgecli/graph/node.py +47 -0
  66. forgecli/graph/repository.py +164 -0
  67. forgecli/memory/__init__.py +12 -0
  68. forgecli/memory/cache.py +61 -0
  69. forgecli/memory/history.py +136 -0
  70. forgecli/memory/store.py +85 -0
  71. forgecli/optimizer/__init__.py +13 -0
  72. forgecli/optimizer/caveman/__init__.py +169 -0
  73. forgecli/optimizer/caveman/cli.py +62 -0
  74. forgecli/optimizer/caveman/decorator.py +67 -0
  75. forgecli/optimizer/caveman/factory.py +51 -0
  76. forgecli/optimizer/caveman/ruleset.py +156 -0
  77. forgecli/optimizer/caveman/state.py +50 -0
  78. forgecli/optimizer/chunker.py +85 -0
  79. forgecli/optimizer/optimizer.py +81 -0
  80. forgecli/optimizer/ponytail/__init__.py +181 -0
  81. forgecli/optimizer/ponytail/cli.py +159 -0
  82. forgecli/optimizer/ponytail/decorator.py +70 -0
  83. forgecli/optimizer/ponytail/factory.py +51 -0
  84. forgecli/optimizer/ponytail/ruleset.py +168 -0
  85. forgecli/optimizer/ponytail/state.py +51 -0
  86. forgecli/optimizer/ranker.py +37 -0
  87. forgecli/optimizer/summarizer.py +44 -0
  88. forgecli/orchestrator/__init__.py +706 -0
  89. forgecli/planner/__init__.py +56 -0
  90. forgecli/planner/agent.py +61 -0
  91. forgecli/planner/plan.py +65 -0
  92. forgecli/planner/planner.py +17 -0
  93. forgecli/planner/render.py +267 -0
  94. forgecli/planner/serialize.py +104 -0
  95. forgecli/planner/software.py +832 -0
  96. forgecli/platform/__init__.py +91 -0
  97. forgecli/platform/core.py +201 -0
  98. forgecli/platform/deps.py +361 -0
  99. forgecli/platform/paths.py +234 -0
  100. forgecli/platform/shell.py +176 -0
  101. forgecli/platform/update.py +253 -0
  102. forgecli/plugins/__init__.py +249 -0
  103. forgecli/prompts/__init__.py +11 -0
  104. forgecli/prompts/loader.py +28 -0
  105. forgecli/prompts/registry.py +32 -0
  106. forgecli/prompts/renderer.py +23 -0
  107. forgecli/providers/__init__.py +39 -0
  108. forgecli/providers/anthropic.py +207 -0
  109. forgecli/providers/base.py +204 -0
  110. forgecli/providers/builtin.py +26 -0
  111. forgecli/providers/conversation.py +74 -0
  112. forgecli/providers/google.py +290 -0
  113. forgecli/providers/http_base.py +207 -0
  114. forgecli/providers/mock.py +111 -0
  115. forgecli/providers/openai.py +206 -0
  116. forgecli/providers/openai_compatible.py +787 -0
  117. forgecli/providers/router.py +340 -0
  118. forgecli/providers/router_state.py +89 -0
  119. forgecli/review/__init__.py +45 -0
  120. forgecli/review/analyzer.py +124 -0
  121. forgecli/review/analyzers/__init__.py +1 -0
  122. forgecli/review/analyzers/architecture.py +255 -0
  123. forgecli/review/analyzers/complexity.py +162 -0
  124. forgecli/review/analyzers/dead_code.py +255 -0
  125. forgecli/review/analyzers/duplicates.py +161 -0
  126. forgecli/review/analyzers/performance.py +161 -0
  127. forgecli/review/analyzers/security.py +244 -0
  128. forgecli/review/finding.py +68 -0
  129. forgecli/review/report.py +321 -0
  130. forgecli/review/repository.py +130 -0
  131. forgecli/review/suggestions.py +98 -0
  132. forgecli/runtime/__init__.py +6 -0
  133. forgecli/runtime/cache_store.py +75 -0
  134. forgecli/runtime/mcp_config.py +118 -0
  135. forgecli/runtime/prepare.py +203 -0
  136. forgecli/runtime/wrappers.py +150 -0
  137. forgecli/sdk/__init__.py +132 -0
  138. forgecli/sdk/events.py +206 -0
  139. forgecli/sdk/interfaces.py +282 -0
  140. forgecli/sdk/loader.py +239 -0
  141. forgecli/sdk/manager.py +678 -0
  142. forgecli/sdk/manifest.py +395 -0
  143. forgecli/sdk/sandbox.py +247 -0
  144. forgecli/sdk/version.py +313 -0
  145. forgecli/templates/__init__.py +9 -0
  146. forgecli/templates/engine.py +37 -0
  147. forgecli/templates/registry.py +32 -0
  148. forgecli/utils/__init__.py +19 -0
  149. forgecli/utils/fs.py +121 -0
  150. forgecli/utils/ids.py +11 -0
  151. forgecli/utils/io.py +27 -0
  152. forgecli/utils/paths.py +78 -0
  153. forgecli/utils/stats.py +179 -0
  154. forgecli/utils/timing.py +25 -0
  155. forgeoptimizer-0.1.0.dist-info/METADATA +177 -0
  156. forgeoptimizer-0.1.0.dist-info/RECORD +159 -0
  157. forgeoptimizer-0.1.0.dist-info/WHEEL +4 -0
  158. forgeoptimizer-0.1.0.dist-info/entry_points.txt +2 -0
  159. forgeoptimizer-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,179 @@
1
+ """Helper utilities for tracking and displaying Forge CLI optimization statistics."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ from forgecli.runtime.prepare import PreparedRuntime, _scan_repo_light
11
+ from forgecli.utils.paths import ProjectPaths
12
+
13
+
14
+ def estimate_tokens(text: str) -> int:
15
+ """Estimate the number of tokens in the given text (rule of thumb: 4 chars/token)."""
16
+ if not text:
17
+ return 0
18
+ return max(1, len(text) // 4)
19
+
20
+
21
+ def count_files_in_layout(context_text: str) -> int:
22
+ """Count the number of files present in the Project layout section of the context."""
23
+ lines = context_text.splitlines()
24
+ file_count = 0
25
+ in_layout = False
26
+ for line in lines:
27
+ if "Project layout (shallow scan):" in line:
28
+ in_layout = True
29
+ continue
30
+ if in_layout:
31
+ if not line.strip():
32
+ # Section ends on first empty line
33
+ continue
34
+ if line.startswith("#") or "Knowledge graph" in line:
35
+ # Reached next section
36
+ break
37
+ clean = line.strip()
38
+ # If it doesn't end with a slash, it's a file, not a directory
39
+ if clean and not clean.endswith("/"):
40
+ file_count += 1
41
+ return file_count
42
+
43
+
44
+ def count_total_files(root: Path) -> int:
45
+ """Recursively count all non-hidden, non-skipped files in the repository."""
46
+ skip_dirs = {
47
+ ".git",
48
+ ".venv",
49
+ "__pycache__",
50
+ "node_modules",
51
+ "dist",
52
+ "build",
53
+ ".forge",
54
+ "graphify-out",
55
+ ".mypy_cache",
56
+ ".pytest_cache",
57
+ ".ruff_cache",
58
+ }
59
+ count = 0
60
+ try:
61
+ for p in root.rglob("*"):
62
+ try:
63
+ rel = p.relative_to(root)
64
+ if any(part.startswith(".") or part in skip_dirs for part in rel.parts[:-1]):
65
+ continue
66
+ if p.is_file() and not p.name.startswith("."):
67
+ count += 1
68
+ except (ValueError, OSError):
69
+ continue
70
+ except OSError:
71
+ pass
72
+ return count
73
+
74
+
75
+ def get_graph_build_time(repo_root: Path) -> float | None:
76
+ """Load the recorded Graphify build time if available."""
77
+ build_time_file = repo_root / "graphify-out" / "build_time.json"
78
+ if build_time_file.is_file():
79
+ try:
80
+ with open(build_time_file, encoding="utf-8") as f:
81
+ data = json.load(f)
82
+ return data.get("build_time")
83
+ except Exception:
84
+ pass
85
+ return None
86
+
87
+
88
+ def record_wrapper_stats(
89
+ wrapper_id: str,
90
+ repo_root: Path,
91
+ prepared: PreparedRuntime,
92
+ prep_time: float,
93
+ ) -> None:
94
+ """Record context preparation and token optimization statistics to a history file."""
95
+ try:
96
+ raw_context = _scan_repo_light(repo_root)
97
+ optimized_context = prepared.context_summary
98
+
99
+ orig_tokens = estimate_tokens(raw_context)
100
+ opt_tokens = estimate_tokens(optimized_context)
101
+
102
+ # Enforce non-negative token reduction
103
+ reduction_tokens = max(0, orig_tokens - opt_tokens)
104
+ reduction_pct = (reduction_tokens / orig_tokens * 100) if orig_tokens > 0 else 0.0
105
+
106
+ is_reduced = reduction_tokens > 0
107
+ prompt_opt_status = "Enabled" if is_reduced else "Disabled"
108
+ token_opt_status = "Enabled" if is_reduced else "Disabled"
109
+
110
+ files_scanned = count_total_files(repo_root)
111
+ relevant_files = count_files_in_layout(optimized_context)
112
+ excluded_files = max(0, files_scanned - relevant_files)
113
+
114
+ kg_cache = (
115
+ "Cache Hit" if (repo_root / "graphify-out" / "graph.json").is_file() else "Cache Miss"
116
+ )
117
+ cache_status = "Cache Hit" if prepared.from_cache else "Cache Miss"
118
+ graph_build_time = get_graph_build_time(repo_root)
119
+
120
+ stats_data = {
121
+ "cli_used": wrapper_id,
122
+ "repo_name": repo_root.name,
123
+ "kg_cache": kg_cache,
124
+ "prep_time": prep_time,
125
+ "graph_build_time": graph_build_time,
126
+ "original_tokens": orig_tokens,
127
+ "optimized_tokens": opt_tokens,
128
+ "reduction_tokens": reduction_tokens,
129
+ "reduction_pct": reduction_pct,
130
+ "files_scanned": files_scanned,
131
+ "files_count": relevant_files,
132
+ "excluded_files": excluded_files,
133
+ "prompt_opt_status": prompt_opt_status,
134
+ "token_opt_status": token_opt_status,
135
+ "cache_status": cache_status,
136
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
137
+ }
138
+
139
+ # Save to ProjectPaths.data_dir / "stats_history.json"
140
+ paths = ProjectPaths.from_env()
141
+ paths.ensure()
142
+ stats_file = paths.data_dir / "stats_history.json"
143
+
144
+ history = []
145
+ if stats_file.exists():
146
+ try:
147
+ with open(stats_file, encoding="utf-8") as f:
148
+ history = json.load(f)
149
+ except Exception:
150
+ pass
151
+
152
+ if not isinstance(history, list):
153
+ history = []
154
+
155
+ history.insert(0, stats_data)
156
+ history = history[:10] # Maintain only the last 10 runs
157
+
158
+ with open(stats_file, "w", encoding="utf-8") as f:
159
+ json.dump(history, f, indent=2, ensure_ascii=False)
160
+
161
+ except Exception:
162
+ # Prevent any stats failure from interrupting/slowing the CLI execution
163
+ pass
164
+
165
+
166
+ def get_stats_history() -> list[dict[str, Any]]:
167
+ """Retrieve the stored optimization statistics history."""
168
+ try:
169
+ paths = ProjectPaths.from_env()
170
+ stats_file = paths.data_dir / "stats_history.json"
171
+ if not stats_file.exists():
172
+ return []
173
+ with open(stats_file, encoding="utf-8") as f:
174
+ history = json.load(f)
175
+ if isinstance(history, list):
176
+ return history
177
+ except Exception:
178
+ pass
179
+ return []
@@ -0,0 +1,25 @@
1
+ """Simple timing utilities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import time
6
+ from collections.abc import Iterator
7
+ from contextlib import contextmanager
8
+ from typing import Any
9
+
10
+
11
+ @contextmanager
12
+ def Timer(label: str = "elapsed") -> Iterator[dict[str, Any]]:
13
+ """Context manager that measures wall-clock duration.
14
+
15
+ Usage:
16
+ with Timer() as t:
17
+ ...
18
+ print(t["seconds"])
19
+ """
20
+ result: dict[str, Any] = {"label": label, "seconds": 0.0}
21
+ started = time.perf_counter()
22
+ try:
23
+ yield result
24
+ finally:
25
+ result["seconds"] = time.perf_counter() - started
@@ -0,0 +1,177 @@
1
+ Metadata-Version: 2.4
2
+ Name: forgeoptimizer
3
+ Version: 0.1.0
4
+ Summary: Forge — AI optimization runtime. Fast prompt and token optimization for Claude Code, Codex, Cursor, OpenCode, and CommandCode CLI.
5
+ Project-URL: Homepage, https://github.com/mdshzb04/Forge
6
+ Project-URL: Repository, https://github.com/mdshzb04/Forge
7
+ Project-URL: Documentation, https://github.com/mdshzb04/Forge#readme
8
+ Project-URL: Issues, https://github.com/mdshzb04/Forge/issues
9
+ Author: Forge Authors
10
+ License: MIT License
11
+
12
+ Copyright (c) 2025 Forge Authors
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: ai,claude,cli,codex,cursor,developer-tools
33
+ Classifier: Development Status :: 5 - Production/Stable
34
+ Classifier: Environment :: Console
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Operating System :: OS Independent
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Topic :: Software Development
42
+ Requires-Python: >=3.12
43
+ Requires-Dist: aiofiles>=23.2.1
44
+ Requires-Dist: click>=8.1.7
45
+ Requires-Dist: cryptography>=42.0.5
46
+ Requires-Dist: fastapi>=0.100.0
47
+ Requires-Dist: gitpython>=3.1.42
48
+ Requires-Dist: httpx>=0.27.0
49
+ Requires-Dist: keyring>=25.2.0
50
+ Requires-Dist: platformdirs>=4.2.0
51
+ Requires-Dist: pydantic-settings>=2.2.0
52
+ Requires-Dist: pydantic>=2.6.0
53
+ Requires-Dist: pyyaml>=6.0
54
+ Requires-Dist: rich>=13.7.0
55
+ Requires-Dist: tree-sitter-languages>=1.10.0
56
+ Requires-Dist: tree-sitter>=0.21.0
57
+ Requires-Dist: typer>=0.12.0
58
+ Requires-Dist: uvicorn>=0.20.0
59
+ Provides-Extra: dev
60
+ Requires-Dist: build>=1.0.0; extra == 'dev'
61
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
62
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
63
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
64
+ Requires-Dist: pytest-timeout>=2.3.0; extra == 'dev'
65
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
66
+ Requires-Dist: respx>=0.21.0; extra == 'dev'
67
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
68
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
69
+ Requires-Dist: types-pyyaml; extra == 'dev'
70
+ Description-Content-Type: text/markdown
71
+
72
+ # Forge
73
+
74
+ Forge is an AI optimization runtime. It prepares your repository context at light speed — prompt optimization and token compression — then launches the AI CLI you already use.
75
+
76
+ Install:
77
+
78
+ **Development:**
79
+ ```bash
80
+ uv tool install .
81
+ ```
82
+
83
+ **Release:**
84
+ ```bash
85
+ uv tool install forgectx
86
+ ```
87
+
88
+ The command is `forge`.
89
+
90
+ ## Convenience Wrappers vs. Core MCP Runtime
91
+
92
+ Forge provides two primary interfaces to connect with your AI coding tools:
93
+ 1. **Convenience Wrappers** (`forge claude`, `forge cursor`, etc.): Commands that automatically prepare/optimize context, update local and global configurations, and launch the target AI CLI under an optimized environment.
94
+ 2. **Core MCP Runtime** (`forge mcp`): The standard Model Context Protocol (MCP) interface that compatible AI clients communicate with over stdio.
95
+
96
+ ## Commands
97
+
98
+ | Command | Type | Description |
99
+ | -------- | ---- | ----------- |
100
+ | `forge claude` | Wrapper | Launch Claude Code with optimized context and auto-registered MCP |
101
+ | `forge codex` | Wrapper | Launch Codex CLI with optimized context and auto-registered MCP |
102
+ | `forge cursor` | Wrapper | Launch Cursor CLI with optimized context and auto-registered MCP |
103
+ | `forge opencode` | Wrapper | Launch OpenCode CLI with optimized context and auto-registered MCP |
104
+ | `forge commandcode` | Wrapper | Launch CommandCode CLI with optimized context and auto-registered MCP |
105
+ | `forge antigravity` | Wrapper | Launch Antigravity CLI with optimized context and auto-registered MCP |
106
+ | `forge mcp` | Core Runtime | Start the stdio Model Context Protocol (MCP) server |
107
+ | `forge start` | Daemon | Start the background context optimization daemon |
108
+ | `forge graph build` | Tool | Build a full knowledge graph via Graphify (optional) |
109
+ | `forge --version` | Tool | Show version |
110
+
111
+ > [!NOTE]
112
+ > When launching convenience wrappers, prompts or extra positional arguments are not supported directly (e.g. `forge claude "some prompt"` is blocked). Run the wrapper command without arguments to launch the tool's interactive session directly. Use the `--refresh` option to bypass the cache:
113
+ > ```bash
114
+ > forge claude --refresh
115
+ > ```
116
+
117
+ ## Model Context Protocol (MCP) Integration
118
+
119
+ Forge automatically registers its MCP server globally and project-locally for launched clients (updating `~/.claude.json`, `~/.cursor/mcp.json`, and project `.mcp.json` files).
120
+
121
+ ### Exposed Tools
122
+ Forge exposes the following schema tools over MCP:
123
+ * `get_optimized_context` — Retrieve the fully optimized and token-compressed repository context.
124
+ * `get_summary` — Retrieve a summary of the repository layout, size, and file list.
125
+ * `get_dependency_graph` — Retrieve module/file import relationships.
126
+ * `file_lookup` — Query individual file contents.
127
+ * `symbol_lookup` — Find definition locations of symbols (classes/functions).
128
+ * `semantic_search` — Keyword/phrase search across codebase chunks.
129
+
130
+ > [!IMPORTANT]
131
+ > **Client Behavior Notice:** While Forge exposes these tools to the MCP client, whether and when they are invoked depends entirely on the AI client's internal orchestration logic. Forge makes these capabilities available, but the client decides which tool to call.
132
+
133
+
134
+
135
+ ## Environment variables
136
+
137
+ Wrappers export:
138
+
139
+ | Variable | Purpose |
140
+ | -------- | -------- |
141
+ | `FORGE_CONTEXT` | Optimized text context |
142
+ | `FORGE_CONTEXT_FILE` | Path to the optimized context file |
143
+ | `FORGE_REPO_ROOT` | Detected repository root |
144
+
145
+ ## Development
146
+
147
+ ```bash
148
+ git clone https://github.com/mdshzb04/Forge
149
+ cd Forge
150
+ python -m venv .venv && source .venv/bin/activate
151
+ pip install -e ".[dev]"
152
+ pytest
153
+ ruff check forgecli tests
154
+ ```
155
+
156
+ ## Release
157
+
158
+ Push a version tag to publish to TestPyPI and PyPI:
159
+
160
+ ```bash
161
+ git tag v0.1.0
162
+ git push origin v0.1.0
163
+ ```
164
+
165
+ Publish jobs run **only on `v*` tags**. On regular pushes to `main`, those jobs show as **Skipped** — that is expected, not a failure.
166
+
167
+ Configure GitHub environments `testpypi` and `pypi` with PyPI trusted publishing for package name `forgectx`.
168
+
169
+ ---
170
+
171
+ <img width="1854" height="1005" alt="image" src="https://github.com/user-attachments/assets/03f3c2e2-424c-4784-8a59-b2b0f4b99447" />
172
+
173
+ <img width="1854" height="1005" alt="image" src="https://github.com/user-attachments/assets/6eb06d10-6f1f-4648-b679-028368362c24" />
174
+
175
+ ## License
176
+
177
+ [MIT](LICENSE)
@@ -0,0 +1,159 @@
1
+ forgecli/__init__.py,sha256=xmp4x8aITK8gag1_WQeX8YNmCcZgpgfeuKT5YSnHHD0,87
2
+ forgecli/build/__init__.py,sha256=nCsFRQ7Fk6XUPZFNmjxOi5Mxly89AiZE1zH11yaXvUM,3998
3
+ forgecli/build/apply.py,sha256=4tUwOdYSl5eVcoKHa2QFzfCZu4oJytgtHPIg0zsKUpo,7156
4
+ forgecli/build/caveman_optimize.py,sha256=_Ry1cEzAmAGNqPgWPtEy8VWIqCBFBHxi4W8SW7-sTmk,1442
5
+ forgecli/build/diff_extract.py,sha256=Pft7nFjCSn4I8IucQMZuIclpnqmtSKIJbV8pDog_kQ4,7713
6
+ forgecli/build/llm.py,sha256=sPoaEOCBrkDXx-UNfCMwgRqgwCGIbtuNwGD_-bfeHrc,5958
7
+ forgecli/build/optimize.py,sha256=qgaAClaCcULSzO6JvGkNV8dl5VSx_eXUuhvjApNk2ew,1342
8
+ forgecli/build/pipeline.py,sha256=KzSBspZtsbsiwoh_TXGPci6Y0Z03jlew2mEQInqAGZU,2484
9
+ forgecli/build/retrieval.py,sha256=Uh8-0DWoJUx1ORChIPA_wa2BNI3m9EohaKLrjLRtShA,4622
10
+ forgecli/build/summarize.py,sha256=zW3xTL-5dOypr8daN1WVfDSGNSw-1j-e5DsobZeoJ4E,2574
11
+ forgecli/build/test_run.py,sha256=WzboaYrfzhLJ5wym-K1kkc9C7hdRa13olU_dVXQnMmo,2200
12
+ forgecli/builder/__init__.py,sha256=SEFEtlumPsziNHHFAt85CI8QdroxOlGFjViA0t4lDxI,260
13
+ forgecli/builder/builder.py,sha256=HAOv8nhUjjHe83WryYETwOjGeDlnZdYGg2MuF9KxZYM,1456
14
+ forgecli/builder/editor.py,sha256=J1NOFFJ_n5KgzS9zGbGOY5SGSWUO43wsX6Y9vzcHE7I,919
15
+ forgecli/builder/formatter.py,sha256=A2ty_Gn9ZwW_v2Y-JsdTa0orQ-4GMlExKdpc7sj94dU,848
16
+ forgecli/cli/__init__.py,sha256=qWTHdenUK0k_M-W6uZXuQKHeXje1F8qolRUxNYrtyEQ,97
17
+ forgecli/cli/bootstrap.py,sha256=C1r35j7EEm-0CRgJW36l-J1PivBo38dgdfSf2al1mKE,9607
18
+ forgecli/cli/commands_graph.py,sha256=txWz1GhxusLLvzJzj3vc97iS_g5F2kZlnRT9EfCGL2k,4934
19
+ forgecli/cli/commands_wrappers.py,sha256=E66YPbF3NvQmnmABDsLgBWkRZkVcDGvABTG7S4Enn3I,2752
20
+ forgecli/cli/daemon.py,sha256=3z-aXke-HfTk4k_NSob7yM6dZtR4KOcrryIeuO09Q_M,30477
21
+ forgecli/cli/main.py,sha256=bj2TOSNV2FzxnUIvCw9_1AukmYKBsFOtxX1T_Kf33OM,8681
22
+ forgecli/cli/ui.py,sha256=kI4wjdnP-_hkmxiQqv0nyrdSOe79DYJ5vGKE9OuLEfo,1457
23
+ forgecli/config/__init__.py,sha256=VHjyEkDdIwIyq0WuD2WV_f9cE0ZxE3SJacrr7QHxQKY,766
24
+ forgecli/config/loader.py,sha256=hCOOY0XIWNjzSRuKYFB3SoD3d4KEMCRlxDHgZFP55X8,3109
25
+ forgecli/config/settings.py,sha256=zmxSg59iqMMF0zEdbUymZCPyN5Di0bZCh-PJRA6b1g0,5864
26
+ forgecli/config/writer.py,sha256=IUst_UDgQyGEdkwzml03hVZfNLHoczFMkwdAAHmipcE,3115
27
+ forgecli/core/__init__.py,sha256=IJ9zeHVxA6ZYrszuWJO1NzvyfgJcdmx6Q0Z4IUbJ9mo,852
28
+ forgecli/core/container.py,sha256=Wbxl9hO1q4jw8Nbwt1jzorNSTHem0Oh_QHLEPuovnzU,2494
29
+ forgecli/core/context.py,sha256=W97kjPovcPdbJQv8q43XWp2ypIkLI9lldhBSX_u9CF0,1814
30
+ forgecli/core/credentials.py,sha256=JjI_I5vDqgj2FoRKLjHtIyElL77xXhOv0M6XJ83sHKI,3215
31
+ forgecli/core/errors.py,sha256=rjwUEVA-Od3llf9LcWLXe1NLuMSMUKZJPtkzHcvRUKM,689
32
+ forgecli/core/events.py,sha256=Hi4EVUcG5Km4_Z6jRY_hln0rvemkjh0cbQR0kJccUU8,2521
33
+ forgecli/core/logging.py,sha256=rhOhU5q9vPAxcX-7nt2IWI1plYPBTNzsABu3WvAvPEc,1390
34
+ forgecli/core/models.py,sha256=yu-08PDLrhmKk-0OYRlc378Ong_3pMyKkyiOnix8R80,10524
35
+ forgecli/core/plugins.py,sha256=tdacOeQGVUHXQE0NAEfoARMPgchOIvRLxiQryhHUgZA,1784
36
+ forgecli/core/service.py,sha256=Jr-91BfdyAxauk0bOypU6NRDgW7_RU0VOYiMZrPJ9_M,693
37
+ forgecli/docs/__init__.py,sha256=1TQsopiZP_tC4_6QgZ64tMBCfkYdQ960lQZAJnd4SkU,124
38
+ forgecli/docs/generator.py,sha256=fnxqtk1KOzoqk5AylhSL8LTMGDZMDrHsicSG-McdqtI,4222
39
+ forgecli/engine/__init__.py,sha256=a1qjkKBgacYhLMTWSpy_Jo6ScMNiY9GNdYyN05VVb7E,2723
40
+ forgecli/engine/context.py,sha256=odwBR_PMcPohY3leYjY8gQueYandqxZVHJIHSibl--U,5254
41
+ forgecli/engine/defaults.py,sha256=obnDakOBycUDo0ocZgm3OVwm9IX3d_qOTcmYxe6nLMw,2931
42
+ forgecli/engine/events.py,sha256=P_5YGqZcRY980iPDjaq2xV_mzJh2nutAWLOIJmYoqt4,5840
43
+ forgecli/engine/execution.py,sha256=xUHYfYjahOjMNmF8lGioie3J6X-82KU6vQ-eirBxCmQ,16544
44
+ forgecli/engine/plugins.py,sha256=7Ks4l-KYaV78GLuUAb4IJjE3xkZtqPz_8AJ6jPbzIqY,4532
45
+ forgecli/engine/runner.py,sha256=wQhXBY7uO6YoExnKat6xfO1t5hSRy3moetUCCBygGDA,5444
46
+ forgecli/engine/stages/__init__.py,sha256=HKfqPiVrJY7tv6cVVuOfBV0gdZL-VmSzxJJ8htL13fE,1373
47
+ forgecli/engine/stages/caveman_optimizer.py,sha256=rHO6xJh4q8_kBMm1qVzhmx0LXqXyXAJvHXhBMizfxLk,1647
48
+ forgecli/engine/stages/context_optimizer.py,sha256=O-Q3EhwMhSw5-zHZPbysFRak8hxK-qwn8I-tlOFfN5I,1457
49
+ forgecli/engine/stages/execution_engine_stage.py,sha256=t4-CaF5M4MulKEwjbUQXy82kxqtOuGmh42f6la4b4FI,3982
50
+ forgecli/engine/stages/git_engine.py,sha256=BrBE89V8e-AmTPPDJg-QKELSgcYAZ4jnAOuPg881MfE,877
51
+ forgecli/engine/stages/intent_analyzer.py,sha256=whjqOl-_jo_vax0HmiBgzxaD_ue5-a0i0wGtUY6WsyI,1324
52
+ forgecli/engine/stages/model_router.py,sha256=WfC_x5cyiLxCW-wVrs4Ofp84bno8Eh8LO1J8Rh2krA8,2200
53
+ forgecli/engine/stages/planning_engine.py,sha256=J7pVN5jgx7hGlDylAtLXzqfFDJ76MNnrBFfWqxfatoM,1478
54
+ forgecli/engine/stages/repository_analyzer.py,sha256=Vu9kaaigOXB2Drea5wCppTq_7cNoIrBOl-Uk0KhwZMw,1842
55
+ forgecli/engine/stages/validation_engine.py,sha256=X35TxWFIsUiNKJ4McjZ8aL2RmRGG5PQ2dSChrAeyaLA,3339
56
+ forgecli/git/__init__.py,sha256=YSr-vvYZspcADVgTLbV80Hwap5XKMSiIfkXnK-M_vaM,185
57
+ forgecli/git/repo.py,sha256=UNPncjPrToGkL2_VDaUsJ2OQ3sNncVnXihg14zj5JjQ,1536
58
+ forgecli/git/service.py,sha256=0JVll8910JANFVdr3sgnpK1aKjoNlcLVfLeNvm4Xd1w,1251
59
+ forgecli/graph/__init__.py,sha256=8bsg-nMEBgmwz_pdthKYy2YNzdZNH_T2ViQxf-lO8js,1393
60
+ forgecli/graph/backend_graphify.py,sha256=fvIMkm9-WtocX5iIORHQaaYnmhQiJecc_7AxjIImJE0,15445
61
+ forgecli/graph/edge.py,sha256=s7AHRen_FYqm1uckUGcZ7SFFzxHZs-0VsuDTyBviiMo,400
62
+ forgecli/graph/graph.py,sha256=fw7x-BdwmPL5oxj56RBPyWeDlE7c0UvoAIQSPsh7jfQ,2925
63
+ forgecli/graph/graphify.py,sha256=L3sq_Up8pLsW7Ds2ZPZA2TEZLpWUlCz4EnfYqrS4JQ8,13175
64
+ forgecli/graph/indexer.py,sha256=dIEyGKtNaU13I6DjEJ-bgGjXQ3aSB8WxEirCLIP31TI,2595
65
+ forgecli/graph/node.py,sha256=lyWHsFwWfPUjcp7gBeYTo_nRrpNhUzbjrcOeYldkcdM,1045
66
+ forgecli/graph/repository.py,sha256=c-CGdV-7sxeZ3-mANxHkgjg-ZTsOmjZx_iw8svWo3yI,4833
67
+ forgecli/memory/__init__.py,sha256=GCoYrZazysef6LlEWYogmdL4RY5fDBSODVmGqEf4XKw,301
68
+ forgecli/memory/cache.py,sha256=phYGgj4_2f9uPeHTNbbsb_LsCK3TC3sCtY7tieGYzEM,1776
69
+ forgecli/memory/history.py,sha256=Zkn3ktwmkhCOQjra4ccLJHmDf1RikiTR4ZdPQ3QtGTE,4188
70
+ forgecli/memory/store.py,sha256=StfqCSueUKfJoV0vHI_0A0DMMXUIW6FuHiR1u2G65ug,2674
71
+ forgecli/optimizer/__init__.py,sha256=A_YnsdqL2d69pMyM9SNvTXaYLOkPuOIO-r3DcVl2fW4,372
72
+ forgecli/optimizer/chunker.py,sha256=9Kv-wby8GLxrSLDo0UcrW6DEDcGn9erj49YHJ_qyhQg,2358
73
+ forgecli/optimizer/optimizer.py,sha256=EeUJh3eQHJMpytShEPqxLESxFN_5xPK9pMMbumWVuG4,2363
74
+ forgecli/optimizer/ranker.py,sha256=FWs21UctWstLJNXAwFak68fVcb4eA5o0EqZpTc7BmOw,1301
75
+ forgecli/optimizer/summarizer.py,sha256=PoqzTmHZNp0NVrfRyboda9HOBW6O5Z_q48zGw_zIk_g,1515
76
+ forgecli/optimizer/caveman/__init__.py,sha256=V-uP-_xDzb_OgN_jqMFED_RoBIv0gi_67zTlghC_JyE,5925
77
+ forgecli/optimizer/caveman/cli.py,sha256=wHZZWnPZSHakvLWeDqdAw-3S5p-9r6zD8ecKOTAqg9Y,1968
78
+ forgecli/optimizer/caveman/decorator.py,sha256=yIM2wZcD3ZxfkuR-LqSxW_4Lo5QEpYg0S9MByit5pZc,1989
79
+ forgecli/optimizer/caveman/factory.py,sha256=rTLo7rQfHawdcXAcLgF3YohKqtREZ3c3Yq3KLmPp0Rs,1593
80
+ forgecli/optimizer/caveman/ruleset.py,sha256=Xs10HADmR2enj5pI6hL-tUOu-5ejmJl8u4ybgmHELTM,6057
81
+ forgecli/optimizer/caveman/state.py,sha256=ejbwf2vrhsIjNSocSWh2azmGkdDnvj3BscwO-7QDJM0,1683
82
+ forgecli/optimizer/ponytail/__init__.py,sha256=kylIwrW4M9fud6dQKTXRQmALo0wpOm7ti_mneVQUmMg,6097
83
+ forgecli/optimizer/ponytail/cli.py,sha256=zyZPNtIEE5LMzPW_wAdRdIOAJn6GKBJTb3tgD1PI1_k,5065
84
+ forgecli/optimizer/ponytail/decorator.py,sha256=6nAwSzWQ7-oWp0f9MIUd88bPFGB0lKhUVbDX5sj9UTM,2145
85
+ forgecli/optimizer/ponytail/factory.py,sha256=OMaiJ08fFjxv0nLC1hLFUi5rHgLzqwHzY4iOgb6T-pE,1547
86
+ forgecli/optimizer/ponytail/ruleset.py,sha256=JfkgMpa2A-A9VCBQzBz9_kQSF09crmizd85SjgqlJzs,6053
87
+ forgecli/optimizer/ponytail/state.py,sha256=Wu6u1bx7m5kCP0IXuroDP5UW6uKdTSFgvz8wtfxEKSk,1722
88
+ forgecli/orchestrator/__init__.py,sha256=Hhk8gLlHKNZhR14ENiYjnITtvJp_RHVrWHdPRdXXLEs,25521
89
+ forgecli/planner/__init__.py,sha256=AF-l3-O_W5J-x9b8eMBP59K7LUkgYYCzULtyhBD8Nn4,1169
90
+ forgecli/planner/agent.py,sha256=AV7Qnz5Cz9WLE15sigQmsTqO-WAT1kHuobf4HIMMAy8,1954
91
+ forgecli/planner/plan.py,sha256=hyYn8wrMzCz-b1V61F3QaUitvPmeiYLcZJssn1zgyGg,1765
92
+ forgecli/planner/planner.py,sha256=reRVqA0ad-EuTbU0_n2Lcs3hOVDj4ZUyvObOkG1WQH4,439
93
+ forgecli/planner/render.py,sha256=D86Ts6kp8DDGB0fwszGdijczWf8WJyI7XROU4aWdt9Q,8788
94
+ forgecli/planner/serialize.py,sha256=BAK2o5ZiTHPBoD0mQhskIIcLbdsV55g6tL9kMiCH_tk,3814
95
+ forgecli/planner/software.py,sha256=4idIxQkImMFFnCkiMaxGabFoeNvyyvJiT5GitUeKTw4,27204
96
+ forgecli/platform/__init__.py,sha256=GpSNQNUlSLXITnddZtWe-njoxASzNj7WxvYCvzgfz4c,2162
97
+ forgecli/platform/core.py,sha256=8knytvYR10SRu32jkjWkMAVrvg_2onq6CbdPsyWiiPk,5355
98
+ forgecli/platform/deps.py,sha256=zXzYNbDh2ybT2AmzbGRolJKQM5nMbQwtstruqglEiw8,10950
99
+ forgecli/platform/paths.py,sha256=1FVMqls6uyTpPRWmzz8B1H8-NEigIgiKF-DvA0DDPuU,7344
100
+ forgecli/platform/shell.py,sha256=lexXMC7klRSvl-_PZhaH6FKtAFm7naDXMrhBwaddniI,5321
101
+ forgecli/platform/update.py,sha256=VOlAVMnAY4w_YVLLk-XDphzRFore_edvVKsa6cwNhBM,7597
102
+ forgecli/plugins/__init__.py,sha256=Wtiso7gGurp8cpFv17zgdyKJpKKqVVO_W6mlSxp5TZI,8567
103
+ forgecli/prompts/__init__.py,sha256=Ayh_h3WSwXSyvTnB12cSNYY2Q-JAZnB13etO4Dl5zV8,273
104
+ forgecli/prompts/loader.py,sha256=RV5mh1OKnhJosFhOvoed23FeT7wjOnXru5lQB3O3Vkc,758
105
+ forgecli/prompts/registry.py,sha256=vnVrXAPg_crkF1hWT3CfLtl3Fz4dQVzh8XvbpgTtzjI,845
106
+ forgecli/prompts/renderer.py,sha256=wwo7tiUQvomZ710t-0epG32tu6ZoGyqgrwBbfYhx6JY,728
107
+ forgecli/providers/__init__.py,sha256=3aqVaNw50pgwqvULaSYpWCS88VxJhpcKrfSLTGaJ-7Q,731
108
+ forgecli/providers/anthropic.py,sha256=BSIdXhBlgZG0Fa6TiMHW4J9xy9-WI7S7juyJlEvQVCs,7199
109
+ forgecli/providers/base.py,sha256=Xn9gscUoiazB5T7_4zrid6e6OA5A8hnRpq4-rKrlplo,5898
110
+ forgecli/providers/builtin.py,sha256=yGCClRQYS7ZJtudYtqeKG0xzKDaL-_NMa7DtAlGfwfg,858
111
+ forgecli/providers/conversation.py,sha256=RjHeVpagDDXG7KQKGrk9ImaebljJzXoaLgujV5fSrzI,1799
112
+ forgecli/providers/google.py,sha256=YReUSFSyVEdbqDrhpavXb4elTIE23ZbNrVrFTvH2XdQ,10820
113
+ forgecli/providers/http_base.py,sha256=z7j02P2yY_8qsODOapvVur4fRqOKZFqn7qU1yPufbEI,7140
114
+ forgecli/providers/mock.py,sha256=3x2IakNMugt7dUNSdKsmLjPxUHUqRi-WoBpZLu5tmMU,3723
115
+ forgecli/providers/openai.py,sha256=yoAul9ouw03exeVxW0I-tqy3nV2hmL2-Bt_wx9cjiis,7107
116
+ forgecli/providers/openai_compatible.py,sha256=N-b43eO4_vdGPvNmgCs83MtNu3NH64Qv3G_IejhGwqc,24167
117
+ forgecli/providers/router.py,sha256=PgAuJobRw9zUWSTRVW2duMStNlk0wRuzMqPLPu82QZk,11566
118
+ forgecli/providers/router_state.py,sha256=oQS3l5BSYNFAmDOGVUreJT7ffdM_LLMvAV76mbxtd6M,2582
119
+ forgecli/review/__init__.py,sha256=fwYv6aHoRcMOtvYjvr0VTZ-f6wpGSvq491YrQoklfKk,1342
120
+ forgecli/review/analyzer.py,sha256=aFsxbznX7j6lhWaqZ2gDLmqLnRdu8iSccVKxwP0gHp8,3134
121
+ forgecli/review/finding.py,sha256=mKF8Gcvm4WuYHK9AgaWhGP4d8PEFt1j45tDf77zmezg,1763
122
+ forgecli/review/report.py,sha256=Gxpe3ECDvRj2tc5q93ECFkeIteVh-Nm5XI7zzuqKku0,10743
123
+ forgecli/review/repository.py,sha256=GzNKVEiuBGhG7BhlgJNMQYffLPlZLrHWIJ_Za1LXOMQ,4294
124
+ forgecli/review/suggestions.py,sha256=_G8tM3MCq9GsfV9vxLXRrHCfAq0Vzm8VlriXQVKtumY,3260
125
+ forgecli/review/analyzers/__init__.py,sha256=9AR42PWue7RTq7TjPPqjkcA06Bei3eJXoQ_VWyCibbs,48
126
+ forgecli/review/analyzers/architecture.py,sha256=KCBRxtf0tn4JABM1ki7VlR9Y_NhuROkbe7vKyreDofc,9042
127
+ forgecli/review/analyzers/complexity.py,sha256=Ub5bXHNoIJ2qiidJ3IGG3i_HLHH2ovlkHm1aWOyULMU,5634
128
+ forgecli/review/analyzers/dead_code.py,sha256=FPe6d72kWZ4Wnm4jAaxideIM2rLPonUzsJpxmUSzF-g,7725
129
+ forgecli/review/analyzers/duplicates.py,sha256=d5FJwdZ5rjZGKrkLnDVPhW559RMuaOmSVzAkRaMuKp8,6493
130
+ forgecli/review/analyzers/performance.py,sha256=wXT0I7QMrWucGmQnQXppw5bW5LzPKJB6UHB964fGNNk,5818
131
+ forgecli/review/analyzers/security.py,sha256=liTUdyUKldXC3GRmJcG5L8k3vPJh7xTN4eRDAR6TCno,8834
132
+ forgecli/runtime/__init__.py,sha256=8jJwXHIXI9qcsk0Ai_somXBouwc_KTVbFVmJ5hkzT7w,275
133
+ forgecli/runtime/cache_store.py,sha256=ZPuKAvsHx7Zx1WuTAtTX9AgyJNme8T6w4B6OFTjbiMo,2299
134
+ forgecli/runtime/mcp_config.py,sha256=u-8EdDRRmXDETk-GhcDsr8adviG9dvUllZEP8Xu8hKc,4909
135
+ forgecli/runtime/prepare.py,sha256=-tNTcUq0EVHf-7ZB5vvpmpNEZwYnX4jaKT3HkDiQiHk,6093
136
+ forgecli/runtime/wrappers.py,sha256=7VqvI-8bWlPQZbemnmFsW2NCWW0_2y6l5bWXY1c_qdg,4503
137
+ forgecli/sdk/__init__.py,sha256=gE_dnjWPj1cNL-30N3VBabi3qTmSrnO8dlpChcVct4U,3372
138
+ forgecli/sdk/events.py,sha256=_i3PrtXUNTiviaJBymLCQa1Jok2HfWi6jCUvXMD7Q6k,6562
139
+ forgecli/sdk/interfaces.py,sha256=nAg7_ehGMPdrfG0eJChOid3p2BquAuIb3S2lSwg30ww,8244
140
+ forgecli/sdk/loader.py,sha256=Iz_4T-6_5SS11uo4nOzpGX3cDJAbqhHNrVYUOhAIx9c,7850
141
+ forgecli/sdk/manager.py,sha256=16hHK867d-2ZivCgiaviC229QkXxSn15dVRWI56sGxw,24521
142
+ forgecli/sdk/manifest.py,sha256=DkcjT7NZ1XTym7KGXeG9K2BV-e9YN1UYibl1zxG2_b4,14297
143
+ forgecli/sdk/sandbox.py,sha256=5DDr5Z79y4pcl7um0f9Crpeb_0U92NVWQgt4-Gp9Qok,7068
144
+ forgecli/sdk/version.py,sha256=v1F1d_D7UcXfx_bdkVD-hzlKvOTrk6pQDemzgB0NmGo,10358
145
+ forgecli/templates/__init__.py,sha256=MRbet1ADd0nDKvlRjTOJd4g7uYbW_lVLxYhyMrAA19w,219
146
+ forgecli/templates/engine.py,sha256=9HyFtjz6ewWE7C2PLFFsc8uFzXlQtiqzEc-l0IY8zNY,1192
147
+ forgecli/templates/registry.py,sha256=6zQS54gadPXcU3cPIco-6CFk1a2pYR1DZXpAg4LUrYo,878
148
+ forgecli/utils/__init__.py,sha256=WIh_PkzipvqFuzVa0Fdxuk3xgPbxpyrPspktjjdBNXg,471
149
+ forgecli/utils/fs.py,sha256=KkTD-FEu9JMbMGjDIZnvCvwSOuTzmCcoM_c2EF5bH6E,3045
150
+ forgecli/utils/ids.py,sha256=j98tVfdwa-N0JezpBa0t4xKexdDkdjc3xo3q7PQcuqQ,312
151
+ forgecli/utils/io.py,sha256=CWqAwK6xY0Pg2reSbjmFBxhkGJ12zoeZGuzbrPKDrG0,745
152
+ forgecli/utils/paths.py,sha256=LHqWLb0e7UlwMPT7ki5ghOo3mL27MuEas94pkzrnzfo,2456
153
+ forgecli/utils/stats.py,sha256=ePpOOZMdRi-JVs2PvI1pLlIPjlhrVgbIB4uzwGCsQJA,5966
154
+ forgecli/utils/timing.py,sha256=niO6z25sCsq81nkCPNrMRaLKFRhgTHaTKwWWajDOf8w,605
155
+ forgeoptimizer-0.1.0.dist-info/METADATA,sha256=-sk3SB3QiX7_ZrVna3952D71h38W9aliKCOwhto_iSE,7554
156
+ forgeoptimizer-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
157
+ forgeoptimizer-0.1.0.dist-info/entry_points.txt,sha256=jc5LXqA-RLHWqsRA6PjBUEoQHJXQZir1H0_kxIPs4oQ,48
158
+ forgeoptimizer-0.1.0.dist-info/licenses/LICENSE,sha256=wZ2_rDzYfTv5PGhPKffBvgjxIDs-5pCBTwt3osC_9Bk,1070
159
+ forgeoptimizer-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ forge = forgecli.cli.main:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Forge Authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.