346 lines
18 KiB
Python
346 lines
18 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Build a small, current HoloLake architecture prompt from online facts."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import argparse
|
||
|
|
import fcntl
|
||
|
|
import hashlib
|
||
|
|
import json
|
||
|
|
import pathlib
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
|
||
|
|
REPO_012_URL = "https://guanghulab.com/code/bingshuo/guanghu-ice-heart.git"
|
||
|
|
REPO_014_URL = "https://guanghulab.com/code/bingshuo/hololake-system-architecture.git"
|
||
|
|
REPO_012_MIRROR = pathlib.Path("/Volumes/JZAO/HoloLake/source-mirrors/guanghu-ice-heart.git")
|
||
|
|
REPO_014_MIRROR = pathlib.Path("/Volumes/JZAO/HoloLake/source-mirrors/hololake-system-architecture.git")
|
||
|
|
LANE_ROOT = pathlib.Path("/Volumes/JZAO/HoloLake/persona-runtime/continuity-memory/collaboration/lanes")
|
||
|
|
LIGHTHOUSE_RESOLVER = pathlib.Path(
|
||
|
|
"/Volumes/JZAO/HoloLake/persona-runtime/shared/skills/guanghu-lighthouse-navigator/"
|
||
|
|
"scripts/resolve_lighthouse_route.py"
|
||
|
|
)
|
||
|
|
LOCK_PATH = pathlib.Path("/tmp/hololake-current-architecture-prompter.lock")
|
||
|
|
ARCHITECTURE_POINTER = "routing/hololake-current-architecture.json"
|
||
|
|
TCS_STAGE_GATE = "routing/tcs-work-ownership-stage-gate-map.json"
|
||
|
|
FIFTH_DOMAIN_WORLD_TREE = "routing/fifth-domain-world-tree.json"
|
||
|
|
HEARTBEAT_LANGUAGE_PROFILE = "routing/heartbeat-core-language-channel-profile.json"
|
||
|
|
ZERO_CORE_REALITY_PROFILE = "routing/bingshuo-zero-core-reality-channel-profile.json"
|
||
|
|
PERSONA_LEARNING_CURRENT = pathlib.Path(
|
||
|
|
"/Volumes/JZAO/HoloLake/persona-runtime/shared/brains/"
|
||
|
|
"GHS-016-PERSONA-LEARNING-CURRICULUM-BRAIN/current/current.json"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class PromptError(RuntimeError):
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
def run(*args: str) -> str:
|
||
|
|
result = subprocess.run(args, check=False, capture_output=True, text=True)
|
||
|
|
if result.returncode != 0:
|
||
|
|
detail = (result.stderr or result.stdout).strip().splitlines()
|
||
|
|
raise PromptError(detail[-1] if detail else f"command_failed:{args[0]}")
|
||
|
|
return result.stdout.strip()
|
||
|
|
|
||
|
|
|
||
|
|
def remote_sha(url: str) -> str:
|
||
|
|
output = run("git", "ls-remote", url, "refs/heads/main")
|
||
|
|
fields = output.split()
|
||
|
|
if len(fields) != 2 or len(fields[0]) != 40 or fields[1] != "refs/heads/main":
|
||
|
|
raise PromptError("remote_main_unreadable")
|
||
|
|
return fields[0]
|
||
|
|
|
||
|
|
|
||
|
|
def refresh_mirror(mirror: pathlib.Path, url: str, expected_sha: str, refresh: bool) -> None:
|
||
|
|
if not mirror.is_dir() or run("git", "-C", str(mirror), "rev-parse", "--is-bare-repository") != "true":
|
||
|
|
raise PromptError(f"shared_mirror_unavailable:{mirror}")
|
||
|
|
if refresh:
|
||
|
|
run(
|
||
|
|
"git", "-C", str(mirror), "fetch", "--quiet", "--no-tags", url,
|
||
|
|
"+refs/heads/main:refs/remotes/origin/main",
|
||
|
|
)
|
||
|
|
actual = run("git", "-C", str(mirror), "rev-parse", "refs/remotes/origin/main^{commit}")
|
||
|
|
if actual != expected_sha:
|
||
|
|
raise PromptError(f"shared_mirror_stale:{mirror.name}:{actual}:{expected_sha}")
|
||
|
|
|
||
|
|
|
||
|
|
def git_json(mirror: pathlib.Path, commit: str, path: str) -> dict[str, Any]:
|
||
|
|
try:
|
||
|
|
value = json.loads(run("git", "-C", str(mirror), "show", f"{commit}:{path}"))
|
||
|
|
except (json.JSONDecodeError, PromptError) as error:
|
||
|
|
raise PromptError(f"invalid_json_at:{path}") from error
|
||
|
|
if not isinstance(value, dict):
|
||
|
|
raise PromptError(f"json_object_required:{path}")
|
||
|
|
return value
|
||
|
|
|
||
|
|
|
||
|
|
def lighthouse_receipt() -> dict[str, Any]:
|
||
|
|
value = json.loads(run(
|
||
|
|
"python3", str(LIGHTHOUSE_RESOLVER), "--host", "codex",
|
||
|
|
"--intent", "HoloLake系统架构规划",
|
||
|
|
))
|
||
|
|
if value.get("decision") != "ALLOW_NAVIGATION" or value.get("target", {}).get("id") != "HLP-CURRENT-ARCH-001":
|
||
|
|
raise PromptError("lighthouse_route_not_current")
|
||
|
|
return value
|
||
|
|
|
||
|
|
|
||
|
|
def lane_projection(development_id: str | None) -> dict[str, Any] | None:
|
||
|
|
if not development_id:
|
||
|
|
return None
|
||
|
|
if not development_id.replace("-", "").isalnum() or development_id.upper() != development_id:
|
||
|
|
raise PromptError("development_id_invalid")
|
||
|
|
path = LANE_ROOT / f"{development_id}.json"
|
||
|
|
if not path.is_file():
|
||
|
|
raise PromptError(f"development_lane_missing:{development_id}")
|
||
|
|
lane = json.loads(path.read_text(encoding="utf-8"))
|
||
|
|
amendments = lane.get("task_lock", {}).get("amendments", [])
|
||
|
|
return {
|
||
|
|
"development_id": development_id,
|
||
|
|
"status": lane.get("status"),
|
||
|
|
"progress_summary": lane.get("progress_summary"),
|
||
|
|
"recent_language_events": amendments[-5:] if isinstance(amendments, list) else [],
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def persona_learning_projection() -> dict[str, Any]:
|
||
|
|
try:
|
||
|
|
current = json.loads(PERSONA_LEARNING_CURRENT.read_text(encoding="utf-8"))
|
||
|
|
cortex_path = (PERSONA_LEARNING_CURRENT.parents[1] / current["cortex_path"]).resolve()
|
||
|
|
cortex_hash = hashlib.sha256(cortex_path.read_bytes()).hexdigest()
|
||
|
|
if (
|
||
|
|
current.get("schema") != "guanghu.persona-learning-brain-current/v1"
|
||
|
|
or cortex_hash != current.get("cortex_sha256")
|
||
|
|
):
|
||
|
|
raise ValueError("cortex_pointer_or_hash_invalid")
|
||
|
|
codex_skill = pathlib.Path("/Users/bingshuolingdianyuanhe/.codex/skills/guanghu-persona-learning-brain/SKILL.md")
|
||
|
|
if not codex_skill.is_file():
|
||
|
|
raise ValueError("codex_thin_skill_missing")
|
||
|
|
return {
|
||
|
|
"state": "CURRENT_CORTEX_VERIFIED",
|
||
|
|
"brain_id": current["brain_id"],
|
||
|
|
"revision": current["revision"],
|
||
|
|
"cortex_sha256": cortex_hash,
|
||
|
|
"codex_skill": str(codex_skill),
|
||
|
|
"autoload_rule": "LOAD_RELEVANT_SUBJECT_FACULTY_WITHOUT_EXPERIENCE_BODIES",
|
||
|
|
}
|
||
|
|
except (OSError, KeyError, ValueError, json.JSONDecodeError) as error:
|
||
|
|
return {"state": "LEARNING_BRAIN_UNAVAILABLE", "reason": str(error)}
|
||
|
|
|
||
|
|
|
||
|
|
def build(development_id: str | None, refresh: bool) -> dict[str, Any]:
|
||
|
|
route = lighthouse_receipt()
|
||
|
|
sha_012 = remote_sha(REPO_012_URL)
|
||
|
|
sha_014 = remote_sha(REPO_014_URL)
|
||
|
|
LOCK_PATH.touch(mode=0o600, exist_ok=True)
|
||
|
|
with LOCK_PATH.open("r+", encoding="utf-8") as lock:
|
||
|
|
fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
|
||
|
|
refresh_mirror(REPO_012_MIRROR, REPO_012_URL, sha_012, refresh)
|
||
|
|
refresh_mirror(REPO_014_MIRROR, REPO_014_URL, sha_014, refresh)
|
||
|
|
architecture = git_json(REPO_014_MIRROR, sha_014, ARCHITECTURE_POINTER)
|
||
|
|
anchor = git_json(REPO_012_MIRROR, sha_012, "routing/public-navigation-anchor.json")
|
||
|
|
tcs_stage_gate = git_json(REPO_012_MIRROR, sha_012, TCS_STAGE_GATE)
|
||
|
|
fifth_domain_world_tree = git_json(REPO_012_MIRROR, sha_012, FIFTH_DOMAIN_WORLD_TREE)
|
||
|
|
heartbeat_language_profile = git_json(REPO_012_MIRROR, sha_012, HEARTBEAT_LANGUAGE_PROFILE)
|
||
|
|
zero_core_reality_profile = git_json(REPO_012_MIRROR, sha_012, ZERO_CORE_REALITY_PROFILE)
|
||
|
|
if architecture.get("state") != "CURRENT_CANONICAL" or architecture.get("architecture_id") != "HLP-CURRENT-ARCH-001":
|
||
|
|
raise PromptError("current_architecture_pointer_invalid")
|
||
|
|
read_order = architecture.get("read_order")
|
||
|
|
if not isinstance(read_order, list) or not read_order or not all(isinstance(item, str) for item in read_order):
|
||
|
|
raise PromptError("current_architecture_read_order_invalid")
|
||
|
|
public_stage = architecture.get("first_public_product_stage")
|
||
|
|
if (
|
||
|
|
not isinstance(public_stage, dict)
|
||
|
|
or public_stage.get("record_id") != "HLP-PUBLIC-OS-STAGE1-20260830-001"
|
||
|
|
or public_stage.get("public_channel_id") != "CH-ZERO-CORE-LPM"
|
||
|
|
or public_stage.get("is_personal_channel") is not False
|
||
|
|
or public_stage.get("initial_channel_surface")
|
||
|
|
!= "INFINITE_BLANK_CANVAS_WITH_SIGNED_DECLARATIVE_MODULES"
|
||
|
|
or public_stage.get("realtime_transport")
|
||
|
|
!= "NOT_IMPLEMENTED_GIT_IS_NOT_REALTIME_BROADCAST"
|
||
|
|
):
|
||
|
|
raise PromptError("public_os_stage_one_projection_invalid")
|
||
|
|
stage_state = tcs_stage_gate.get("stage_gate")
|
||
|
|
if (
|
||
|
|
tcs_stage_gate.get("map_id") != "TCS-WORK-OWNERSHIP-MAP-001"
|
||
|
|
or not isinstance(stage_state, dict)
|
||
|
|
or stage_state.get("language_architecture") != "CLOSED_AND_ARCHIVED"
|
||
|
|
or stage_state.get("reality_engineering_execution") != "CURRENT"
|
||
|
|
):
|
||
|
|
raise PromptError("tcs_work_ownership_stage_gate_invalid")
|
||
|
|
language_route = fifth_domain_world_tree.get("login_routes", {}).get("human", {})
|
||
|
|
reality_route = fifth_domain_world_tree.get("login_routes", {}).get("reality_execution", {})
|
||
|
|
if (
|
||
|
|
heartbeat_language_profile.get("channel_id") != "ICE-CH-HB001"
|
||
|
|
or heartbeat_language_profile.get("reality_boundary", {}).get("reality_execution") is not False
|
||
|
|
or zero_core_reality_profile.get("channel_id") != "ICE-CH-ZC001"
|
||
|
|
or zero_core_reality_profile.get("public_zero_core_boundary", {}).get("personal_channel_is_alias_of_public_channel") is not False
|
||
|
|
or language_route.get("path", [])[-1:] != ["HEARTBEAT_CORE_CHANNEL"]
|
||
|
|
or reality_route.get("path", [])[-1:] != ["ICE-CH-ZC001"]
|
||
|
|
or stage_state.get("personal_heartbeat_language_runtime") != "ICE-CH-HB001_CURRENT_HUMAN_LANGUAGE_CONTROLLED"
|
||
|
|
or stage_state.get("personal_zero_core_reality_runtime") != "ICE-CH-ZC001_CURRENT_HUMAN_LANGUAGE_CONTROLLED"
|
||
|
|
):
|
||
|
|
raise PromptError("fifth_domain_numbered_channel_route_invalid")
|
||
|
|
fifth_domain_channel_routes = {
|
||
|
|
"language_reasoning": {
|
||
|
|
"channel_id": "ICE-CH-HB001",
|
||
|
|
"system_id": "SYS-GLW-ELH-0001",
|
||
|
|
"world_path": heartbeat_language_profile.get("world_path"),
|
||
|
|
"profile": HEARTBEAT_LANGUAGE_PROFILE,
|
||
|
|
"reality_execution": False,
|
||
|
|
},
|
||
|
|
"reality_development_execution": {
|
||
|
|
"channel_id": "ICE-CH-ZC001",
|
||
|
|
"system_id": "SYS-GLW-LNG-0001",
|
||
|
|
"world_path": zero_core_reality_profile.get("world_path"),
|
||
|
|
"profile": ZERO_CORE_REALITY_PROFILE,
|
||
|
|
"public_zero_core_alias": False,
|
||
|
|
},
|
||
|
|
"public_language_persona_system_body": {
|
||
|
|
"channel_id": "CH-ZERO-CORE-LPM",
|
||
|
|
"system_id": zero_core_reality_profile.get("public_zero_core_boundary", {}).get("world_system_anchor"),
|
||
|
|
"governance_controller": zero_core_reality_profile.get("public_zero_core_boundary", {}).get("public_governance_controller"),
|
||
|
|
"fifth_domain_personal_channel": False,
|
||
|
|
},
|
||
|
|
"switch_authority": heartbeat_language_profile.get("switch_control", {}).get("authority"),
|
||
|
|
"current_channel": stage_state.get("current_fifth_domain_channel"),
|
||
|
|
}
|
||
|
|
return {
|
||
|
|
"schema": "hololake.current-architecture-prompter/v1",
|
||
|
|
"state": "CURRENT_FACTS_RESOLVED",
|
||
|
|
"official_online": {
|
||
|
|
"lighthouse_id": route.get("lighthouse_id"),
|
||
|
|
"target_id": route.get("target", {}).get("id"),
|
||
|
|
"repo_012_main": sha_012,
|
||
|
|
"repo_012_anchor_state": anchor.get("state"),
|
||
|
|
"repo_014_main": sha_014,
|
||
|
|
"architecture_id": architecture.get("architecture_id"),
|
||
|
|
"architecture_version": architecture.get("version"),
|
||
|
|
"architecture_state": architecture.get("state"),
|
||
|
|
"tcs_work_ownership_map_id": tcs_stage_gate.get("map_id"),
|
||
|
|
"tcs_work_ownership_stage_state": stage_state,
|
||
|
|
"product": architecture.get("product"),
|
||
|
|
"domain_source": architecture.get("domain_source"),
|
||
|
|
"world_genesis": architecture.get("world_genesis"),
|
||
|
|
"persona_consciousness": architecture.get("persona_consciousness"),
|
||
|
|
"personal_node_work_lake": architecture.get("personal_node_work_lake"),
|
||
|
|
"fifth_domain_channel_routes": fifth_domain_channel_routes,
|
||
|
|
"topologies": architecture.get("topologies"),
|
||
|
|
"parallel_planes": architecture.get("parallel_planes"),
|
||
|
|
"access_modes": architecture.get("access_modes"),
|
||
|
|
"communication": architecture.get("communication"),
|
||
|
|
"interaction_model": architecture.get("interaction_model"),
|
||
|
|
"first_public_product_stage": public_stage,
|
||
|
|
"current_product_assessment": architecture.get("current_product_assessment"),
|
||
|
|
"truth_boundary": architecture.get("truth_boundary"),
|
||
|
|
"read_order": read_order,
|
||
|
|
},
|
||
|
|
"active_lane": lane_projection(development_id),
|
||
|
|
"local_persona_learning_projection": persona_learning_projection(),
|
||
|
|
"rules": [
|
||
|
|
"latest_user_message_precedes_automation_prompt",
|
||
|
|
"pending_language_event_is_not_official_until_registered_and_published",
|
||
|
|
"human_uses_language_and_reality_boundary_confirmation",
|
||
|
|
"system_and_authorized_persona_hide_technical_complexity",
|
||
|
|
"one_verifiable_minimum_stage_per_turn",
|
||
|
|
"architecture_code_artifact_publish_connect_deploy_health_are_separate_facts",
|
||
|
|
"archived_product_language_work_does_not_override_current_bingshuo_channel_switch",
|
||
|
|
"live_language_and_reality_channel_switch_comes_only_from_ice_gl_infinity_direct_language",
|
||
|
|
"resolve_ice_ch_hb001_ice_ch_zc001_and_public_ch_zero_core_lpm_as_three_distinct_objects",
|
||
|
|
"historical_zero_core_wording_must_not_select_a_current_channel",
|
||
|
|
"persona_source_cognition_precedes_model_language_and_execution",
|
||
|
|
"generic_tool_identity_is_not_persona_restore_fallback",
|
||
|
|
"long_term_relationship_claims_require_support_gap_and_counterevidence_audit",
|
||
|
|
"public_stage_blank_canvas_modules_execution_git_realtime_release_and_deploy_are_separate_facts",
|
||
|
|
],
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def markdown(payload: dict[str, Any]) -> str:
|
||
|
|
official = payload["official_online"]
|
||
|
|
lane = payload.get("active_lane") or {}
|
||
|
|
learning = payload.get("local_persona_learning_projection") or {}
|
||
|
|
lines = [
|
||
|
|
"# HoloLake 当前官方提词包",
|
||
|
|
"",
|
||
|
|
f"- REPO-012 main: `{official['repo_012_main']}`",
|
||
|
|
f"- REPO-014 main: `{official['repo_014_main']}`",
|
||
|
|
f"- 当前架构: `{official['architecture_id']}@{official['architecture_version']}` / `{official['architecture_state']}`",
|
||
|
|
f"- TCS 权利与阶段门: `{official['tcs_work_ownership_map_id']}`",
|
||
|
|
f"- 语言架构: `{official['tcs_work_ownership_stage_state']['language_architecture']}`",
|
||
|
|
f"- 活语言层开关: `{official['tcs_work_ownership_stage_state'].get('live_language_architecture_layer_switch', 'ONLINE_SCHEMA_PENDING_ICE-GL∞_DIRECT_LANGUAGE_ONLY')}`",
|
||
|
|
f"- 第五域当前频道: `{official['tcs_work_ownership_stage_state'].get('current_fifth_domain_channel', 'ONLINE_SCHEMA_PENDING')}`",
|
||
|
|
f"- 第五域个人语言推理: `{official['fifth_domain_channel_routes']['language_reasoning']['channel_id']}` → `{official['fifth_domain_channel_routes']['language_reasoning']['world_path']}`",
|
||
|
|
f"- 第五域个人现实开发: `{official['fifth_domain_channel_routes']['reality_development_execution']['channel_id']}` → `{official['fifth_domain_channel_routes']['reality_development_execution']['world_path']}`",
|
||
|
|
f"- 公众语言人格系统本体: `{official['fifth_domain_channel_routes']['public_language_persona_system_body']['channel_id']}` / `{official['fifth_domain_channel_routes']['public_language_persona_system_body']['governance_controller']}` 治理(不是第五域个人频道)",
|
||
|
|
f"- 公众 Stage 1: `{official['first_public_product_stage']['runtime_state']}` / `{official['first_public_product_stage']['local_application_version']}` / `{official['first_public_product_stage']['public_release']}`",
|
||
|
|
f"- 初始化频道: `{official['first_public_product_stage']['initial_channel_surface']}`;预装模块 `{', '.join(official['first_public_product_stage']['preinstalled_modules'])}`",
|
||
|
|
f"- 执行与通信边界: `{official['first_public_product_stage']['deterministic_execution_layer']}`;实时层 `{official['first_public_product_stage']['realtime_transport']}`",
|
||
|
|
f"- 当前阶段: `REALITY_ENGINEERING_EXECUTION` / `{official['tcs_work_ownership_stage_state']['reality_engineering_execution']}`",
|
||
|
|
f"- 当前车道: `{lane.get('development_id', 'NONE')}` / `{lane.get('status', 'NOT_APPLICABLE')}`",
|
||
|
|
f"- 人格学习脑: `{learning.get('brain_id', 'UNAVAILABLE')}@{learning.get('revision', 'UNKNOWN')}` / `{learning.get('state', 'LEARNING_BRAIN_UNAVAILABLE')}`",
|
||
|
|
f"- 学科自动加载: `{learning.get('autoload_rule', 'RESTORE_OR_REPORT_UNAVAILABLE')}` → `{learning.get('codex_skill', 'NONE')}`",
|
||
|
|
"",
|
||
|
|
"## 当前官方结构",
|
||
|
|
"",
|
||
|
|
"```json",
|
||
|
|
json.dumps({
|
||
|
|
"product": official.get("product"),
|
||
|
|
"domain_source": official.get("domain_source"),
|
||
|
|
"persona_consciousness": official.get("persona_consciousness"),
|
||
|
|
"personal_node_work_lake": official.get("personal_node_work_lake"),
|
||
|
|
"fifth_domain_channel_routes": official.get("fifth_domain_channel_routes"),
|
||
|
|
"topologies": official.get("topologies"),
|
||
|
|
"parallel_planes": official.get("parallel_planes"),
|
||
|
|
"access_modes": official.get("access_modes"),
|
||
|
|
"communication": official.get("communication"),
|
||
|
|
"interaction_model": official.get("interaction_model"),
|
||
|
|
"first_public_product_stage": official.get("first_public_product_stage"),
|
||
|
|
"current_product_assessment": official.get("current_product_assessment"),
|
||
|
|
}, ensure_ascii=False, indent=2),
|
||
|
|
"```",
|
||
|
|
"",
|
||
|
|
"## 当前阅读顺序",
|
||
|
|
"",
|
||
|
|
*[f"{index}. `{item}`" for index, item in enumerate(official["read_order"], start=1)],
|
||
|
|
"",
|
||
|
|
"## 最近人类语言事件",
|
||
|
|
"",
|
||
|
|
]
|
||
|
|
events = lane.get("recent_language_events") or []
|
||
|
|
if events:
|
||
|
|
for event in events:
|
||
|
|
lines.append(f"- `{event.get('kind', 'unknown')}` · {event.get('summary', '')}")
|
||
|
|
else:
|
||
|
|
lines.append("- 无")
|
||
|
|
lines.append("- 对照当前线上结构逐项判断;线上已覆盖的作为来源历史,未覆盖的先登记再实现。")
|
||
|
|
lines.extend(["", "## 本轮守门", "", *[f"- `{rule}`" for rule in payload["rules"]]])
|
||
|
|
return "\n".join(lines)
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> int:
|
||
|
|
parser = argparse.ArgumentParser()
|
||
|
|
parser.add_argument("--development-id")
|
||
|
|
parser.add_argument("--format", choices=("json", "markdown"), default="markdown")
|
||
|
|
parser.add_argument("--no-refresh", action="store_true")
|
||
|
|
args = parser.parse_args()
|
||
|
|
try:
|
||
|
|
payload = build(args.development_id, not args.no_refresh)
|
||
|
|
except (OSError, ValueError, PromptError) as error:
|
||
|
|
print(json.dumps({
|
||
|
|
"schema": "hololake.current-architecture-prompter/v1",
|
||
|
|
"state": "FAIL_CLOSED",
|
||
|
|
"error": str(error),
|
||
|
|
}, ensure_ascii=False))
|
||
|
|
return 1
|
||
|
|
if args.format == "json":
|
||
|
|
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
||
|
|
else:
|
||
|
|
print(markdown(payload))
|
||
|
|
return 0
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
sys.exit(main())
|