phi47-superpowers 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- phi47_superpowers-0.1.0/LICENSE +22 -0
- phi47_superpowers-0.1.0/PKG-INFO +98 -0
- phi47_superpowers-0.1.0/README.md +50 -0
- phi47_superpowers-0.1.0/pyproject.toml +32 -0
- phi47_superpowers-0.1.0/setup.cfg +4 -0
- phi47_superpowers-0.1.0/src/phi47/__init__.py +13 -0
- phi47_superpowers-0.1.0/src/phi47/cli/__init__.py +2 -0
- phi47_superpowers-0.1.0/src/phi47/cli/main.py +102 -0
- phi47_superpowers-0.1.0/src/phi47/core/__init__.py +2 -0
- phi47_superpowers-0.1.0/src/phi47/core/phi_calculator.py +67 -0
- phi47_superpowers-0.1.0/src/phi47/linter/__init__.py +2 -0
- phi47_superpowers-0.1.0/src/phi47/linter/phi_linter.py +177 -0
- phi47_superpowers-0.1.0/src/phi47/wrapper/__init__.py +2 -0
- phi47_superpowers-0.1.0/src/phi47/wrapper/llm_wrapper.py +105 -0
- phi47_superpowers-0.1.0/src/phi47_superpowers.egg-info/PKG-INFO +98 -0
- phi47_superpowers-0.1.0/src/phi47_superpowers.egg-info/SOURCES.txt +18 -0
- phi47_superpowers-0.1.0/src/phi47_superpowers.egg-info/dependency_links.txt +1 -0
- phi47_superpowers-0.1.0/src/phi47_superpowers.egg-info/entry_points.txt +2 -0
- phi47_superpowers-0.1.0/src/phi47_superpowers.egg-info/requires.txt +14 -0
- phi47_superpowers-0.1.0/src/phi47_superpowers.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 wcalmels
|
|
4
|
+
TUCH Systems Research Laboratory -- Buenos Aires / Santiago
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
|
14
|
+
all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phi47-superpowers
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Structural code quality layer based on IIT 4.0
|
|
5
|
+
Author-email: wcalmels <wcalmels@phi47.cl>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 wcalmels
|
|
9
|
+
TUCH Systems Research Laboratory -- Buenos Aires / Santiago
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in
|
|
19
|
+
all copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
27
|
+
THE SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Homepage, https://phi47.tuch.systems
|
|
30
|
+
Project-URL: Repository, https://github.com/wcalmels/phi47-superpowers
|
|
31
|
+
Keywords: linter,code-quality,iit,phi,ast,developer-tools
|
|
32
|
+
Requires-Python: >=3.10
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: numpy>=1.24
|
|
36
|
+
Requires-Dist: scipy>=1.11
|
|
37
|
+
Requires-Dist: click>=8.1
|
|
38
|
+
Requires-Dist: rich>=13.0
|
|
39
|
+
Provides-Extra: llm
|
|
40
|
+
Requires-Dist: anthropic>=0.20; extra == "llm"
|
|
41
|
+
Requires-Dist: openai>=1.0; extra == "llm"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-cov>=4.1; extra == "dev"
|
|
45
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
46
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# Phi47 Superpowers Layer
|
|
50
|
+
|
|
51
|
+
[](https://github.com/TUCHSystems/phi47-superpowers/actions)
|
|
52
|
+
[](https://pypi.org/project/phi47-superpowers/)
|
|
53
|
+
[](LICENSE)
|
|
54
|
+
|
|
55
|
+
> Structural code quality layer based on Integrated Information Theory (IIT 4.0).
|
|
56
|
+
> Works on top of any editor (VS Code, Cursor, Neovim) or LLM (Claude, GPT-4, Gemini).
|
|
57
|
+
> No vendor lock-in. Use your own API keys.
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
pip install phi47-superpowers
|
|
62
|
+
pip install "phi47-superpowers[llm]"
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
phi47 analyze mycode.py
|
|
67
|
+
phi47 analyze .
|
|
68
|
+
phi47 generate "Build a REST API" --output api.py
|
|
69
|
+
phi47 init
|
|
70
|
+
|
|
71
|
+
## Diagnostic codes
|
|
72
|
+
|
|
73
|
+
| Code | Issue | Severity |
|
|
74
|
+
|------|---------------------------|-----------------|
|
|
75
|
+
| P001 | Low system Phi | error / warning |
|
|
76
|
+
| P002 | Zombie function | warning |
|
|
77
|
+
| P003 | High cyclomatic complexity| error / warning |
|
|
78
|
+
| P004 | Low causal density | info |
|
|
79
|
+
| P006 | Disconnected class | hint |
|
|
80
|
+
| P007 | God function | hint |
|
|
81
|
+
|
|
82
|
+
## Use as a library
|
|
83
|
+
|
|
84
|
+
from phi47 import Phi47Linter
|
|
85
|
+
linter = Phi47Linter()
|
|
86
|
+
for d in linter.lint_file("mycode.py"):
|
|
87
|
+
print(d)
|
|
88
|
+
|
|
89
|
+
## Scientific background
|
|
90
|
+
|
|
91
|
+
Phi47 applies spectral IIT 4.0 to dependency graphs:
|
|
92
|
+
Phi = H(eigenvalues(C*C^T)) * (1 - e^(-k))
|
|
93
|
+
Runs in O(n^3) instead of exact O(2^n).
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT License -- Copyright (c) 2025 Walter Calmels Von dem Knesebeck
|
|
98
|
+
TUCH Systems Research Laboratory
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Phi47 Superpowers Layer
|
|
2
|
+
|
|
3
|
+
[](https://github.com/TUCHSystems/phi47-superpowers/actions)
|
|
4
|
+
[](https://pypi.org/project/phi47-superpowers/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
> Structural code quality layer based on Integrated Information Theory (IIT 4.0).
|
|
8
|
+
> Works on top of any editor (VS Code, Cursor, Neovim) or LLM (Claude, GPT-4, Gemini).
|
|
9
|
+
> No vendor lock-in. Use your own API keys.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
pip install phi47-superpowers
|
|
14
|
+
pip install "phi47-superpowers[llm]"
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
phi47 analyze mycode.py
|
|
19
|
+
phi47 analyze .
|
|
20
|
+
phi47 generate "Build a REST API" --output api.py
|
|
21
|
+
phi47 init
|
|
22
|
+
|
|
23
|
+
## Diagnostic codes
|
|
24
|
+
|
|
25
|
+
| Code | Issue | Severity |
|
|
26
|
+
|------|---------------------------|-----------------|
|
|
27
|
+
| P001 | Low system Phi | error / warning |
|
|
28
|
+
| P002 | Zombie function | warning |
|
|
29
|
+
| P003 | High cyclomatic complexity| error / warning |
|
|
30
|
+
| P004 | Low causal density | info |
|
|
31
|
+
| P006 | Disconnected class | hint |
|
|
32
|
+
| P007 | God function | hint |
|
|
33
|
+
|
|
34
|
+
## Use as a library
|
|
35
|
+
|
|
36
|
+
from phi47 import Phi47Linter
|
|
37
|
+
linter = Phi47Linter()
|
|
38
|
+
for d in linter.lint_file("mycode.py"):
|
|
39
|
+
print(d)
|
|
40
|
+
|
|
41
|
+
## Scientific background
|
|
42
|
+
|
|
43
|
+
Phi47 applies spectral IIT 4.0 to dependency graphs:
|
|
44
|
+
Phi = H(eigenvalues(C*C^T)) * (1 - e^(-k))
|
|
45
|
+
Runs in O(n^3) instead of exact O(2^n).
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
MIT License -- Copyright (c) 2025 Walter Calmels Von dem Knesebeck
|
|
50
|
+
TUCH Systems Research Laboratory
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=72", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "phi47-superpowers"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Structural code quality layer based on IIT 4.0"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "wcalmels", email = "wcalmels@phi47.cl" }]
|
|
13
|
+
keywords = ["linter","code-quality","iit","phi","ast","developer-tools"]
|
|
14
|
+
dependencies = ["numpy>=1.24","scipy>=1.11","click>=8.1","rich>=13.0"]
|
|
15
|
+
|
|
16
|
+
[project.optional-dependencies]
|
|
17
|
+
llm = ["anthropic>=0.20","openai>=1.0"]
|
|
18
|
+
dev = ["pytest>=7.4","pytest-cov>=4.1","black>=23.0","ruff>=0.1"]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
phi47 = "phi47.cli.main:cli"
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://phi47.tuch.systems"
|
|
25
|
+
Repository = "https://github.com/wcalmels/phi47-superpowers"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.packages.find]
|
|
28
|
+
where = ["src"]
|
|
29
|
+
|
|
30
|
+
[tool.pytest.ini_options]
|
|
31
|
+
testpaths = ["tests"]
|
|
32
|
+
addopts = "-v --tb=short"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2025 wcalmels -- TUCH Systems Research Laboratory
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
__author__ = "wcalmels"
|
|
5
|
+
__email__ = "wcalmels@phi47.cl"
|
|
6
|
+
__license__ = "MIT"
|
|
7
|
+
__copyright__ = "Copyright (c) 2025 TUCH Systems Research Laboratory"
|
|
8
|
+
|
|
9
|
+
from phi47.linter.phi_linter import Phi47Linter
|
|
10
|
+
from phi47.wrapper.llm_wrapper import Phi47LLMWrapper
|
|
11
|
+
from phi47.core.phi_calculator import PhiCalculator
|
|
12
|
+
|
|
13
|
+
__all__ = ["Phi47Linter", "Phi47LLMWrapper", "PhiCalculator"]
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Copyright (c) 2025 wcalmels -- TUCH Systems Research Laboratory
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import click
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
from phi47.linter.phi_linter import Phi47Linter
|
|
10
|
+
from phi47.wrapper.llm_wrapper import Phi47LLMWrapper
|
|
11
|
+
|
|
12
|
+
console = Console()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@click.group()
|
|
16
|
+
@click.version_option("0.1.0", prog_name="phi47")
|
|
17
|
+
def cli():
|
|
18
|
+
"""phi47 -- structural code quality layer based on IIT 4.0."""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@cli.command()
|
|
22
|
+
@click.argument("path", default=".")
|
|
23
|
+
@click.option("--json", "as_json", is_flag=True, help="Output JSON")
|
|
24
|
+
@click.option("--quiet", is_flag=True, help="Only show errors")
|
|
25
|
+
def analyze(path, as_json, quiet):
|
|
26
|
+
"""Analyze Phi of a file or directory."""
|
|
27
|
+
linter = Phi47Linter()
|
|
28
|
+
p = Path(path)
|
|
29
|
+
if p.is_file():
|
|
30
|
+
diags = linter.lint_file(str(p))
|
|
31
|
+
if as_json:
|
|
32
|
+
click.echo(json.dumps([d.to_dict() for d in diags], indent=2))
|
|
33
|
+
return
|
|
34
|
+
phi = next((d.phi_value for d in diags if d.code == "P001"), 0.65)
|
|
35
|
+
icon = "G" if phi > 0.6 else "Y" if phi > 0.3 else "R"
|
|
36
|
+
console.print(f"[{icon}] {p.name} Phi={phi:.3f}")
|
|
37
|
+
show = diags if not quiet else [d for d in diags if d.severity == "error"]
|
|
38
|
+
for d in show[:8]:
|
|
39
|
+
c = {"error":"red","warning":"yellow","info":"blue","hint":"dim"}.get(d.severity,"white")
|
|
40
|
+
console.print(f" [{c}][{d.code}][/{c}] L{d.line}: {d.message}")
|
|
41
|
+
if not quiet:
|
|
42
|
+
console.print(f" [dim]-> {d.suggestion}[/dim]")
|
|
43
|
+
else:
|
|
44
|
+
all_d = linter.lint_directory(str(p))
|
|
45
|
+
if as_json:
|
|
46
|
+
click.echo(json.dumps(
|
|
47
|
+
{fp: [d.to_dict() for d in ds] for fp, ds in all_d.items()}, indent=2))
|
|
48
|
+
return
|
|
49
|
+
import numpy as np
|
|
50
|
+
t = Table(title=f"Phi47: {p}")
|
|
51
|
+
t.add_column("File", style="cyan")
|
|
52
|
+
t.add_column("Phi", justify="right")
|
|
53
|
+
t.add_column("E", justify="right", style="red")
|
|
54
|
+
t.add_column("W", justify="right", style="yellow")
|
|
55
|
+
phis = []
|
|
56
|
+
for fp, ds in sorted(all_d.items()):
|
|
57
|
+
phi = next((d.phi_value for d in ds if d.code == "P001"), 0.65)
|
|
58
|
+
phis.append(phi)
|
|
59
|
+
e = sum(1 for d in ds if d.severity == "error")
|
|
60
|
+
w = sum(1 for d in ds if d.severity == "warning")
|
|
61
|
+
t.add_row(Path(fp).name, f"{phi:.3f}", str(e), str(w))
|
|
62
|
+
console.print(t)
|
|
63
|
+
if phis:
|
|
64
|
+
console.print(f"System Phi = {float(np.mean(phis)):.3f}")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@cli.command()
|
|
68
|
+
@click.argument("task")
|
|
69
|
+
@click.option("--output", "-o", default=None)
|
|
70
|
+
@click.option("--backend", "-b", default="claude")
|
|
71
|
+
@click.option("--threshold", default=0.5)
|
|
72
|
+
def generate(task, output, backend, threshold):
|
|
73
|
+
"""Generate code with Phi analysis and auto-refinement."""
|
|
74
|
+
console.print(f"[cyan]Task:[/cyan] {task} [cyan]Backend:[/cyan] {backend}")
|
|
75
|
+
w = Phi47LLMWrapper(backend=backend, phi_threshold=threshold)
|
|
76
|
+
r = w.generate(task)
|
|
77
|
+
ok = "OK" if r["phi_ok"] else "!!"
|
|
78
|
+
console.print(f"[{ok}] Phi={r['phi']:.3f} refinements={r['refinements']}")
|
|
79
|
+
if output:
|
|
80
|
+
Path(output).write_text(r["code"], encoding="utf-8")
|
|
81
|
+
console.print(f"Saved: {output}")
|
|
82
|
+
else:
|
|
83
|
+
click.echo(r["code"])
|
|
84
|
+
for s in r["suggestions"][:3]:
|
|
85
|
+
console.print(f" -> {s}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@cli.command()
|
|
89
|
+
@click.argument("path", default=".")
|
|
90
|
+
def init(path):
|
|
91
|
+
"""Initialize Phi47 in a project."""
|
|
92
|
+
p = Path(path)
|
|
93
|
+
cfg = {"version": "0.1.0", "phi_threshold": 0.5,
|
|
94
|
+
"auto_refine": True, "backend": "claude"}
|
|
95
|
+
(p / ".phi47.json").write_text(json.dumps(cfg, indent=2), encoding="utf-8")
|
|
96
|
+
hook = p / ".git" / "hooks" / "pre-commit"
|
|
97
|
+
if hook.parent.exists():
|
|
98
|
+
hook.write_text("#!/bin/bash\nphi47 analyze . --quiet || exit 1\n", encoding="utf-8")
|
|
99
|
+
import stat
|
|
100
|
+
hook.chmod(hook.stat().st_mode | stat.S_IEXEC)
|
|
101
|
+
console.print("[green]Git hook installed[/green]")
|
|
102
|
+
console.print("[bold green]Phi47 initialized![/bold green] Run: phi47 analyze .")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Copyright (c) 2025 wcalmels -- TUCH Systems Research Laboratory
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import numpy as np
|
|
5
|
+
from scipy import linalg
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PhiCalculator:
|
|
9
|
+
"""Calculates Phi for a connectivity matrix using spectral approximation (IIT 4.0).
|
|
10
|
+
|
|
11
|
+
Example::
|
|
12
|
+
|
|
13
|
+
calc = PhiCalculator()
|
|
14
|
+
import numpy as np
|
|
15
|
+
phi, meta = calc.calculate(np.random.rand(5, 5))
|
|
16
|
+
print(phi)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def calculate(self, connectivity: np.ndarray, method: str = "spectral") -> tuple:
|
|
20
|
+
"""Calculate Phi.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
connectivity: Square NxN float matrix.
|
|
24
|
+
method: 'spectral' (fast, O(n^3)) or 'exact' (n<=8 only).
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
Tuple of (phi: float, metadata: dict).
|
|
28
|
+
"""
|
|
29
|
+
if connectivity.ndim != 2 or connectivity.shape[0] != connectivity.shape[1]:
|
|
30
|
+
raise ValueError(f"Expected square matrix, got {connectivity.shape}")
|
|
31
|
+
m = (connectivity + connectivity.T) / 2.0
|
|
32
|
+
m = np.nan_to_num(m, nan=0.0)
|
|
33
|
+
if method == "exact" and m.shape[0] <= 8:
|
|
34
|
+
return self._exact(m)
|
|
35
|
+
return self._spectral(m)
|
|
36
|
+
|
|
37
|
+
def _spectral(self, m: np.ndarray) -> tuple:
|
|
38
|
+
cov = m @ m.T
|
|
39
|
+
eigv = linalg.eigvalsh(cov)
|
|
40
|
+
eigv = eigv[eigv > 1e-10]
|
|
41
|
+
if not len(eigv):
|
|
42
|
+
return 0.0, {"method": "spectral", "phi": 0.0}
|
|
43
|
+
eigv /= eigv.sum()
|
|
44
|
+
h = float(-np.sum(eigv * np.log2(eigv + 1e-12)))
|
|
45
|
+
k = float(np.mean(np.abs(m)))
|
|
46
|
+
phi = h * (1.0 - np.exp(-k))
|
|
47
|
+
return float(phi), {"method": "spectral", "phi": phi,
|
|
48
|
+
"total_information": h, "integration_factor": 1 - np.exp(-k)}
|
|
49
|
+
|
|
50
|
+
def _exact(self, m: np.ndarray) -> tuple:
|
|
51
|
+
from itertools import combinations
|
|
52
|
+
n = m.shape[0]
|
|
53
|
+
all_idx = list(range(n))
|
|
54
|
+
min_phi = float("inf")
|
|
55
|
+
mip = None
|
|
56
|
+
for k in range(1, n // 2 + 1):
|
|
57
|
+
for pa in combinations(all_idx, k):
|
|
58
|
+
pa = list(pa)
|
|
59
|
+
pb = [i for i in all_idx if i not in pa]
|
|
60
|
+
mi = max(0.0,
|
|
61
|
+
np.linalg.norm(m[np.ix_(pa, pa)], "fro")
|
|
62
|
+
+ np.linalg.norm(m[np.ix_(pb, pb)], "fro")
|
|
63
|
+
- np.linalg.norm(m, "fro"))
|
|
64
|
+
if mi < min_phi:
|
|
65
|
+
min_phi, mip = mi, (pa, pb)
|
|
66
|
+
phi = float(min_phi) if min_phi != float("inf") else 0.0
|
|
67
|
+
return phi, {"method": "exact", "phi": phi, "mip": mip}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Copyright (c) 2025 wcalmels -- TUCH Systems Research Laboratory
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import ast, json
|
|
5
|
+
from dataclasses import dataclass, asdict
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import numpy as np
|
|
8
|
+
from phi47.core.phi_calculator import PhiCalculator
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class Diagnostic:
|
|
13
|
+
file: str
|
|
14
|
+
line: int
|
|
15
|
+
col: int
|
|
16
|
+
severity: str
|
|
17
|
+
code: str
|
|
18
|
+
message: str
|
|
19
|
+
phi_value: float
|
|
20
|
+
suggestion: str
|
|
21
|
+
|
|
22
|
+
def to_dict(self): return asdict(self)
|
|
23
|
+
def __str__(self):
|
|
24
|
+
return f"{self.file}:{self.line}:{self.col}: {self.severity} [{self.code}] {self.message}"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Phi47Linter:
|
|
28
|
+
"""Phi-based linter compatible with any LSP editor.
|
|
29
|
+
|
|
30
|
+
Example::
|
|
31
|
+
|
|
32
|
+
linter = Phi47Linter()
|
|
33
|
+
for d in linter.lint_file("mycode.py"):
|
|
34
|
+
print(d)
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, phi_error=0.3, phi_warning=0.5,
|
|
38
|
+
complexity_error=15, complexity_warning=10, max_lines=80):
|
|
39
|
+
self.phi_error = phi_error
|
|
40
|
+
self.phi_warning = phi_warning
|
|
41
|
+
self.complexity_error = complexity_error
|
|
42
|
+
self.complexity_warning = complexity_warning
|
|
43
|
+
self.max_lines = max_lines
|
|
44
|
+
self._calc = PhiCalculator()
|
|
45
|
+
|
|
46
|
+
def lint_file(self, filepath: str) -> list:
|
|
47
|
+
p = Path(filepath)
|
|
48
|
+
try:
|
|
49
|
+
tree = ast.parse(p.read_text(encoding="utf-8"), filename=str(p))
|
|
50
|
+
except SyntaxError as e:
|
|
51
|
+
return [Diagnostic(str(p), e.lineno or 1, 0, "error", "P000",
|
|
52
|
+
f"Syntax: {e.msg}", 0.0, "Fix syntax first.")]
|
|
53
|
+
except OSError as e:
|
|
54
|
+
return [Diagnostic(str(p), 1, 0, "error", "P000",
|
|
55
|
+
f"IO: {e}", 0.0, "Check permissions.")]
|
|
56
|
+
funcs = _extract_functions(tree)
|
|
57
|
+
clss = _extract_classes(tree)
|
|
58
|
+
matrix = _build_dep_matrix(funcs)
|
|
59
|
+
diags = []
|
|
60
|
+
diags += self._check_phi(str(p), matrix)
|
|
61
|
+
diags += self._check_funcs(str(p), funcs)
|
|
62
|
+
diags += self._check_cd(str(p), matrix)
|
|
63
|
+
diags += self._check_classes(str(p), clss)
|
|
64
|
+
return sorted(diags, key=lambda d: (d.line, d.code))
|
|
65
|
+
|
|
66
|
+
def lint_directory(self, directory: str) -> dict:
|
|
67
|
+
skip = {".venv", "venv", "__pycache__", ".git", "dist", "build"}
|
|
68
|
+
out = {}
|
|
69
|
+
for f in Path(directory).rglob("*.py"):
|
|
70
|
+
if any(p in skip for p in f.parts): continue
|
|
71
|
+
d = self.lint_file(str(f))
|
|
72
|
+
if d: out[str(f)] = d
|
|
73
|
+
return out
|
|
74
|
+
|
|
75
|
+
def lint_to_json(self, path: str) -> str:
|
|
76
|
+
if Path(path).is_dir():
|
|
77
|
+
data = {fp: [d.to_dict() for d in ds]
|
|
78
|
+
for fp, ds in self.lint_directory(path).items()}
|
|
79
|
+
else:
|
|
80
|
+
data = {path: [d.to_dict() for d in self.lint_file(path)]}
|
|
81
|
+
return json.dumps(data, indent=2)
|
|
82
|
+
|
|
83
|
+
def _check_phi(self, fp, matrix):
|
|
84
|
+
if matrix.shape[0] < 2: return []
|
|
85
|
+
phi, _ = self._calc.calculate(matrix)
|
|
86
|
+
if phi < self.phi_error:
|
|
87
|
+
return [Diagnostic(fp, 1, 0, "error", "P001",
|
|
88
|
+
f"System Phi={phi:.3f} critically low (threshold {self.phi_error})",
|
|
89
|
+
phi, "Add connections between functions.")]
|
|
90
|
+
if phi < self.phi_warning:
|
|
91
|
+
return [Diagnostic(fp, 1, 0, "warning", "P001",
|
|
92
|
+
f"System Phi={phi:.3f} below recommended (threshold {self.phi_warning})",
|
|
93
|
+
phi, "Consider increasing causal connections.")]
|
|
94
|
+
return []
|
|
95
|
+
|
|
96
|
+
def _check_funcs(self, fp, funcs):
|
|
97
|
+
diags = []
|
|
98
|
+
for name, data in funcs.items():
|
|
99
|
+
calls = set(data["calls"])
|
|
100
|
+
callers = {n for n, d in funcs.items() if name in d["calls"]}
|
|
101
|
+
cx, ln, lines = data["complexity"], data["lineno"], data["lines"]
|
|
102
|
+
if not calls and not callers and name not in {"main","__init__","__new__"}:
|
|
103
|
+
diags.append(Diagnostic(fp, ln, 0, "warning", "P002",
|
|
104
|
+
f"Zombie function: '{name}' has no callers and no callees",
|
|
105
|
+
0.0, f"Connect or remove '{name}'."))
|
|
106
|
+
if cx > self.complexity_error:
|
|
107
|
+
diags.append(Diagnostic(fp, ln, 0, "error", "P003",
|
|
108
|
+
f"'{name}' complexity={cx} > {self.complexity_error}",
|
|
109
|
+
0.0, "Decompose into smaller functions."))
|
|
110
|
+
elif cx > self.complexity_warning:
|
|
111
|
+
diags.append(Diagnostic(fp, ln, 0, "warning", "P003",
|
|
112
|
+
f"'{name}' complexity={cx}", 0.0, "Consider splitting."))
|
|
113
|
+
if lines > self.max_lines:
|
|
114
|
+
diags.append(Diagnostic(fp, ln, 0, "hint", "P007",
|
|
115
|
+
f"'{name}' is {lines} lines (limit {self.max_lines})",
|
|
116
|
+
0.0, "Functions over 80 lines often have multiple responsibilities."))
|
|
117
|
+
return diags
|
|
118
|
+
|
|
119
|
+
def _check_cd(self, fp, matrix):
|
|
120
|
+
n = matrix.shape[0]
|
|
121
|
+
if n < 3: return []
|
|
122
|
+
cd = float(np.sum(matrix > 0) / (n * (n - 1) + 1e-10))
|
|
123
|
+
if cd < 0.05:
|
|
124
|
+
return [Diagnostic(fp, 1, 0, "info", "P004",
|
|
125
|
+
f"Low causal density={cd:.3f}: modules mostly isolated",
|
|
126
|
+
cd, "Consider a shared utility module.")]
|
|
127
|
+
return []
|
|
128
|
+
|
|
129
|
+
def _check_classes(self, fp, classes):
|
|
130
|
+
diags = []
|
|
131
|
+
for name, data in classes.items():
|
|
132
|
+
if not data["bases"] and not data["methods"]:
|
|
133
|
+
diags.append(Diagnostic(fp, data["lineno"], 0, "hint", "P006",
|
|
134
|
+
f"Class '{name}' has no base class and no methods",
|
|
135
|
+
0.0, "Consider @dataclass or adding methods."))
|
|
136
|
+
return diags
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _extract_functions(tree):
|
|
140
|
+
funcs = {}
|
|
141
|
+
for node in ast.walk(tree):
|
|
142
|
+
if isinstance(node, ast.FunctionDef):
|
|
143
|
+
calls = []
|
|
144
|
+
for c in ast.walk(node):
|
|
145
|
+
if isinstance(c, ast.Call):
|
|
146
|
+
if isinstance(c.func, ast.Name): calls.append(c.func.id)
|
|
147
|
+
elif isinstance(c.func, ast.Attribute): calls.append(c.func.attr)
|
|
148
|
+
cx = 1 + sum(1 for n in ast.walk(node)
|
|
149
|
+
if isinstance(n, (ast.If, ast.For, ast.While,
|
|
150
|
+
ast.Try, ast.ExceptHandler)))
|
|
151
|
+
end = getattr(node, "end_lineno", node.lineno)
|
|
152
|
+
funcs[node.name] = {"calls": list(set(calls)), "complexity": cx,
|
|
153
|
+
"lineno": node.lineno, "lines": end - node.lineno}
|
|
154
|
+
return funcs
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _extract_classes(tree):
|
|
158
|
+
out = {}
|
|
159
|
+
for node in ast.walk(tree):
|
|
160
|
+
if isinstance(node, ast.ClassDef):
|
|
161
|
+
bases = [b.id if isinstance(b, ast.Name) else "?" for b in node.bases]
|
|
162
|
+
methods = [n.name for n in ast.walk(node) if isinstance(n, ast.FunctionDef)]
|
|
163
|
+
out[node.name] = {"bases": bases, "methods": methods, "lineno": node.lineno}
|
|
164
|
+
return out
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _build_dep_matrix(funcs):
|
|
168
|
+
names = list(funcs.keys())
|
|
169
|
+
n = len(names)
|
|
170
|
+
if n < 2: return np.zeros((2, 2))
|
|
171
|
+
idx = {name: i for i, name in enumerate(names)}
|
|
172
|
+
matrix = np.zeros((n, n), dtype=float)
|
|
173
|
+
for name, data in funcs.items():
|
|
174
|
+
i = idx[name]
|
|
175
|
+
for c in data["calls"]:
|
|
176
|
+
if c in idx: matrix[i, idx[c]] = 1.0
|
|
177
|
+
return matrix
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Copyright (c) 2025 wcalmels -- TUCH Systems Research Laboratory
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from phi47.linter.phi_linter import Phi47Linter
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Phi47LLMWrapper:
|
|
10
|
+
"""Universal LLM wrapper that adds Phi analysis to generated code.
|
|
11
|
+
|
|
12
|
+
Supports Claude, GPT-4, and any chat-compatible API.
|
|
13
|
+
Caller keeps their own API key -- no markup, no vendor lock-in.
|
|
14
|
+
|
|
15
|
+
Example::
|
|
16
|
+
|
|
17
|
+
w = Phi47LLMWrapper(backend="claude")
|
|
18
|
+
r = w.generate("Build a binary search tree")
|
|
19
|
+
print(r["phi"], r["code"])
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
SYSTEM = ("You are an expert Python developer. Write clean code with high "
|
|
23
|
+
"causal cohesion. Include type hints and docstrings. "
|
|
24
|
+
"Return ONLY Python code, no explanation.")
|
|
25
|
+
|
|
26
|
+
def __init__(self, backend="claude", api_key=None,
|
|
27
|
+
phi_threshold=0.5, auto_refine=True, max_refinements=2):
|
|
28
|
+
self.backend = backend
|
|
29
|
+
self.api_key = api_key or os.environ.get(
|
|
30
|
+
{"claude": "ANTHROPIC_API_KEY", "openai": "OPENAI_API_KEY"}.get(backend, ""), "")
|
|
31
|
+
self.phi_threshold = phi_threshold
|
|
32
|
+
self.auto_refine = auto_refine
|
|
33
|
+
self.max_refinements = max_refinements
|
|
34
|
+
self._linter = Phi47Linter()
|
|
35
|
+
self._client = None
|
|
36
|
+
|
|
37
|
+
def generate(self, task: str, context: str = "") -> dict:
|
|
38
|
+
"""Generate code and run Phi analysis. Auto-refines if Phi < threshold."""
|
|
39
|
+
prompt = task if not context else f"{task}\n\nContext:\n{context}"
|
|
40
|
+
code = self._extract(self._call(prompt))
|
|
41
|
+
phi, diags = self._phi_of(code)
|
|
42
|
+
refs = 0
|
|
43
|
+
if self.auto_refine and phi < self.phi_threshold:
|
|
44
|
+
for _ in range(self.max_refinements):
|
|
45
|
+
issues = "\n".join(f"- [{d.code}] {d.message}" for d in diags[:3])
|
|
46
|
+
code = self._extract(self._call(
|
|
47
|
+
f"Refactor for higher Phi.\nIssues:\n{issues}\n\n`python\n{code}\n`"))
|
|
48
|
+
phi, diags = self._phi_of(code)
|
|
49
|
+
refs += 1
|
|
50
|
+
if phi >= self.phi_threshold:
|
|
51
|
+
break
|
|
52
|
+
return {
|
|
53
|
+
"code": code,
|
|
54
|
+
"phi": phi,
|
|
55
|
+
"phi_ok": phi >= self.phi_threshold,
|
|
56
|
+
"diagnostics": [{"code": d.code, "message": d.message} for d in diags],
|
|
57
|
+
"suggestions": list({d.suggestion for d in diags})[:4],
|
|
58
|
+
"refinements": refs,
|
|
59
|
+
"backend": self.backend,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
def _call(self, prompt: str) -> str:
|
|
63
|
+
c = self._get_client()
|
|
64
|
+
if self.backend == "claude":
|
|
65
|
+
r = c.messages.create(
|
|
66
|
+
model="claude-sonnet-4-6", max_tokens=2048,
|
|
67
|
+
system=self.SYSTEM,
|
|
68
|
+
messages=[{"role": "user", "content": prompt}])
|
|
69
|
+
return r.content[0].text
|
|
70
|
+
if self.backend == "openai":
|
|
71
|
+
r = c.chat.completions.create(
|
|
72
|
+
model="gpt-4o", max_tokens=2048,
|
|
73
|
+
messages=[{"role": "system", "content": self.SYSTEM},
|
|
74
|
+
{"role": "user", "content": prompt}])
|
|
75
|
+
return r.choices[0].message.content
|
|
76
|
+
return f"# {prompt}\ndef solution(): pass\n"
|
|
77
|
+
|
|
78
|
+
def _get_client(self):
|
|
79
|
+
if self._client:
|
|
80
|
+
return self._client
|
|
81
|
+
if self.backend == "claude":
|
|
82
|
+
import anthropic
|
|
83
|
+
self._client = anthropic.Anthropic(api_key=self.api_key)
|
|
84
|
+
elif self.backend == "openai":
|
|
85
|
+
import openai
|
|
86
|
+
openai.api_key = self.api_key
|
|
87
|
+
self._client = openai
|
|
88
|
+
return self._client
|
|
89
|
+
|
|
90
|
+
def _phi_of(self, code: str):
|
|
91
|
+
tmp = Path("_phi47_tmp.py")
|
|
92
|
+
try:
|
|
93
|
+
tmp.write_text(code, encoding="utf-8")
|
|
94
|
+
diags = self._linter.lint_file(str(tmp))
|
|
95
|
+
phi = next((d.phi_value for d in diags if d.code == "P001"), 0.65)
|
|
96
|
+
return phi, diags
|
|
97
|
+
finally:
|
|
98
|
+
if tmp.exists():
|
|
99
|
+
tmp.unlink()
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def _extract(text: str) -> str:
|
|
103
|
+
if "`python" in text: return text.split("`python")[1].split("`")[0].strip()
|
|
104
|
+
if "`" in text: return text.split("`")[1].split("`")[0].strip()
|
|
105
|
+
return text.strip()
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phi47-superpowers
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Structural code quality layer based on IIT 4.0
|
|
5
|
+
Author-email: wcalmels <wcalmels@phi47.cl>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 wcalmels
|
|
9
|
+
TUCH Systems Research Laboratory -- Buenos Aires / Santiago
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in
|
|
19
|
+
all copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
27
|
+
THE SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: Homepage, https://phi47.tuch.systems
|
|
30
|
+
Project-URL: Repository, https://github.com/wcalmels/phi47-superpowers
|
|
31
|
+
Keywords: linter,code-quality,iit,phi,ast,developer-tools
|
|
32
|
+
Requires-Python: >=3.10
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: numpy>=1.24
|
|
36
|
+
Requires-Dist: scipy>=1.11
|
|
37
|
+
Requires-Dist: click>=8.1
|
|
38
|
+
Requires-Dist: rich>=13.0
|
|
39
|
+
Provides-Extra: llm
|
|
40
|
+
Requires-Dist: anthropic>=0.20; extra == "llm"
|
|
41
|
+
Requires-Dist: openai>=1.0; extra == "llm"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-cov>=4.1; extra == "dev"
|
|
45
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
46
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# Phi47 Superpowers Layer
|
|
50
|
+
|
|
51
|
+
[](https://github.com/TUCHSystems/phi47-superpowers/actions)
|
|
52
|
+
[](https://pypi.org/project/phi47-superpowers/)
|
|
53
|
+
[](LICENSE)
|
|
54
|
+
|
|
55
|
+
> Structural code quality layer based on Integrated Information Theory (IIT 4.0).
|
|
56
|
+
> Works on top of any editor (VS Code, Cursor, Neovim) or LLM (Claude, GPT-4, Gemini).
|
|
57
|
+
> No vendor lock-in. Use your own API keys.
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
pip install phi47-superpowers
|
|
62
|
+
pip install "phi47-superpowers[llm]"
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
phi47 analyze mycode.py
|
|
67
|
+
phi47 analyze .
|
|
68
|
+
phi47 generate "Build a REST API" --output api.py
|
|
69
|
+
phi47 init
|
|
70
|
+
|
|
71
|
+
## Diagnostic codes
|
|
72
|
+
|
|
73
|
+
| Code | Issue | Severity |
|
|
74
|
+
|------|---------------------------|-----------------|
|
|
75
|
+
| P001 | Low system Phi | error / warning |
|
|
76
|
+
| P002 | Zombie function | warning |
|
|
77
|
+
| P003 | High cyclomatic complexity| error / warning |
|
|
78
|
+
| P004 | Low causal density | info |
|
|
79
|
+
| P006 | Disconnected class | hint |
|
|
80
|
+
| P007 | God function | hint |
|
|
81
|
+
|
|
82
|
+
## Use as a library
|
|
83
|
+
|
|
84
|
+
from phi47 import Phi47Linter
|
|
85
|
+
linter = Phi47Linter()
|
|
86
|
+
for d in linter.lint_file("mycode.py"):
|
|
87
|
+
print(d)
|
|
88
|
+
|
|
89
|
+
## Scientific background
|
|
90
|
+
|
|
91
|
+
Phi47 applies spectral IIT 4.0 to dependency graphs:
|
|
92
|
+
Phi = H(eigenvalues(C*C^T)) * (1 - e^(-k))
|
|
93
|
+
Runs in O(n^3) instead of exact O(2^n).
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT License -- Copyright (c) 2025 Walter Calmels Von dem Knesebeck
|
|
98
|
+
TUCH Systems Research Laboratory
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/phi47/__init__.py
|
|
5
|
+
src/phi47/cli/__init__.py
|
|
6
|
+
src/phi47/cli/main.py
|
|
7
|
+
src/phi47/core/__init__.py
|
|
8
|
+
src/phi47/core/phi_calculator.py
|
|
9
|
+
src/phi47/linter/__init__.py
|
|
10
|
+
src/phi47/linter/phi_linter.py
|
|
11
|
+
src/phi47/wrapper/__init__.py
|
|
12
|
+
src/phi47/wrapper/llm_wrapper.py
|
|
13
|
+
src/phi47_superpowers.egg-info/PKG-INFO
|
|
14
|
+
src/phi47_superpowers.egg-info/SOURCES.txt
|
|
15
|
+
src/phi47_superpowers.egg-info/dependency_links.txt
|
|
16
|
+
src/phi47_superpowers.egg-info/entry_points.txt
|
|
17
|
+
src/phi47_superpowers.egg-info/requires.txt
|
|
18
|
+
src/phi47_superpowers.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
phi47
|