forge-lens-fl 0.2.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.
Files changed (89) hide show
  1. forge_lens_fl-0.2.0/LICENSE +21 -0
  2. forge_lens_fl-0.2.0/PKG-INFO +106 -0
  3. forge_lens_fl-0.2.0/README.md +80 -0
  4. forge_lens_fl-0.2.0/pyproject.toml +156 -0
  5. forge_lens_fl-0.2.0/pyproject.toml.orig +117 -0
  6. forge_lens_fl-0.2.0/src/forge_lens/__init__.py +3 -0
  7. forge_lens_fl-0.2.0/src/forge_lens/__main__.py +3 -0
  8. forge_lens_fl-0.2.0/src/forge_lens/adapters/__init__.py +5 -0
  9. forge_lens_fl-0.2.0/src/forge_lens/adapters/capabilities.py +70 -0
  10. forge_lens_fl-0.2.0/src/forge_lens/adapters/claude_code.py +210 -0
  11. forge_lens_fl-0.2.0/src/forge_lens/api/__init__.py +1 -0
  12. forge_lens_fl-0.2.0/src/forge_lens/api/app.py +2003 -0
  13. forge_lens_fl-0.2.0/src/forge_lens/api/clock.py +18 -0
  14. forge_lens_fl-0.2.0/src/forge_lens/cli/__init__.py +1 -0
  15. forge_lens_fl-0.2.0/src/forge_lens/cli/main.py +2620 -0
  16. forge_lens_fl-0.2.0/src/forge_lens/contracts/__init__.py +55 -0
  17. forge_lens_fl-0.2.0/src/forge_lens/contracts/base.py +16 -0
  18. forge_lens_fl-0.2.0/src/forge_lens/contracts/jsonschema.py +74 -0
  19. forge_lens_fl-0.2.0/src/forge_lens/contracts/provenance.py +28 -0
  20. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/__init__.py +58 -0
  21. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/agent.py +58 -0
  22. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/dataset.py +54 -0
  23. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/evaluation.py +33 -0
  24. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/evidence.py +52 -0
  25. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/experiment.py +70 -0
  26. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/refs.py +48 -0
  27. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/trace.py +149 -0
  28. forge_lens_fl-0.2.0/src/forge_lens/contracts/v1/usage.py +71 -0
  29. forge_lens_fl-0.2.0/src/forge_lens/core/__init__.py +1 -0
  30. forge_lens_fl-0.2.0/src/forge_lens/core/bounded.py +42 -0
  31. forge_lens_fl-0.2.0/src/forge_lens/core/config.py +208 -0
  32. forge_lens_fl-0.2.0/src/forge_lens/core/errors.py +35 -0
  33. forge_lens_fl-0.2.0/src/forge_lens/core/hashing.py +21 -0
  34. forge_lens_fl-0.2.0/src/forge_lens/core/ids.py +73 -0
  35. forge_lens_fl-0.2.0/src/forge_lens/core/jsonutil.py +45 -0
  36. forge_lens_fl-0.2.0/src/forge_lens/core/metrics.py +86 -0
  37. forge_lens_fl-0.2.0/src/forge_lens/core/time.py +60 -0
  38. forge_lens_fl-0.2.0/src/forge_lens/eval/__init__.py +19 -0
  39. forge_lens_fl-0.2.0/src/forge_lens/eval/compare.py +355 -0
  40. forge_lens_fl-0.2.0/src/forge_lens/eval/evaluators.py +1229 -0
  41. forge_lens_fl-0.2.0/src/forge_lens/eval/runner.py +76 -0
  42. forge_lens_fl-0.2.0/src/forge_lens/graph/__init__.py +24 -0
  43. forge_lens_fl-0.2.0/src/forge_lens/graph/algorithms.py +147 -0
  44. forge_lens_fl-0.2.0/src/forge_lens/graph/builder.py +203 -0
  45. forge_lens_fl-0.2.0/src/forge_lens/graph/models.py +62 -0
  46. forge_lens_fl-0.2.0/src/forge_lens/ingest/__init__.py +1 -0
  47. forge_lens_fl-0.2.0/src/forge_lens/ingest/pipeline.py +326 -0
  48. forge_lens_fl-0.2.0/src/forge_lens/install/__init__.py +1 -0
  49. forge_lens_fl-0.2.0/src/forge_lens/install/guided.py +171 -0
  50. forge_lens_fl-0.2.0/src/forge_lens/install/lifecycle.py +133 -0
  51. forge_lens_fl-0.2.0/src/forge_lens/intel/__init__.py +21 -0
  52. forge_lens_fl-0.2.0/src/forge_lens/intel/correlation.py +776 -0
  53. forge_lens_fl-0.2.0/src/forge_lens/intel/cost.py +123 -0
  54. forge_lens_fl-0.2.0/src/forge_lens/intel/efficiency.py +74 -0
  55. forge_lens_fl-0.2.0/src/forge_lens/intel/graph_intel.py +54 -0
  56. forge_lens_fl-0.2.0/src/forge_lens/intel/pricing.py +180 -0
  57. forge_lens_fl-0.2.0/src/forge_lens/intel/recommendations.py +75 -0
  58. forge_lens_fl-0.2.0/src/forge_lens/intel/regressions.py +61 -0
  59. forge_lens_fl-0.2.0/src/forge_lens/intel/waste.py +180 -0
  60. forge_lens_fl-0.2.0/src/forge_lens/investigate/__init__.py +35 -0
  61. forge_lens_fl-0.2.0/src/forge_lens/investigate/bundle.py +47 -0
  62. forge_lens_fl-0.2.0/src/forge_lens/investigate/classify.py +629 -0
  63. forge_lens_fl-0.2.0/src/forge_lens/investigate/eval_suggest.py +364 -0
  64. forge_lens_fl-0.2.0/src/forge_lens/investigate/hypothesis.py +419 -0
  65. forge_lens_fl-0.2.0/src/forge_lens/investigate/replay.py +83 -0
  66. forge_lens_fl-0.2.0/src/forge_lens/mcp_server.py +456 -0
  67. forge_lens_fl-0.2.0/src/forge_lens/ops/__init__.py +29 -0
  68. forge_lens_fl-0.2.0/src/forge_lens/ops/agents.py +189 -0
  69. forge_lens_fl-0.2.0/src/forge_lens/ops/alerts.py +394 -0
  70. forge_lens_fl-0.2.0/src/forge_lens/ops/loops.py +113 -0
  71. forge_lens_fl-0.2.0/src/forge_lens/otlp/__init__.py +1 -0
  72. forge_lens_fl-0.2.0/src/forge_lens/otlp/normalize.py +398 -0
  73. forge_lens_fl-0.2.0/src/forge_lens/otlp/openinference.py +161 -0
  74. forge_lens_fl-0.2.0/src/forge_lens/sanitize/__init__.py +1 -0
  75. forge_lens_fl-0.2.0/src/forge_lens/sanitize/redact.py +426 -0
  76. forge_lens_fl-0.2.0/src/forge_lens/sdk/__init__.py +18 -0
  77. forge_lens_fl-0.2.0/src/forge_lens/sdk/context.py +56 -0
  78. forge_lens_fl-0.2.0/src/forge_lens/sdk/exporter.py +97 -0
  79. forge_lens_fl-0.2.0/src/forge_lens/sdk/query.py +621 -0
  80. forge_lens_fl-0.2.0/src/forge_lens/sdk/tracer.py +635 -0
  81. forge_lens_fl-0.2.0/src/forge_lens/security/__init__.py +27 -0
  82. forge_lens_fl-0.2.0/src/forge_lens/security/keys.py +58 -0
  83. forge_lens_fl-0.2.0/src/forge_lens/security/mcp_inspect.py +122 -0
  84. forge_lens_fl-0.2.0/src/forge_lens/storage/__init__.py +1 -0
  85. forge_lens_fl-0.2.0/src/forge_lens/storage/base.py +233 -0
  86. forge_lens_fl-0.2.0/src/forge_lens/storage/sqlite.py +2082 -0
  87. forge_lens_fl-0.2.0/src/forge_lens/ui/__init__.py +29 -0
  88. forge_lens_fl-0.2.0/src/forge_lens/ui/i18n.py +143 -0
  89. forge_lens_fl-0.2.0/src/forge_lens/ui/kit.py +689 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Edgar Sócrates Caria
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.
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.4
2
+ Name: forge-lens-fl
3
+ Version: 0.2.0
4
+ Summary: Local-first, open-source agentic observability: traces, tools, tokens, cost and evidence.
5
+ Keywords: observability,opentelemetry,openinference,agents,llm,tracing
6
+ Author: Edgar Sócrates Caria
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Dist: pydantic>=2.7
17
+ Requires-Dist: typer>=0.12
18
+ Requires-Dist: rich>=13.7
19
+ Requires-Dist: fastapi>=0.115 ; extra == 'server'
20
+ Requires-Dist: uvicorn>=0.30 ; extra == 'server'
21
+ Requires-Python: >=3.11
22
+ Project-URL: Repository, https://github.com/EdgarSocrates98/forge-lens
23
+ Project-URL: Issues, https://github.com/EdgarSocrates98/forge-lens/issues
24
+ Provides-Extra: server
25
+ Description-Content-Type: text/markdown
26
+
27
+ # Forge Lens
28
+
29
+ <p align="center">
30
+ <img src="docs/assets/logo.png" alt="Forge Lens logo" width="420" />
31
+ </p>
32
+
33
+ **Local-first, open-source agentic observability.** Understand every agent execution. Trace every tool. Measure every cost. Investigate every failure. Prove every improvement.
34
+
35
+ Forge Lens receives, persists and explains agent executions — via OTLP/HTTP, OpenInference attributes, or its own SDKs — on your machine, with no mandatory external dependency.
36
+
37
+ ## Status
38
+
39
+ Cycles 00–01 (foundation, verified): contracts v1, OTLP/HTTP JSON ingestion, sanitization, SQLite WAL store, Python + TypeScript SDKs, CLI.
40
+ Cycles 03–06 backend: temporal execution graph (`/v1/graph/*`), token/cost intelligence (`/v1/traces/{id}/cost`), failure classification + recorded replay + incident bundles (`/v1/traces/{id}/failure|replay|incident`), deterministic evaluation (`/v1/eval/*`), versioned datasets + regression gates — reports in `docs/cycles/`.
41
+ Cycle 02: Angular Studio (`apps/studio`) — Trace Explorer with sortable/filterable list, waterfall with span detail, an evidence pane (cost/failure/loops/graph-analysis payloads rendered as JSON, plus eval results and recorded replay in tables), ops summary view, host-capability table, dark/light themes, URL-state sync, lazy routes, typed API client.
42
+ Cycle 07: loop/no-progress detection (`/v1/traces/{id}/loops`), bounded specialist runtime (`/v1/analyze/*`), threshold alerts (`/v1/alerts/evaluate`), ops summary (`/v1/ops/summary`), MCP security observer (`/v1/traces/{id}/security`).
43
+ Cycle 08: auth modes (`none|key|keys`) with API keys + roles + per-project tenancy, audit trail (`/v1/admin/audit`), retention (`forge-lens prune|archive`, `/v1/admin/prune`), TLS passthrough on `serve`.
44
+ Cycle 09: SSE replay (`/v1/traces/{id}/stream`), measured benchmarks at 1k/10k/100k spans (`scripts/benchmark.py` → `docs/benchmarks/`), archive-before-delete lifecycle.
45
+ Cycle 10: honest host-capability matrix (`/v1/capabilities`), Claude Code JSONL importer (`import-claude`), MCP stdio observer (`mcp-serve`), install lifecycle receipts (`install-status`), 7 skills in `skills/`.
46
+ Cycle 11: CycloneDX SBOM generator (`scripts/gen_sbom.py`), release workflow with OIDC trusted publishing + version gate, `CHANGELOG.md`, `docs/versioning.md`, Studio CI job.
47
+ Cycle 12: efficiency intelligence (`/v1/intel/efficiency`, `/v1/traces/{id}/efficiency`), cohort regression (`/v1/intel/regress`), candidate recommendations (`/v1/traces/{id}/recommendations`), graph centrality/concentration analysis (`/v1/graph/traces/{id}/analysis`).
48
+
49
+ ## Quickstart
50
+
51
+ Portable install (same model as the other Forge projects — venv under
52
+ `~/.forge/installs/forge-lens`, launcher on PATH, no project-venv
53
+ touch):
54
+
55
+ ```bash
56
+ ./install.sh # POSIX; . .\install.ps1 on PowerShell
57
+ forge-lens init .
58
+ forge-lens serve # API on http://127.0.0.1:7777
59
+ forge-lens doctor
60
+ ```
61
+
62
+ Dev checkout alternative: `uv sync --extra server && uv run forge-lens ...`.
63
+
64
+ Instrument an agent:
65
+
66
+ ```python
67
+ from forge_lens.sdk import LensTracer
68
+ from forge_lens.sdk.exporter import HTTPExporter
69
+
70
+ tracer = LensTracer(
71
+ service_name="my-agent",
72
+ exporter=HTTPExporter("http://127.0.0.1:7777"),
73
+ )
74
+
75
+ with tracer.agent("researcher"):
76
+ with tracer.llm_call("claude-sonnet-4", provider="anthropic") as s:
77
+ tracer.record_usage(s, input_tokens=200, output_tokens=80, total_tokens=280)
78
+ with tracer.tool_call("web_search"):
79
+ ... # call the tool
80
+ ```
81
+
82
+ Inspect:
83
+
84
+ ```bash
85
+ forge-lens traces list
86
+ forge-lens traces show <trace-id>
87
+ ```
88
+
89
+ A runnable offline demo (SDK → pipeline → store → read-back, no server):
90
+ `uv run python examples/quickstart.py`
91
+
92
+ ## Principles
93
+
94
+ - **Local-first** — SQLite WAL by default; works fully offline.
95
+ - **Evidence-first** — every claim carries provenance (`observed` / `imported` / `derived` / `inferred` / `unknown`). Inferred never silently becomes observed.
96
+ - **Safe by default** — `capture=metadata` redacts secrets and drops prompt bodies unless you opt into `full`.
97
+ - **OTel/OpenInference compatible** — OTLP/HTTP JSON ingest, `openinference.*` attribute mapping, W3C traceparent propagation.
98
+
99
+ ## Documentation
100
+
101
+ See `docs/` — architecture, guides, API/CLI/contracts reference, ADRs and cycle reports (PT-BR first, EN planned).
102
+
103
+ - `docs/guides/quickstart.md` — first trace in minutes
104
+ - `docs/guides/operations-runbook.md` — serve, auth modes, retention, backups, monitoring, alert rules
105
+ - `docs/guides/troubleshooting.md` — symptom → cause → fix
106
+ - `docs/guides/failure-investigation.md` — failure taxonomy (§05.3), root-cause hypotheses (§05.4), eval suggestions (§12.7)
@@ -0,0 +1,80 @@
1
+ # Forge Lens
2
+
3
+ <p align="center">
4
+ <img src="docs/assets/logo.png" alt="Forge Lens logo" width="420" />
5
+ </p>
6
+
7
+ **Local-first, open-source agentic observability.** Understand every agent execution. Trace every tool. Measure every cost. Investigate every failure. Prove every improvement.
8
+
9
+ Forge Lens receives, persists and explains agent executions — via OTLP/HTTP, OpenInference attributes, or its own SDKs — on your machine, with no mandatory external dependency.
10
+
11
+ ## Status
12
+
13
+ Cycles 00–01 (foundation, verified): contracts v1, OTLP/HTTP JSON ingestion, sanitization, SQLite WAL store, Python + TypeScript SDKs, CLI.
14
+ Cycles 03–06 backend: temporal execution graph (`/v1/graph/*`), token/cost intelligence (`/v1/traces/{id}/cost`), failure classification + recorded replay + incident bundles (`/v1/traces/{id}/failure|replay|incident`), deterministic evaluation (`/v1/eval/*`), versioned datasets + regression gates — reports in `docs/cycles/`.
15
+ Cycle 02: Angular Studio (`apps/studio`) — Trace Explorer with sortable/filterable list, waterfall with span detail, an evidence pane (cost/failure/loops/graph-analysis payloads rendered as JSON, plus eval results and recorded replay in tables), ops summary view, host-capability table, dark/light themes, URL-state sync, lazy routes, typed API client.
16
+ Cycle 07: loop/no-progress detection (`/v1/traces/{id}/loops`), bounded specialist runtime (`/v1/analyze/*`), threshold alerts (`/v1/alerts/evaluate`), ops summary (`/v1/ops/summary`), MCP security observer (`/v1/traces/{id}/security`).
17
+ Cycle 08: auth modes (`none|key|keys`) with API keys + roles + per-project tenancy, audit trail (`/v1/admin/audit`), retention (`forge-lens prune|archive`, `/v1/admin/prune`), TLS passthrough on `serve`.
18
+ Cycle 09: SSE replay (`/v1/traces/{id}/stream`), measured benchmarks at 1k/10k/100k spans (`scripts/benchmark.py` → `docs/benchmarks/`), archive-before-delete lifecycle.
19
+ Cycle 10: honest host-capability matrix (`/v1/capabilities`), Claude Code JSONL importer (`import-claude`), MCP stdio observer (`mcp-serve`), install lifecycle receipts (`install-status`), 7 skills in `skills/`.
20
+ Cycle 11: CycloneDX SBOM generator (`scripts/gen_sbom.py`), release workflow with OIDC trusted publishing + version gate, `CHANGELOG.md`, `docs/versioning.md`, Studio CI job.
21
+ Cycle 12: efficiency intelligence (`/v1/intel/efficiency`, `/v1/traces/{id}/efficiency`), cohort regression (`/v1/intel/regress`), candidate recommendations (`/v1/traces/{id}/recommendations`), graph centrality/concentration analysis (`/v1/graph/traces/{id}/analysis`).
22
+
23
+ ## Quickstart
24
+
25
+ Portable install (same model as the other Forge projects — venv under
26
+ `~/.forge/installs/forge-lens`, launcher on PATH, no project-venv
27
+ touch):
28
+
29
+ ```bash
30
+ ./install.sh # POSIX; . .\install.ps1 on PowerShell
31
+ forge-lens init .
32
+ forge-lens serve # API on http://127.0.0.1:7777
33
+ forge-lens doctor
34
+ ```
35
+
36
+ Dev checkout alternative: `uv sync --extra server && uv run forge-lens ...`.
37
+
38
+ Instrument an agent:
39
+
40
+ ```python
41
+ from forge_lens.sdk import LensTracer
42
+ from forge_lens.sdk.exporter import HTTPExporter
43
+
44
+ tracer = LensTracer(
45
+ service_name="my-agent",
46
+ exporter=HTTPExporter("http://127.0.0.1:7777"),
47
+ )
48
+
49
+ with tracer.agent("researcher"):
50
+ with tracer.llm_call("claude-sonnet-4", provider="anthropic") as s:
51
+ tracer.record_usage(s, input_tokens=200, output_tokens=80, total_tokens=280)
52
+ with tracer.tool_call("web_search"):
53
+ ... # call the tool
54
+ ```
55
+
56
+ Inspect:
57
+
58
+ ```bash
59
+ forge-lens traces list
60
+ forge-lens traces show <trace-id>
61
+ ```
62
+
63
+ A runnable offline demo (SDK → pipeline → store → read-back, no server):
64
+ `uv run python examples/quickstart.py`
65
+
66
+ ## Principles
67
+
68
+ - **Local-first** — SQLite WAL by default; works fully offline.
69
+ - **Evidence-first** — every claim carries provenance (`observed` / `imported` / `derived` / `inferred` / `unknown`). Inferred never silently becomes observed.
70
+ - **Safe by default** — `capture=metadata` redacts secrets and drops prompt bodies unless you opt into `full`.
71
+ - **OTel/OpenInference compatible** — OTLP/HTTP JSON ingest, `openinference.*` attribute mapping, W3C traceparent propagation.
72
+
73
+ ## Documentation
74
+
75
+ See `docs/` — architecture, guides, API/CLI/contracts reference, ADRs and cycle reports (PT-BR first, EN planned).
76
+
77
+ - `docs/guides/quickstart.md` — first trace in minutes
78
+ - `docs/guides/operations-runbook.md` — serve, auth modes, retention, backups, monitoring, alert rules
79
+ - `docs/guides/troubleshooting.md` — symptom → cause → fix
80
+ - `docs/guides/failure-investigation.md` — failure taxonomy (§05.3), root-cause hypotheses (§05.4), eval suggestions (§12.7)
@@ -0,0 +1,156 @@
1
+ [project]
2
+ name = "forge-lens-fl"
3
+ version = "0.2.0"
4
+ description = "Local-first, open-source agentic observability: traces, tools, tokens, cost and evidence."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ classifiers = [
10
+ "Development Status :: 3 - Alpha",
11
+ "Intended Audience :: Developers",
12
+ "Programming Language :: Python :: 3.11",
13
+ "Programming Language :: Python :: 3.12",
14
+ "Programming Language :: Python :: 3.13",
15
+ "Programming Language :: Python :: 3.14",
16
+ "Operating System :: OS Independent",
17
+ ]
18
+ keywords = [
19
+ "observability",
20
+ "opentelemetry",
21
+ "openinference",
22
+ "agents",
23
+ "llm",
24
+ "tracing",
25
+ ]
26
+ dependencies = [
27
+ "pydantic>=2.7",
28
+ "typer>=0.12",
29
+ "rich>=13.7",
30
+ ]
31
+
32
+ [[project.authors]]
33
+ name = "Edgar Sócrates Caria"
34
+
35
+ [project.optional-dependencies]
36
+ server = [
37
+ "fastapi>=0.115",
38
+ "uvicorn>=0.30",
39
+ ]
40
+
41
+ [project.urls]
42
+ Repository = "https://github.com/EdgarSocrates98/forge-lens"
43
+ Issues = "https://github.com/EdgarSocrates98/forge-lens/issues"
44
+
45
+ [project.scripts]
46
+ forge-lens = "forge_lens.cli.main:main"
47
+
48
+ [dependency-groups]
49
+ lint = ["ruff>=0.8"]
50
+ test = [
51
+ "pytest>=8.0",
52
+ "pytest-cov>=6.0",
53
+ "httpx>=0.27",
54
+ ]
55
+ types = ["mypy>=1.13"]
56
+ audit = ["pip-audit>=2.7"]
57
+
58
+ [[dependency-groups.dev]]
59
+ include-group = "lint"
60
+
61
+ [[dependency-groups.dev]]
62
+ include-group = "test"
63
+
64
+ [[dependency-groups.dev]]
65
+ include-group = "types"
66
+
67
+ [[dependency-groups.dev]]
68
+ include-group = "audit"
69
+
70
+ [build-system]
71
+ requires = ["uv_build>=0.8.0,<0.13"]
72
+ build-backend = "uv_build"
73
+
74
+ [tool.uv.build-backend]
75
+ module-name = "forge_lens"
76
+
77
+ [tool.ruff]
78
+ line-length = 100
79
+ target-version = "py311"
80
+ src = [
81
+ "src",
82
+ "tests",
83
+ ]
84
+
85
+ [tool.ruff.lint]
86
+ select = [
87
+ "E",
88
+ "F",
89
+ "W",
90
+ "I",
91
+ "UP",
92
+ "B",
93
+ "SIM",
94
+ "C4",
95
+ "RUF",
96
+ "S",
97
+ "DTZ",
98
+ "PT",
99
+ "PTH",
100
+ "TID",
101
+ ]
102
+ ignore = ["S608"]
103
+
104
+ [tool.ruff.lint.per-file-ignores]
105
+ "scripts/forge_bootstrap.py" = ["ALL"]
106
+ "scripts/lab/forge_lens_lab.py" = ["S314"]
107
+ "tests/**" = [
108
+ "S101",
109
+ "PT011",
110
+ "PTH",
111
+ "S105",
112
+ "S106",
113
+ ]
114
+ "examples/**" = [
115
+ "S101",
116
+ "T201",
117
+ ]
118
+ "homolog/**" = [
119
+ "S101",
120
+ "S105",
121
+ "S310",
122
+ "S603",
123
+ "PTH",
124
+ ]
125
+ "src/forge_lens/cli/**" = ["T201"]
126
+ "src/forge_lens/ui/**/*.py" = ["ALL"]
127
+
128
+ [tool.pytest.ini_options]
129
+ testpaths = ["tests"]
130
+ addopts = "-q"
131
+ markers = [
132
+ "e2e: end-to-end scenarios",
133
+ "contract: contract and schema tests",
134
+ "benchmark: benchmark smoke tests (tests/bench)",
135
+ "network: legitimately opens sockets (exempt from the offline gate)",
136
+ ]
137
+
138
+ [tool.coverage.run]
139
+ source = ["src/forge_lens"]
140
+ omit = ["tests/*"]
141
+
142
+ [tool.coverage.report]
143
+ show_missing = true
144
+ exclude_also = [
145
+ "if TYPE_CHECKING:",
146
+ "raise NotImplementedError",
147
+ "@overload",
148
+ ]
149
+
150
+ [tool.mypy]
151
+ python_version = "3.11"
152
+ mypy_path = "src"
153
+ packages = ["forge_lens"]
154
+ strict = true
155
+ warn_unreachable = true
156
+ exclude = ["forge_lens.ui"]
@@ -0,0 +1,117 @@
1
+ [project]
2
+ name = "forge-lens-fl"
3
+ version = "0.2.0"
4
+ description = "Local-first, open-source agentic observability: traces, tools, tokens, cost and evidence."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ authors = [{ name = "Edgar Sócrates Caria" }]
8
+ license = "MIT"
9
+ license-files = ["LICENSE"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "Programming Language :: Python :: 3.11",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Programming Language :: Python :: 3.13",
16
+ "Programming Language :: Python :: 3.14",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ keywords = ["observability", "opentelemetry", "openinference", "agents", "llm", "tracing"]
20
+ dependencies = [
21
+ "pydantic>=2.7",
22
+ "typer>=0.12",
23
+ "rich>=13.7",
24
+ ]
25
+
26
+ [project.optional-dependencies]
27
+ server = [
28
+ "fastapi>=0.115",
29
+ "uvicorn>=0.30",
30
+ ]
31
+
32
+ [project.urls]
33
+ Repository = "https://github.com/EdgarSocrates98/forge-lens"
34
+ Issues = "https://github.com/EdgarSocrates98/forge-lens/issues"
35
+
36
+ [project.scripts]
37
+ # Route the installed command through the small dispatcher so a bare
38
+ # `forge-lens install` gets the guided wizard on a real TTY. Pointing the
39
+ # entry point directly at the Typer object bypasses that contract in wheels.
40
+ forge-lens = "forge_lens.cli.main:main"
41
+
42
+ [dependency-groups]
43
+ dev = [
44
+ { include-group = "lint" },
45
+ { include-group = "test" },
46
+ { include-group = "types" },
47
+ { include-group = "audit" },
48
+ ]
49
+ lint = ["ruff>=0.8"]
50
+ test = [
51
+ "pytest>=8.0",
52
+ "pytest-cov>=6.0",
53
+ "httpx>=0.27",
54
+ ]
55
+ types = ["mypy>=1.13"]
56
+ audit = ["pip-audit>=2.7"]
57
+
58
+ [build-system]
59
+ requires = ["uv_build>=0.8.0,<0.13"]
60
+ build-backend = "uv_build"
61
+
62
+ # The PyPI distribution is `forge-lens-fl` but the import package stays
63
+ # `forge_lens` — without this, uv_build expects src/forge_lens_fl/.
64
+ [tool.uv.build-backend]
65
+ module-name = "forge_lens"
66
+
67
+ [tool.ruff]
68
+ line-length = 100
69
+ target-version = "py311"
70
+ src = ["src", "tests"]
71
+
72
+ [tool.ruff.lint]
73
+ select = ["E", "F", "W", "I", "UP", "B", "SIM", "C4", "RUF", "S", "DTZ", "PT", "PTH", "TID"]
74
+ ignore = [
75
+ "S608", # SQL is built from fixed fragments + parameters only
76
+ ]
77
+
78
+ [tool.ruff.lint.per-file-ignores]
79
+ # Vendored shared bootstrap — canonical copy in forge-doctor-api is the lint target.
80
+ "scripts/forge_bootstrap.py" = ["ALL"]
81
+ # Lab emitter parses its own just-written junit artifact — not untrusted input.
82
+ "scripts/lab/forge_lens_lab.py" = ["S314"]
83
+ "tests/**" = ["S101", "PT011", "PTH", "S105", "S106"]
84
+ "examples/**" = ["S101", "T201"]
85
+ # Homologation runner — subprocess/urllib against the local install is the point.
86
+ "homolog/**" = ["S101", "S105", "S310", "S603", "PTH"]
87
+ "src/forge_lens/cli/**" = ["T201"]
88
+ # Vendored Forge UI kit (canonical: the-forge/src/theforge/ui) —
89
+ # byte-identical to the shared source; linted in the canonical repo.
90
+ "src/forge_lens/ui/**/*.py" = ["ALL"]
91
+
92
+ [tool.pytest.ini_options]
93
+ testpaths = ["tests"]
94
+ addopts = "-q"
95
+ markers = [
96
+ "e2e: end-to-end scenarios",
97
+ "contract: contract and schema tests",
98
+ "benchmark: benchmark smoke tests (tests/bench)",
99
+ "network: legitimately opens sockets (exempt from the offline gate)",
100
+ ]
101
+
102
+ [tool.coverage.run]
103
+ source = ["src/forge_lens"]
104
+ omit = ["tests/*"]
105
+
106
+ [tool.coverage.report]
107
+ show_missing = true
108
+ exclude_also = ["if TYPE_CHECKING:", "raise NotImplementedError", "@overload"]
109
+
110
+ [tool.mypy]
111
+ python_version = "3.11"
112
+ mypy_path = "src"
113
+ packages = ["forge_lens"]
114
+ strict = true
115
+ warn_unreachable = true
116
+ # Vendored Forge UI kit — mesma razão da exclusão de lint.
117
+ exclude = ["forge_lens.ui"]
@@ -0,0 +1,3 @@
1
+ """Forge Lens — local-first agentic observability and intelligence."""
2
+
3
+ __version__ = "0.2.0"
@@ -0,0 +1,3 @@
1
+ from forge_lens.cli.main import main
2
+
3
+ main()
@@ -0,0 +1,5 @@
1
+ """Host/runtime adapters — Cycle 10. Optional, evidence-first."""
2
+
3
+ from forge_lens.adapters.capabilities import HOST_CAPABILITIES, capability_matrix
4
+
5
+ __all__ = ["HOST_CAPABILITIES", "capability_matrix"]
@@ -0,0 +1,70 @@
1
+ """Honest host capability matrix — Cycle 10.
2
+
3
+ Every host entry states WHAT is actually instrumentable, through which
4
+ mechanism. 'unsupported' is a valid answer — the matrix exists so
5
+ nobody claims coverage that doesn't exist.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+
12
+ HOST_CAPABILITIES: dict[str, dict[str, Any]] = {
13
+ "claude_code": {
14
+ "native_tracing": False,
15
+ "mechanism": "hooks + session JSONL logs",
16
+ "adapter": "adapters.claude_code (JSONL import → Trace)",
17
+ "coverage": "tool calls, model usage, session boundaries",
18
+ "limits": "no in-process span capture; log-derived only",
19
+ },
20
+ "codex": {
21
+ "native_tracing": False,
22
+ "mechanism": "session logs / rollout files",
23
+ "adapter": "not implemented — log format unstable",
24
+ "coverage": "none claimed",
25
+ "limits": "unsupported today",
26
+ },
27
+ "devin": {
28
+ "native_tracing": False,
29
+ "mechanism": "unsupported — no public instrumentation surface",
30
+ "adapter": None,
31
+ "coverage": "none",
32
+ "limits": "unsupported",
33
+ },
34
+ "copilot": {
35
+ "native_tracing": False,
36
+ "mechanism": "unsupported — closed surface",
37
+ "adapter": None,
38
+ "coverage": "none",
39
+ "limits": "unsupported",
40
+ },
41
+ "cursor": {
42
+ "native_tracing": False,
43
+ "mechanism": "MCP instrumentation point exists (client-side)",
44
+ "adapter": "forge_lens.mcp_server used as gateway observer",
45
+ "coverage": "MCP tool list/call/result only — NOT agent internals",
46
+ "limits": "MCP traffic only; no claim of full tracing",
47
+ },
48
+ "forge": {
49
+ "native_tracing": True,
50
+ "mechanism": "in-process SDK instrumentation",
51
+ "adapter": "forge_lens.sdk (native)",
52
+ "coverage": "full spans, tools, tokens",
53
+ "limits": "requires opt-in tracing init",
54
+ },
55
+ "generic_otlp": {
56
+ "native_tracing": True,
57
+ "mechanism": "OTLP/HTTP JSON endpoint",
58
+ "adapter": "built-in",
59
+ "coverage": "whatever the runtime emits",
60
+ "limits": "span quality depends on emitter",
61
+ },
62
+ }
63
+
64
+
65
+ def capability_matrix() -> dict[str, Any]:
66
+ return {
67
+ "hosts": {k: dict(v) for k, v in sorted(HOST_CAPABILITIES.items())},
68
+ "note": "coverage claims are per-mechanism; 'unsupported' means"
69
+ " no verified path exists today",
70
+ }