arkaos 4.0.2 → 4.1.1
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/README.md +2 -2
- package/VERSION +1 -1
- package/arka/SKILL.md +16 -22
- package/arka/skills/flow/SKILL.md +108 -234
- package/config/claude-agents/eduardo-copy.md +53 -0
- package/config/claude-agents/francisca-tech.md +52 -0
- package/config/claude-agents/marta-cqo.md +52 -0
- package/config/claude-agents/paulo-tech-lead.md +50 -0
- package/config/cognition/schedules.yaml +15 -0
- package/config/constitution.yaml +17 -21
- package/config/hooks/_lib/workflow-classifier.sh +1 -1
- package/config/hooks/post-tool-use.sh +52 -536
- package/config/hooks/pre-tool-use.sh +46 -280
- package/config/hooks/session-start.sh +8 -10
- package/config/hooks/stop.sh +44 -424
- package/config/hooks/user-prompt-submit.sh +55 -457
- package/core/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/cognition/__pycache__/dreaming.cpython-313.pyc +0 -0
- package/core/cognition/dreaming.py +5 -0
- package/core/cognition/scheduler/__pycache__/daemon.cpython-313.pyc +0 -0
- package/core/cognition/scheduler/daemon.py +10 -0
- package/core/forge/__init__.py +2 -0
- package/core/forge/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/forge/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/core/forge/__pycache__/persistence.cpython-313.pyc +0 -0
- package/core/forge/__pycache__/renderer.cpython-313.pyc +0 -0
- package/core/forge/__pycache__/runtime_dispatcher.cpython-313.pyc +0 -0
- package/core/forge/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/forge/orchestrator.py +50 -27
- package/core/forge/persistence.py +16 -0
- package/core/forge/renderer.py +16 -0
- package/core/forge/runtime_dispatcher.py +34 -19
- package/core/forge/schema.py +12 -0
- package/core/governance/__pycache__/__init__.cpython-312.pyc +0 -0
- package/core/governance/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/governance/__pycache__/closing_marker_check.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/closing_marker_check.cpython-314.pyc +0 -0
- package/core/governance/__pycache__/compliance_telemetry.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/constitution.cpython-312.pyc +0 -0
- package/core/governance/__pycache__/constitution.cpython-314.pyc +0 -0
- package/core/governance/__pycache__/evidence_checks.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/kb_cite_check.cpython-314.pyc +0 -0
- package/core/governance/__pycache__/meta_tag_check.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/meta_tag_check.cpython-314.pyc +0 -0
- package/core/governance/__pycache__/qg_verdict.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/review_workflow.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/skill_proposer.cpython-313.pyc +0 -0
- package/core/governance/__pycache__/skill_proposer.cpython-314.pyc +0 -0
- package/core/governance/__pycache__/sycophancy_detector.cpython-314.pyc +0 -0
- package/core/governance/closing_marker_check.py +9 -5
- package/core/governance/compliance_telemetry.py +1 -1
- package/core/governance/compliance_telemetry_cli.py +1 -1
- package/core/governance/evidence_checks.py +421 -0
- package/core/governance/meta_tag_check.py +36 -0
- package/core/governance/qg_verdict.py +78 -0
- package/core/governance/review_workflow.py +34 -1
- package/core/governance/skill_proposer.py +2 -1
- package/core/hooks/__init__.py +12 -0
- package/core/hooks/__pycache__/__init__.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/_shared.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/_shared.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/_shared.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/post_tool_use.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/post_tool_use.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/pre_tool_use.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/pre_tool_use.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/pre_tool_use.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/stop.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/stop.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/stop.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/user_prompt_submit.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/core/hooks/_shared.py +110 -0
- package/core/hooks/post_tool_use.py +689 -0
- package/core/hooks/pre_tool_use.py +267 -0
- package/core/hooks/stop.py +395 -0
- package/core/hooks/user_prompt_submit.py +600 -0
- package/core/jobs/__pycache__/__init__.cpython-312.pyc +0 -0
- package/core/jobs/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/jobs/__pycache__/auto_doc_worker.cpython-312.pyc +0 -0
- package/core/jobs/__pycache__/auto_doc_worker.cpython-314.pyc +0 -0
- package/core/jobs/__pycache__/manager.cpython-312.pyc +0 -0
- package/core/jobs/__pycache__/manager.cpython-314.pyc +0 -0
- package/core/knowledge/__pycache__/embedder.cpython-312.pyc +0 -0
- package/core/knowledge/__pycache__/embedder.cpython-313.pyc +0 -0
- package/core/knowledge/__pycache__/vector_store.cpython-312.pyc +0 -0
- package/core/knowledge/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/core/knowledge/embedder.py +118 -11
- package/core/knowledge/vector_store.py +111 -14
- package/core/memory/__pycache__/session_store.cpython-314.pyc +0 -0
- package/core/obsidian/__pycache__/relator.cpython-313.pyc +0 -0
- package/core/obsidian/relator.py +18 -8
- package/core/runtime/__pycache__/__init__.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/base.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/base.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/base.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/capabilities_cli.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/capabilities_cli.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/claude_code.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/claude_code.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/claude_code.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/codex_cli.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/codex_cli.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/codex_cli.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/cost_governor.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/cost_governor.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/cursor.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/cursor.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/cursor.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/gemini_cli.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/gemini_cli.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/gemini_cli.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/llm_cost_telemetry.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/llm_provider.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/llm_provider.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/llm_provider.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/llm_retry.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/llm_retry.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/llm_retry.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/native_usage.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/native_usage.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/native_usage.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/ollama_provider.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/path_resolver.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/pricing.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/pricing.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/pricing.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/registry.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/registry.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/registry.cpython-314.pyc +0 -0
- package/core/runtime/__pycache__/squad_orchestrator.cpython-312.pyc +0 -0
- package/core/runtime/base.py +29 -0
- package/core/runtime/capabilities_cli.py +74 -0
- package/core/runtime/claude_code.py +8 -0
- package/core/runtime/codex_cli.py +205 -37
- package/core/runtime/cost_governor.py +184 -0
- package/core/runtime/cursor.py +8 -0
- package/core/runtime/gemini_cli.py +8 -0
- package/core/runtime/llm_provider.py +32 -13
- package/core/runtime/llm_retry.py +233 -0
- package/core/runtime/native_usage.py +186 -0
- package/core/runtime/pricing.py +9 -0
- package/core/runtime/registry.py +3 -0
- package/core/shared/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/shared/__pycache__/safe_session_id.cpython-314.pyc +0 -0
- package/core/shared/__pycache__/test_evidence.cpython-313-pytest-9.1.1.pyc +0 -0
- package/core/shared/__pycache__/test_evidence.cpython-313.pyc +0 -0
- package/core/shared/test_evidence.py +34 -0
- package/core/synapse/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/synapse/__pycache__/agent_experiences_layer.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/cache.cpython-314.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/engine.cpython-314.pyc +0 -0
- package/core/synapse/__pycache__/graph_context_layer.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/kb_cache.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/kb_cache.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/kb_cache.cpython-314.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-312.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/layers.cpython-314.pyc +0 -0
- package/core/synapse/engine.py +7 -0
- package/core/synapse/graph_context_layer.py +212 -0
- package/core/synapse/kb_cache.py +3 -0
- package/core/synapse/layers.py +104 -20
- package/core/workflow/__pycache__/__init__.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/enforcer.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/engine.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-312.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/gate_checkpoint.cpython-312.pyc +0 -0
- package/core/workflow/__pycache__/gate_checkpoint.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/gate_checkpoint.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/loader.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/marker_cache.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/research_gate.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/research_gate.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/rules_registry.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/schema.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/specialist_enforcer.cpython-312.pyc +0 -0
- package/core/workflow/__pycache__/specialist_enforcer.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/state.cpython-314.pyc +0 -0
- package/core/workflow/enforcer.py +5 -16
- package/core/workflow/flow_enforcer.py +36 -11
- package/core/workflow/gate_checkpoint.py +149 -0
- package/core/workflow/research_gate.py +15 -3
- package/core/workflow/rules_registry.py +137 -389
- package/core/workflow/specialist_enforcer.py +21 -4
- package/dashboard/app/pages/knowledge/index.vue +4 -1
- package/departments/ops/skills/n8n-flow/SKILL.md +13 -0
- package/departments/ops/skills/workflow-automate/SKILL.md +16 -0
- package/departments/quality/SKILL.md +45 -5
- package/departments/quality/agents/copy-director.yaml +3 -1
- package/departments/quality/agents/tech-director.yaml +3 -1
- package/installer/adapters/claude-code.js +46 -2
- package/installer/config-seed.js +39 -14
- package/installer/doctor.js +8 -0
- package/installer/graphify.js +153 -0
- package/installer/index.js +20 -0
- package/installer/init.js +11 -0
- package/installer/update.js +19 -0
- package/package.json +1 -1
- package/pyproject.toml +3 -1
- package/scripts/__pycache__/dashboard-api.cpython-313.pyc +0 -0
- package/scripts/__pycache__/knowledge-index.cpython-313.pyc +0 -0
- package/scripts/__pycache__/synapse-bridge.cpython-312.pyc +0 -0
- package/scripts/__pycache__/synapse-bridge.cpython-313.pyc +0 -0
- package/scripts/knowledge-index.py +8 -2
- package/scripts/synapse-bridge.py +102 -26
|
@@ -14,14 +14,61 @@ Exit codes: 0 = success, 1 = degraded (partial layers), 2 = error
|
|
|
14
14
|
import argparse
|
|
15
15
|
import json
|
|
16
16
|
import os
|
|
17
|
+
import re
|
|
17
18
|
import sys
|
|
18
19
|
import time
|
|
19
20
|
from pathlib import Path
|
|
21
|
+
from typing import Any
|
|
20
22
|
|
|
21
23
|
# Resolve ArkaOS root from environment or script location
|
|
22
24
|
ARKAOS_ROOT = Path(os.environ.get("ARKAOS_ROOT", Path(__file__).resolve().parent.parent))
|
|
23
25
|
sys.path.insert(0, str(ARKAOS_ROOT))
|
|
24
26
|
|
|
27
|
+
# Layer tags carrying the actually-injected KB counts (ground truth for
|
|
28
|
+
# reconciling the model's self-reported `[arka:meta] kb=N`). The optional
|
|
29
|
+
# ` degraded=keyword` suffix (RAG honesty, PR-3 v4.1) must still count.
|
|
30
|
+
_KB_CONTEXT_TAG_RE = re.compile(r"\[kb-context:(\d+)[^\]]*\]")
|
|
31
|
+
_KNOWLEDGE_TAG_RE = re.compile(r"\[knowledge:(\d+) chunks?[^\]]*\]")
|
|
32
|
+
_KB_INJECTED_DIR = Path("/tmp/arkaos-kb-injected")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _count_injected_kb(result: Any) -> tuple[int, int]:
|
|
36
|
+
"""Count KB notes (L2.5) and knowledge chunks (L3.5) actually injected."""
|
|
37
|
+
kb_notes = 0
|
|
38
|
+
chunks = 0
|
|
39
|
+
for lr in result.layers:
|
|
40
|
+
tag = lr.tag or ""
|
|
41
|
+
if lr.layer_id == "L2.5":
|
|
42
|
+
match = _KB_CONTEXT_TAG_RE.search(tag)
|
|
43
|
+
kb_notes = int(match.group(1)) if match else 0
|
|
44
|
+
elif lr.layer_id == "L3.5":
|
|
45
|
+
match = _KNOWLEDGE_TAG_RE.search(tag)
|
|
46
|
+
chunks = int(match.group(1)) if match else 0
|
|
47
|
+
return kb_notes, chunks
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def write_kb_injected_state(result: Any, session_id: str) -> None:
|
|
51
|
+
"""Persist injected KB counts so the Stop hook can reconcile kb=N.
|
|
52
|
+
|
|
53
|
+
Skips silently when no real session id is available (a pid-derived
|
|
54
|
+
fallback id would never match the runtime's session id at Stop time).
|
|
55
|
+
"""
|
|
56
|
+
from core.shared.safe_session_id import safe_session_id
|
|
57
|
+
|
|
58
|
+
sid = safe_session_id(session_id)
|
|
59
|
+
if not sid:
|
|
60
|
+
return
|
|
61
|
+
kb_notes, chunks = _count_injected_kb(result)
|
|
62
|
+
prev_umask = os.umask(0o077)
|
|
63
|
+
try:
|
|
64
|
+
_KB_INJECTED_DIR.mkdir(parents=True, exist_ok=True)
|
|
65
|
+
payload = {"kb_injected": kb_notes, "l35_chunks": chunks, "ts": time.time()}
|
|
66
|
+
(_KB_INJECTED_DIR / f"{sid}.json").write_text(
|
|
67
|
+
json.dumps(payload), encoding="utf-8"
|
|
68
|
+
)
|
|
69
|
+
finally:
|
|
70
|
+
os.umask(prev_umask)
|
|
71
|
+
|
|
25
72
|
|
|
26
73
|
def load_constitution(root: Path) -> str:
|
|
27
74
|
"""Load and compress constitution rules."""
|
|
@@ -73,26 +120,21 @@ def load_commands_registry(root: Path) -> list:
|
|
|
73
120
|
return []
|
|
74
121
|
|
|
75
122
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
)
|
|
83
|
-
parser.add_argument("--root", type=str, default=str(ARKAOS_ROOT), help="ArkaOS root directory")
|
|
84
|
-
args = parser.parse_args()
|
|
123
|
+
def run_bridge(
|
|
124
|
+
input_data: dict,
|
|
125
|
+
root: Path,
|
|
126
|
+
layers_only: bool = False,
|
|
127
|
+
raw: str = "",
|
|
128
|
+
) -> tuple[dict, int]:
|
|
129
|
+
"""Run the Synapse engine for a hook payload. Returns (output, exit_code).
|
|
85
130
|
|
|
86
|
-
|
|
131
|
+
Extracted from ``main()`` (PR-6 hook consolidation) so
|
|
132
|
+
``core.hooks.user_prompt_submit`` can call the bridge in-process
|
|
133
|
+
instead of spawning a second python3. Exit codes match the script:
|
|
134
|
+
0 = success, 1 = degraded (import error), 2 = error.
|
|
135
|
+
"""
|
|
87
136
|
start = time.time()
|
|
88
137
|
|
|
89
|
-
# Read input from stdin
|
|
90
|
-
try:
|
|
91
|
-
raw = sys.stdin.read().strip()
|
|
92
|
-
input_data = json.loads(raw) if raw else {}
|
|
93
|
-
except (json.JSONDecodeError, Exception):
|
|
94
|
-
input_data = {}
|
|
95
|
-
|
|
96
138
|
# Extract context fields
|
|
97
139
|
user_input = input_data.get("user_input", "")
|
|
98
140
|
if not user_input:
|
|
@@ -141,12 +183,15 @@ def main() -> int:
|
|
|
141
183
|
except Exception:
|
|
142
184
|
branch = ""
|
|
143
185
|
|
|
144
|
-
|
|
186
|
+
# Real runtime session id (used for kb=N reconciliation); the
|
|
187
|
+
# pid-derived fallback below is only for cache scoping and is
|
|
188
|
+
# deliberately excluded from reconciliation state.
|
|
189
|
+
runtime_session_id = (
|
|
145
190
|
input_data.get("session_id")
|
|
146
191
|
or os.environ.get("ARKAOS_SESSION_ID", "")
|
|
147
192
|
or os.environ.get("CLAUDE_SESSION_ID", "")
|
|
148
|
-
or f"bridge-{os.getpid()}"
|
|
149
193
|
)
|
|
194
|
+
session_id = runtime_session_id or f"bridge-{os.getpid()}"
|
|
150
195
|
|
|
151
196
|
ctx = PromptContext(
|
|
152
197
|
user_input=user_input,
|
|
@@ -162,6 +207,15 @@ def main() -> int:
|
|
|
162
207
|
result = engine.inject(ctx)
|
|
163
208
|
total_ms = int((time.time() - start) * 1000)
|
|
164
209
|
|
|
210
|
+
# Structural honesty: record how many KB notes L2.5 actually
|
|
211
|
+
# injected. Never raise — reconciliation is telemetry-only and
|
|
212
|
+
# must not degrade context injection itself.
|
|
213
|
+
try:
|
|
214
|
+
if runtime_session_id:
|
|
215
|
+
write_kb_injected_state(result, runtime_session_id)
|
|
216
|
+
except Exception:
|
|
217
|
+
pass
|
|
218
|
+
|
|
165
219
|
# Record token usage in budget tracker
|
|
166
220
|
try:
|
|
167
221
|
from core.budget.manager import BudgetManager
|
|
@@ -183,7 +237,7 @@ def main() -> int:
|
|
|
183
237
|
except Exception:
|
|
184
238
|
pass # Never block on budget tracking
|
|
185
239
|
|
|
186
|
-
if
|
|
240
|
+
if layers_only:
|
|
187
241
|
output = {
|
|
188
242
|
"context_string": result.context_string,
|
|
189
243
|
"layers": [
|
|
@@ -204,19 +258,41 @@ def main() -> int:
|
|
|
204
258
|
else:
|
|
205
259
|
output = {"context_string": result.context_string, "total_ms": total_ms}
|
|
206
260
|
|
|
207
|
-
|
|
208
|
-
return 0
|
|
261
|
+
return output, 0
|
|
209
262
|
|
|
210
263
|
except ImportError as e:
|
|
211
264
|
# Python dependencies not available — output minimal context
|
|
212
265
|
sys.stderr.write(f"synapse-bridge: import error: {e}\n")
|
|
213
|
-
|
|
214
|
-
return 1
|
|
266
|
+
return {"context_string": "", "error": str(e)}, 1
|
|
215
267
|
|
|
216
268
|
except Exception as e:
|
|
217
269
|
sys.stderr.write(f"synapse-bridge: error: {e}\n")
|
|
218
|
-
|
|
219
|
-
|
|
270
|
+
return {"context_string": "", "error": str(e)}, 2
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def main() -> int:
|
|
274
|
+
parser = argparse.ArgumentParser(description="Synapse Bridge — context injection for hooks")
|
|
275
|
+
parser.add_argument(
|
|
276
|
+
"--layers-only",
|
|
277
|
+
action="store_true",
|
|
278
|
+
help="Output layer breakdown instead of context string",
|
|
279
|
+
)
|
|
280
|
+
parser.add_argument("--root", type=str, default=str(ARKAOS_ROOT), help="ArkaOS root directory")
|
|
281
|
+
args = parser.parse_args()
|
|
282
|
+
|
|
283
|
+
# Read input from stdin
|
|
284
|
+
try:
|
|
285
|
+
raw = sys.stdin.read().strip()
|
|
286
|
+
input_data = json.loads(raw) if raw else {}
|
|
287
|
+
except (json.JSONDecodeError, Exception):
|
|
288
|
+
input_data = {}
|
|
289
|
+
raw = ""
|
|
290
|
+
|
|
291
|
+
output, code = run_bridge(
|
|
292
|
+
input_data, Path(args.root), layers_only=args.layers_only, raw=raw
|
|
293
|
+
)
|
|
294
|
+
print(json.dumps(output))
|
|
295
|
+
return code
|
|
220
296
|
|
|
221
297
|
|
|
222
298
|
if __name__ == "__main__":
|