delimit-cli 4.1.44 → 4.1.48

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.
@@ -757,6 +757,56 @@ def preflight_check(
757
757
  }
758
758
 
759
759
 
760
+ # ═══════════════════════════════════════════════════════════════════════
761
+ # Task dispatch — used by loop_engine for governed build iterations
762
+ # ═══════════════════════════════════════════════════════════════════════
763
+
764
+ def dispatch_task(
765
+ title: str,
766
+ description: str = "",
767
+ context: str = "",
768
+ project_path: str = "",
769
+ priority: str = "P1",
770
+ ) -> Dict[str, Any]:
771
+ """Dispatch a task through the swarm governance layer.
772
+
773
+ This is called by the build loop to execute ledger items.
774
+ It logs the dispatch, checks approval tier, and returns
775
+ a result stub for the loop engine to track.
776
+ """
777
+ import uuid as _uuid
778
+
779
+ task_id = f"task-{_uuid.uuid4().hex[:8]}"
780
+
781
+ # Check approval
782
+ approval = check_approval("code_commit")
783
+ if approval.get("tier") == "founder_required":
784
+ _log({"action": "dispatch_blocked", "task_id": task_id, "title": title, "reason": "founder_required"})
785
+ return {
786
+ "task_id": task_id,
787
+ "status": "blocked",
788
+ "reason": "Requires founder approval",
789
+ "title": title,
790
+ }
791
+
792
+ _log({
793
+ "action": "dispatch_task",
794
+ "task_id": task_id,
795
+ "title": title,
796
+ "priority": priority,
797
+ "project_path": project_path,
798
+ })
799
+
800
+ return {
801
+ "task_id": task_id,
802
+ "status": "dispatched",
803
+ "title": title,
804
+ "priority": priority,
805
+ "project_path": project_path,
806
+ "estimated_cost": 0.05,
807
+ }
808
+
809
+
760
810
  # ═══════════════════════════════════════════════════════════════════════
761
811
  # LED-279: Self-Extending Swarm — Founder Mode
762
812
  # Agents can create new MCP tools when authorized
@@ -881,9 +931,43 @@ def hot_reload(reason: str = "update") -> Dict[str, Any]:
881
931
 
882
932
  Works across all AI CLIs because MCP servers are subprocesses —
883
933
  the CLI reconnects automatically within its timeout window (5-10s).
934
+
935
+ In-process fast path: when DELIMIT_INPROC_RELOAD is unset (default),
936
+ also runs importlib.reload() on known hot-reloadable ai.* modules so
937
+ newly-added functions become available without a full process restart.
884
938
  """
939
+ import importlib
940
+ import sys as _sys
941
+
885
942
  _ensure_dir()
886
943
 
944
+ # Fast path: reload key modules in-process. This lets new functions
945
+ # (e.g. dispatch_task added to ai.swarm) become available without a
946
+ # full subprocess restart. Modules with global state are skipped.
947
+ reloaded_modules: List[str] = []
948
+ reload_errors: List[str] = []
949
+ HOT_RELOADABLE = [
950
+ "ai.loop_engine",
951
+ "ai.social_target",
952
+ "ai.social",
953
+ "ai.reddit_scanner",
954
+ "ai.ledger_manager",
955
+ "ai.deliberation", # added 2026-04-09 per LED-805 — CLI stdin fix needed hot reload
956
+ "ai.backends.repo_bridge",
957
+ "ai.backends.tools_infra",
958
+ "backends.repo_bridge", # alias used by server.py lazy imports
959
+ "social", # alias
960
+ "ai.swarm", # self — reload last
961
+ ]
962
+ for modname in HOT_RELOADABLE:
963
+ if modname not in _sys.modules:
964
+ continue
965
+ try:
966
+ importlib.reload(_sys.modules[modname])
967
+ reloaded_modules.append(modname)
968
+ except Exception as e:
969
+ reload_errors.append(f"{modname}: {e}")
970
+
887
971
  # 1. Capture current state for transfer
888
972
  state = {
889
973
  "timestamp": time.time(),
@@ -922,7 +1006,10 @@ def hot_reload(reason: str = "update") -> Dict[str, Any]:
922
1006
  "method": restart_method,
923
1007
  "state_file": str(STATE_FILE),
924
1008
  "reason": reason,
1009
+ "reloaded_modules": reloaded_modules,
1010
+ "reload_errors": reload_errors,
925
1011
  "message": f"MCP server reload scheduled ({restart_method}). "
1012
+ f"In-process reloaded {len(reloaded_modules)} modules. "
926
1013
  "AI CLI will reconnect within 5-10 seconds. "
927
1014
  "Session context (ledger, memory, conversation) is preserved.",
928
1015
  "next_step": "The MCP server will restart and load updated modules. "