nexo-brain 3.0.2 → 3.1.0
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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +62 -0
- package/community/launch/2026-04-v3-0-2/case-study-outreach.md +36 -0
- package/community/launch/2026-04-v3-0-2/devto-v3-0-2.md +91 -0
- package/community/launch/2026-04-v3-0-2/github-discussion-v3-0-2.md +58 -0
- package/community/launch/2026-04-v3-0-2/x-thread-v3-0-2.md +60 -0
- package/hooks/hooks.json +12 -0
- package/package.json +1 -1
- package/src/client_sync.py +6 -0
- package/src/doctor/providers/runtime.py +10 -5
- package/src/evolution_cycle.py +28 -1
- package/src/hook_guardrails.py +182 -0
- package/src/hooks/protocol-guardrail.sh +1 -1
- package/src/hooks/protocol-pretool-guardrail.sh +9 -0
- package/src/plugins/protocol.py +15 -0
- package/src/protocol_settings.py +59 -0
- package/src/public_evolution_queue.py +241 -0
- package/src/scripts/nexo-daily-self-audit.py +665 -27
- package/src/scripts/nexo-evolution-run.py +35 -1
- package/src/server.py +26 -1
|
@@ -187,6 +187,10 @@ from public_contribution import (
|
|
|
187
187
|
mark_public_contribution_result,
|
|
188
188
|
STATUS_PAUSED_OPEN_PR,
|
|
189
189
|
)
|
|
190
|
+
from public_evolution_queue import (
|
|
191
|
+
list_pending_public_port_candidates,
|
|
192
|
+
update_public_port_candidate,
|
|
193
|
+
)
|
|
190
194
|
|
|
191
195
|
|
|
192
196
|
# ── Consecutive failure tracking ─────────────────────────────────────────
|
|
@@ -807,10 +811,19 @@ def run_public_contribution_cycle(*, objective: dict, cycle_num: int) -> None:
|
|
|
807
811
|
branch_name = ""
|
|
808
812
|
summary: dict = {}
|
|
809
813
|
conn = sqlite3.connect(str(NEXO_DB), timeout=10)
|
|
814
|
+
conn.row_factory = sqlite3.Row
|
|
815
|
+
queued_candidate: dict | None = None
|
|
810
816
|
try:
|
|
817
|
+
pending_candidates = list_pending_public_port_candidates(conn, limit=1)
|
|
818
|
+
if pending_candidates:
|
|
819
|
+
queued_candidate = pending_candidates[0]
|
|
811
820
|
worktree_dir, branch_name = _prepare_public_worktree(config, title_hint="public-core")
|
|
812
821
|
_prime_public_git_identity(worktree_dir, config)
|
|
813
|
-
prompt = build_public_contribution_prompt(
|
|
822
|
+
prompt = build_public_contribution_prompt(
|
|
823
|
+
repo_root=str(worktree_dir),
|
|
824
|
+
cycle_number=cycle_num,
|
|
825
|
+
queued_candidate=queued_candidate,
|
|
826
|
+
)
|
|
814
827
|
raw_response = call_public_claude_cli(prompt, cwd=worktree_dir)
|
|
815
828
|
summary = _parse_summary_json(raw_response)
|
|
816
829
|
changed_files = _changed_public_files(worktree_dir)
|
|
@@ -849,6 +862,14 @@ def run_public_contribution_cycle(*, objective: dict, cycle_num: int) -> None:
|
|
|
849
862
|
),
|
|
850
863
|
)
|
|
851
864
|
conn.commit()
|
|
865
|
+
if queued_candidate:
|
|
866
|
+
update_public_port_candidate(
|
|
867
|
+
conn,
|
|
868
|
+
queued_candidate["id"],
|
|
869
|
+
status="skipped_duplicate_existing_pr",
|
|
870
|
+
metadata_patch={"duplicate_of": duplicate},
|
|
871
|
+
)
|
|
872
|
+
conn.commit()
|
|
852
873
|
mark_public_contribution_result(
|
|
853
874
|
result=f"skipped:duplicate_pr:{duplicate.get('number')}",
|
|
854
875
|
config=config,
|
|
@@ -888,6 +909,19 @@ def run_public_contribution_cycle(*, objective: dict, cycle_num: int) -> None:
|
|
|
888
909
|
),
|
|
889
910
|
)
|
|
890
911
|
conn.commit()
|
|
912
|
+
if queued_candidate:
|
|
913
|
+
update_public_port_candidate(
|
|
914
|
+
conn,
|
|
915
|
+
queued_candidate["id"],
|
|
916
|
+
status="draft_pr_created",
|
|
917
|
+
metadata_patch={
|
|
918
|
+
"pr_url": pr_url,
|
|
919
|
+
"pr_number": pr_number,
|
|
920
|
+
"branch": branch_name,
|
|
921
|
+
"ported_via_cycle": cycle_num,
|
|
922
|
+
},
|
|
923
|
+
)
|
|
924
|
+
conn.commit()
|
|
891
925
|
|
|
892
926
|
objective["last_evolution"] = str(date.today())
|
|
893
927
|
objective["total_evolutions"] = cycle_num
|
package/src/server.py
CHANGED
|
@@ -213,6 +213,31 @@ mcp = FastMCP(
|
|
|
213
213
|
)
|
|
214
214
|
|
|
215
215
|
|
|
216
|
+
def _run_kwargs_from_env() -> dict:
|
|
217
|
+
transport = str(os.environ.get("NEXO_MCP_TRANSPORT", "stdio") or "stdio").strip().lower()
|
|
218
|
+
if transport in {"http", "streamable_http"}:
|
|
219
|
+
transport = "streamable-http"
|
|
220
|
+
if transport == "stdio":
|
|
221
|
+
return {"transport": "stdio"}
|
|
222
|
+
|
|
223
|
+
host = str(os.environ.get("NEXO_MCP_HOST", "127.0.0.1") or "127.0.0.1").strip()
|
|
224
|
+
port_text = str(os.environ.get("NEXO_MCP_PORT", "8000") or "8000").strip()
|
|
225
|
+
path = str(os.environ.get("NEXO_MCP_PATH", "/mcp") or "/mcp").strip() or "/mcp"
|
|
226
|
+
try:
|
|
227
|
+
port = int(port_text)
|
|
228
|
+
except Exception:
|
|
229
|
+
port = 8000
|
|
230
|
+
|
|
231
|
+
kwargs = {
|
|
232
|
+
"transport": transport,
|
|
233
|
+
"host": host,
|
|
234
|
+
"port": port,
|
|
235
|
+
}
|
|
236
|
+
if transport == "streamable-http":
|
|
237
|
+
kwargs["path"] = path
|
|
238
|
+
return kwargs
|
|
239
|
+
|
|
240
|
+
|
|
216
241
|
# ── Session management (3 tools) ──────────────────────────────────
|
|
217
242
|
|
|
218
243
|
@mcp.tool
|
|
@@ -912,4 +937,4 @@ def nexo_plugin_remove(filename: str) -> str:
|
|
|
912
937
|
|
|
913
938
|
if __name__ == "__main__":
|
|
914
939
|
_server_init()
|
|
915
|
-
mcp.run(
|
|
940
|
+
mcp.run(**_run_kwargs_from_env())
|