create-workframe 0.1.7 → 0.1.9

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 (93) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/scripts/apply-update-workframe.sh +68 -28
  4. package/scripts/compose-docker-host.sh +8 -2
  5. package/workframe-api/.dockerignore +4 -0
  6. package/workframe-api/package.json +1 -1
  7. package/workframe-api/server.py +306 -70
  8. package/workframe-api/stack_config.py +7 -7
  9. package/workframe-api/test_stack_config_install_smtp.py +5 -0
  10. package/workframe-api/updates.py +146 -33
  11. package/workframe-supervisor/Dockerfile +1 -1
  12. package/workframe-supervisor/server.py +16 -3
  13. package/workframe-ui/public/assets/{arc-Cn-lt9fT.js → arc-DjpS9a2b.js} +1 -1
  14. package/workframe-ui/public/assets/architecture-7EHR7CIX-CvhbXEvt.js +1 -0
  15. package/workframe-ui/public/assets/{architectureDiagram-3BPJPVTR-qXoGCqfH.js → architectureDiagram-3BPJPVTR-puCKmKHV.js} +1 -1
  16. package/workframe-ui/public/assets/{blockDiagram-GPEHLZMM-DoopFlWj.js → blockDiagram-GPEHLZMM-C2P0g-eH.js} +1 -1
  17. package/workframe-ui/public/assets/{c4Diagram-AAUBKEIU-BRa7hfzE.js → c4Diagram-AAUBKEIU-DdvYEITH.js} +1 -1
  18. package/workframe-ui/public/assets/channel-D63s_yN9.js +1 -0
  19. package/workframe-ui/public/assets/{chunk-2J33WTMH-Cl33E2hh.js → chunk-2J33WTMH-Cxe8QsEF.js} +1 -1
  20. package/workframe-ui/public/assets/{chunk-3OPIFGDE-BRywYZQO.js → chunk-3OPIFGDE-DPNyTwR3.js} +1 -1
  21. package/workframe-ui/public/assets/{chunk-4BX2VUAB-CI3xzp-0.js → chunk-4BX2VUAB-XKG9gfRN.js} +1 -1
  22. package/workframe-ui/public/assets/{chunk-55IACEB6-Bkf3Ye3F.js → chunk-55IACEB6-oPMTulgb.js} +1 -1
  23. package/workframe-ui/public/assets/{chunk-5ZQYHXKU-C5RN3hUT.js → chunk-5ZQYHXKU-BWwXvpa_.js} +1 -1
  24. package/workframe-ui/public/assets/{chunk-727SXJPM-BaY0yDwt.js → chunk-727SXJPM-Cml2twO_.js} +1 -1
  25. package/workframe-ui/public/assets/{chunk-AQP2D5EJ-VMMBaDqd.js → chunk-AQP2D5EJ-DzrRBhQu.js} +1 -1
  26. package/workframe-ui/public/assets/{chunk-BSJP7CBP-DlNZ1UV3.js → chunk-BSJP7CBP-EZ7STU6h.js} +1 -1
  27. package/workframe-ui/public/assets/{chunk-CSCIHK7Q-tT2HyVy0.js → chunk-CSCIHK7Q-BGTQzWYw.js} +1 -1
  28. package/workframe-ui/public/assets/{chunk-FMBD7UC4-CyACRaUT.js → chunk-FMBD7UC4-Cm4stfRa.js} +1 -1
  29. package/workframe-ui/public/assets/{chunk-KSCS5N6A-seK5WAZs.js → chunk-KSCS5N6A-exbMijjy.js} +1 -1
  30. package/workframe-ui/public/assets/{chunk-L5ZTLDWV-r5cyG5AH.js → chunk-L5ZTLDWV-C75kbQwN.js} +1 -1
  31. package/workframe-ui/public/assets/{chunk-LZXEDZCA-SnbeVxsJ.js → chunk-LZXEDZCA-CsRdBqUB.js} +2 -2
  32. package/workframe-ui/public/assets/{chunk-ND2GUHAM-zbFgEXSJ.js → chunk-ND2GUHAM-D84zyIu2.js} +1 -1
  33. package/workframe-ui/public/assets/{chunk-NZK2D7GU-UhZc8kOk.js → chunk-NZK2D7GU-CUNNo1bj.js} +1 -1
  34. package/workframe-ui/public/assets/{chunk-O5CBEL6O-DHvu2iZ-.js → chunk-O5CBEL6O-DN6WEIh-.js} +1 -1
  35. package/workframe-ui/public/assets/chunk-QZHKN3VN-Dj_Yxhgo.js +1 -0
  36. package/workframe-ui/public/assets/chunk-WU5MYG2G-AFchshb6.js +1 -0
  37. package/workframe-ui/public/assets/{chunk-XPW4576I-CCPNKbzG.js → chunk-XPW4576I-Ct5VQv2D.js} +1 -1
  38. package/workframe-ui/public/assets/classDiagram-4FO5ZUOK-Opj8t01I.js +1 -0
  39. package/workframe-ui/public/assets/classDiagram-v2-Q7XG4LA2-Opj8t01I.js +1 -0
  40. package/workframe-ui/public/assets/{cose-bilkent-S5V4N54A-D1CLe6Y0.js → cose-bilkent-S5V4N54A-Bj4W5oMk.js} +1 -1
  41. package/workframe-ui/public/assets/{dagre-BM42HDAG-DYHcGVs_.js → dagre-BM42HDAG-DAjHBkAy.js} +1 -1
  42. package/workframe-ui/public/assets/{diagram-2AECGRRQ-DVUkJ-II.js → diagram-2AECGRRQ-Ch2gGFPG.js} +1 -1
  43. package/workframe-ui/public/assets/{diagram-5GNKFQAL-C9Y1Acc2.js → diagram-5GNKFQAL-BzIIvgYH.js} +1 -1
  44. package/workframe-ui/public/assets/{diagram-KO2AKTUF-Db3zez-n.js → diagram-KO2AKTUF-Df0Q8nv6.js} +1 -1
  45. package/workframe-ui/public/assets/{diagram-LMA3HP47-BaOR5sIr.js → diagram-LMA3HP47-D-G3ekmF.js} +1 -1
  46. package/workframe-ui/public/assets/{diagram-OG6HWLK6-fLBzMY5W.js → diagram-OG6HWLK6-TBHhT9f5.js} +1 -1
  47. package/workframe-ui/public/assets/{dist-uZYeD3o1.js → dist-CPbiDkEZ.js} +1 -1
  48. package/workframe-ui/public/assets/{erDiagram-TEJ5UH35-BoCxDSyE.js → erDiagram-TEJ5UH35-YxkUmLLV.js} +1 -1
  49. package/workframe-ui/public/assets/eventmodeling-FCH6USID-LQOYL50n.js +1 -0
  50. package/workframe-ui/public/assets/{flowDiagram-I6XJVG4X-BnYa3CAj.js → flowDiagram-I6XJVG4X-kfZ7-RSd.js} +1 -1
  51. package/workframe-ui/public/assets/{ganttDiagram-6RSMTGT7-Dm_e_Kaa.js → ganttDiagram-6RSMTGT7-DmTx3hzR.js} +1 -1
  52. package/workframe-ui/public/assets/{gitGraph-WXDBUCRP-CBAj8ntv.js → gitGraph-WXDBUCRP-BXa0ewp3.js} +1 -1
  53. package/workframe-ui/public/assets/{gitGraphDiagram-PVQCEYII-D5auJjJh.js → gitGraphDiagram-PVQCEYII-CQr2qMxU.js} +1 -1
  54. package/workframe-ui/public/assets/{index-auJ0bLMU.css → index-B08aShJy.css} +1 -1
  55. package/workframe-ui/public/assets/index-DCF3W3G_.js +129 -0
  56. package/workframe-ui/public/assets/{info-J43DQDTF-BNMADxE2.js → info-J43DQDTF-t-Qlx8zv.js} +1 -1
  57. package/workframe-ui/public/assets/{infoDiagram-5YYISTIA-C8c45T4J.js → infoDiagram-5YYISTIA-CzkYofPx.js} +1 -1
  58. package/workframe-ui/public/assets/{ishikawaDiagram-YF4QCWOH-CyWuHB4e.js → ishikawaDiagram-YF4QCWOH-djK3Oxgb.js} +1 -1
  59. package/workframe-ui/public/assets/{journeyDiagram-JHISSGLW-B43pCuDT.js → journeyDiagram-JHISSGLW-CWxYXxdF.js} +1 -1
  60. package/workframe-ui/public/assets/{kanban-definition-UN3LZRKU-Dyn480BI.js → kanban-definition-UN3LZRKU-D7leCAD9.js} +1 -1
  61. package/workframe-ui/public/assets/{line-CNtIbnmt.js → line-BSFj2OC5.js} +1 -1
  62. package/workframe-ui/public/assets/{linear-pmSg_4uV.js → linear-pfPwnu-o.js} +1 -1
  63. package/workframe-ui/public/assets/{mermaid-parser.core-BX4tnojE.js → mermaid-parser.core-Dm2L9Ib_.js} +2 -2
  64. package/workframe-ui/public/assets/{mermaid.core-BtpBva5o.js → mermaid.core-Bevx9bif.js} +3 -3
  65. package/workframe-ui/public/assets/{mindmap-definition-RKZ34NQL-DcMcB_69.js → mindmap-definition-RKZ34NQL-UkjDssmP.js} +1 -1
  66. package/workframe-ui/public/assets/{packet-YPE3B663-KSzK9WlD.js → packet-YPE3B663-JO2ezH3_.js} +1 -1
  67. package/workframe-ui/public/assets/{pie-LRSECV5Y-DLOH6Mg8.js → pie-LRSECV5Y-DdMFsfR8.js} +1 -1
  68. package/workframe-ui/public/assets/{pieDiagram-4H26LBE5-BhrX2aGk.js → pieDiagram-4H26LBE5-CEPHFBU1.js} +1 -1
  69. package/workframe-ui/public/assets/{quadrantDiagram-W4KKPZXB-B5dDjbTX.js → quadrantDiagram-W4KKPZXB-_RF9_86k.js} +1 -1
  70. package/workframe-ui/public/assets/{radar-GUYGQ44K-BPdjqZiu.js → radar-GUYGQ44K-Cb-YfdaA.js} +1 -1
  71. package/workframe-ui/public/assets/{requirementDiagram-4Y6WPE33-21Dq5e0N.js → requirementDiagram-4Y6WPE33-DBVOxmBn.js} +1 -1
  72. package/workframe-ui/public/assets/{sankeyDiagram-5OEKKPKP-CiA99dbO.js → sankeyDiagram-5OEKKPKP-BTpxsGUA.js} +1 -1
  73. package/workframe-ui/public/assets/{sequenceDiagram-3UESZ5HK-Bwpui7_x.js → sequenceDiagram-3UESZ5HK-DHP_Bq3l.js} +1 -1
  74. package/workframe-ui/public/assets/{src-B3Axsi1U.js → src-CY_By-r7.js} +1 -1
  75. package/workframe-ui/public/assets/{stateDiagram-AJRCARHV-C76qwtE8.js → stateDiagram-AJRCARHV-BVtp_LPR.js} +1 -1
  76. package/workframe-ui/public/assets/stateDiagram-v2-BHNVJYJU-CvJhS_BJ.js +1 -0
  77. package/workframe-ui/public/assets/{timeline-definition-PNZ67QCA-CufInOyk.js → timeline-definition-PNZ67QCA-D38HJhop.js} +1 -1
  78. package/workframe-ui/public/assets/{treeView-BLDUP644-C4sxh0R-.js → treeView-BLDUP644-CFCG3Sc_.js} +1 -1
  79. package/workframe-ui/public/assets/{treemap-LRROVOQU-BjV72ANV.js → treemap-LRROVOQU-BeiMs_dF.js} +1 -1
  80. package/workframe-ui/public/assets/{vennDiagram-CIIHVFJN-DgsdR0Rl.js → vennDiagram-CIIHVFJN-CKMeT6PW.js} +1 -1
  81. package/workframe-ui/public/assets/{wardley-L42UT6IY-DZ279G_t.js → wardley-L42UT6IY-BljDy8ph.js} +1 -1
  82. package/workframe-ui/public/assets/{wardleyDiagram-YWT4CUSO-Bde25kvz.js → wardleyDiagram-YWT4CUSO-DEE8D94J.js} +1 -1
  83. package/workframe-ui/public/assets/{xychartDiagram-2RQKCTM6-B8VnS2Pb.js → xychartDiagram-2RQKCTM6-BRaAWV_g.js} +1 -1
  84. package/workframe-ui/public/index.html +2 -2
  85. package/workframe-ui/public/assets/architecture-7EHR7CIX-CCMNXHod.js +0 -1
  86. package/workframe-ui/public/assets/channel-CtFV3sE3.js +0 -1
  87. package/workframe-ui/public/assets/chunk-QZHKN3VN-B1g7l1_B.js +0 -1
  88. package/workframe-ui/public/assets/chunk-WU5MYG2G-B_qfZ6QP.js +0 -1
  89. package/workframe-ui/public/assets/classDiagram-4FO5ZUOK-CJoeCNq6.js +0 -1
  90. package/workframe-ui/public/assets/classDiagram-v2-Q7XG4LA2-CJoeCNq6.js +0 -1
  91. package/workframe-ui/public/assets/eventmodeling-FCH6USID-Bw910jho.js +0 -1
  92. package/workframe-ui/public/assets/index-DHLQNAXd.js +0 -129
  93. package/workframe-ui/public/assets/stateDiagram-v2-BHNVJYJU-Dn0CDWJD.js +0 -1
@@ -53,6 +53,55 @@ def _npm_latest_version() -> str:
53
53
  return str(data.get("version") or "").strip()
54
54
 
55
55
 
56
+ def _supervisor_tarball_path(package: str, version: str) -> str:
57
+ """Path on the compose bind mount — supervisor reads /compose even when API lacks that mount."""
58
+ for raw in (os.environ.get("WORKFRAME_COMPOSE_DIR", ""), "/compose"):
59
+ root = str(raw or "").strip().rstrip("/")
60
+ if root and root != ".":
61
+ return f"{root}/workframe-api/data/.update-staging/{package}-{version}.tgz"
62
+ data_dir = Path(os.environ.get("WORKFRAME_API_DATA_DIR", "/app/data"))
63
+ return str(data_dir / ".update-staging" / f"{package}-{version}.tgz")
64
+
65
+
66
+ def prefetch_workframe_npm_tarball(version: str) -> str:
67
+ """Download create-workframe pack to API data dir; return supervisor-visible path."""
68
+ import base64
69
+ import hashlib
70
+
71
+ ver = str(version or "").strip()
72
+ if not ver:
73
+ raise ValueError("workframe_version_required")
74
+ pkg = NPM_PACKAGE
75
+ try:
76
+ meta = _http_json(
77
+ f"https://registry.npmjs.org/{urllib.parse.quote(pkg)}/{urllib.parse.quote(ver)}",
78
+ timeout=60.0,
79
+ )
80
+ except (urllib.error.URLError, TimeoutError, json.JSONDecodeError, OSError) as exc:
81
+ raise ValueError(f"npm_fetch_failed:{exc}") from exc
82
+ dist = meta.get("dist") if isinstance(meta.get("dist"), dict) else {}
83
+ url = str(dist.get("tarball") or "").strip()
84
+ integrity = str(dist.get("integrity") or "").strip()
85
+ if not url:
86
+ raise ValueError("npm_tarball_url_missing")
87
+ data_dir = Path(os.environ.get("WORKFRAME_API_DATA_DIR", "/app/data"))
88
+ staging = data_dir / ".update-staging"
89
+ staging.mkdir(parents=True, exist_ok=True)
90
+ dest = staging / f"{pkg}-{ver}.tgz"
91
+ req = urllib.request.Request(url, headers={"User-Agent": "workframe-api"})
92
+ try:
93
+ with urllib.request.urlopen(req, timeout=300.0) as resp:
94
+ body = resp.read()
95
+ except (urllib.error.URLError, TimeoutError, OSError) as exc:
96
+ raise ValueError(f"npm_download_failed:{exc}") from exc
97
+ if integrity.startswith("sha512-"):
98
+ actual = "sha512-" + base64.b64encode(hashlib.sha512(body).digest()).decode()
99
+ if actual != integrity:
100
+ raise ValueError("npm_integrity_mismatch")
101
+ dest.write_bytes(body)
102
+ return _supervisor_tarball_path(pkg, ver)
103
+
104
+
56
105
  def _docker_hub_digest(repo: str, tag: str) -> str:
57
106
  url = f"https://hub.docker.com/v2/repositories/{repo}/tags/{urllib.parse.quote(tag)}"
58
107
  data = _http_json(url)
@@ -113,8 +162,11 @@ def _container_image_digest(name: str) -> tuple[str, str]:
113
162
 
114
163
  def _read_installed_workframe_version(project_root: Path) -> dict[str, str]:
115
164
  out = {"api": API_VERSION, "package": "", "manifest_generator": ""}
165
+ pin = Path(os.environ.get("WORKFRAME_API_DATA_DIR", "/app/data")) / "package-version"
166
+ if pin.is_file():
167
+ out["package"] = pin.read_text(encoding="utf-8").strip()
116
168
  manifest = project_root / "workframe-manifest.json"
117
- if manifest.is_file():
169
+ if not out["package"] and manifest.is_file():
118
170
  try:
119
171
  data = json.loads(manifest.read_text(encoding="utf-8"))
120
172
  out["package"] = str(data.get("package_version") or "")
@@ -404,36 +456,64 @@ def updates_available(*, desktop_version: str = "", hermes_agent_version: str =
404
456
  }
405
457
 
406
458
 
407
- def _apply_env_for_target(target: str) -> dict[str, str]:
408
- env = os.environ.copy()
409
- env.setdefault("WORKFRAME_COMPOSE_DIR", str(_compose_dir()))
410
- env.setdefault("WORKFRAME_PROJECT_ROOT", str(_project_root()))
411
- if target in {"workframe", "all"}:
412
- latest = ""
459
+ def _supervisor_stack_apply(body: dict[str, Any], *, timeout: float = 900.0) -> dict[str, Any]:
460
+ if not _supervisor_configured():
461
+ raise ValueError("supervisor_not_configured")
462
+ base = str(os.environ.get("WORKFRAME_SUPERVISOR_URL", "")).rstrip("/")
463
+ token = str(os.environ.get("WORKFRAME_SUPERVISOR_TOKEN", "")).strip()
464
+ payload = json.dumps(body).encode("utf-8")
465
+ req = urllib.request.Request(
466
+ f"{base}/v1/stack.apply",
467
+ data=payload,
468
+ method="POST",
469
+ headers={
470
+ "Authorization": f"Bearer {token}",
471
+ "Content-Type": "application/json",
472
+ "Accept": "application/json",
473
+ "User-Agent": "workframe-api",
474
+ },
475
+ )
476
+ try:
477
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
478
+ data = json.loads(resp.read().decode("utf-8"))
479
+ except urllib.error.HTTPError as exc:
480
+ detail = exc.read().decode("utf-8", errors="replace")
413
481
  try:
414
- latest = str(updates_available().get("workframe", {}).get("latest") or "").strip()
415
- except Exception: # noqa: BLE001
416
- latest = ""
417
- if latest:
418
- env["WORKFRAME_UPDATE_ALLOW_NPM"] = "1"
419
- env["WORKFRAME_UPDATE_VERSION"] = latest
420
- return env
482
+ parsed = json.loads(detail)
483
+ if isinstance(parsed, dict) and parsed.get("error"):
484
+ raise ValueError(str(parsed["error"])) from exc
485
+ except json.JSONDecodeError:
486
+ pass
487
+ raise ValueError(f"supervisor_apply_failed:{exc.code}") from exc
488
+ except (urllib.error.URLError, TimeoutError, json.JSONDecodeError, OSError) as exc:
489
+ raise ValueError(f"supervisor_apply_failed:{exc}") from exc
490
+ if not isinstance(data, dict) or not data.get("ok"):
491
+ raise ValueError(str(data.get("error") or "supervisor_apply_failed"))
492
+ return data
421
493
 
422
494
 
423
- def apply_update(target: str) -> dict[str, Any]:
424
- if not _admin_stack_updates_enabled():
425
- raise ValueError("admin_updates_disabled")
426
- target = str(target or "all").strip().lower()
427
- if target not in {"hermes", "workframe", "all"}:
428
- raise ValueError("invalid_update_target")
429
- _, apply_ready, apply_reason = _update_apply_channel()
430
- if not apply_ready:
431
- if not Path(DOCKER_SOCK).exists():
432
- raise ValueError("docker_unavailable")
433
- raise ValueError(str(apply_reason or "docker_apply_unavailable"))
434
- if not Path(DOCKER_SOCK).exists():
435
- raise ValueError("docker_unavailable")
495
+ def _workframe_update_target_version() -> str:
496
+ try:
497
+ return str(updates_available().get("workframe", {}).get("latest") or "").strip()
498
+ except Exception: # noqa: BLE001
499
+ return ""
500
+
501
+
502
+ def _visible_tarball_path(package: str, version: str, *, channel: str) -> str:
503
+ if channel == "supervisor":
504
+ return _supervisor_tarball_path(package, version)
505
+ return str(Path(os.environ.get("WORKFRAME_API_DATA_DIR", "/app/data")) / ".update-staging" / f"{package}-{version}.tgz")
436
506
 
507
+
508
+ def _prepare_workframe_update(channel: str) -> tuple[str, str]:
509
+ version = _workframe_update_target_version()
510
+ if not version:
511
+ raise ValueError("workframe_update_version_unavailable")
512
+ prefetch_workframe_npm_tarball(version)
513
+ return version, _visible_tarball_path(NPM_PACKAGE, version, channel=channel)
514
+
515
+
516
+ def _run_apply_scripts(target: str, env: dict[str, str]) -> dict[str, Any]:
437
517
  scripts: list[str] = []
438
518
  if target in {"hermes", "all"}:
439
519
  script = _script_path("apply-update-hermes.sh")
@@ -446,8 +526,6 @@ def apply_update(target: str) -> dict[str, Any]:
446
526
  raise ValueError("update_script_missing:workframe")
447
527
  scripts.append(str(script))
448
528
 
449
- env = _apply_env_for_target(target)
450
-
451
529
  logs: list[str] = []
452
530
  for script in scripts:
453
531
  proc = subprocess.run(
@@ -461,18 +539,53 @@ def apply_update(target: str) -> dict[str, Any]:
461
539
  logs.append(f"=== {script} (exit {proc.returncode}) ===\n{proc.stdout}\n{proc.stderr}")
462
540
  if proc.returncode != 0:
463
541
  raise ValueError(f"update_failed:{Path(script).name}")
464
-
465
542
  return {"ok": True, "target": target, "log": "\n".join(logs)[-12000:]}
466
543
 
467
544
 
545
+ def apply_update(target: str) -> dict[str, Any]:
546
+ if not _admin_stack_updates_enabled():
547
+ raise ValueError("admin_updates_disabled")
548
+ target = str(target or "all").strip().lower()
549
+ if target not in {"hermes", "workframe", "all"}:
550
+ raise ValueError("invalid_update_target")
551
+ channel, apply_ready, apply_reason = _update_apply_channel()
552
+ if not apply_ready:
553
+ raise ValueError(str(apply_reason or "docker_apply_unavailable"))
554
+
555
+ workframe_version = ""
556
+ workframe_tarball = ""
557
+ if target in {"workframe", "all"}:
558
+ workframe_version, workframe_tarball = _prepare_workframe_update(channel)
559
+
560
+ if channel == "supervisor":
561
+ body: dict[str, Any] = {"target": target}
562
+ if workframe_version:
563
+ body["workframe_version"] = workframe_version
564
+ if workframe_tarball:
565
+ body["workframe_tarball"] = workframe_tarball
566
+ return _supervisor_stack_apply(body)
567
+
568
+ if not Path(DOCKER_SOCK).exists():
569
+ raise ValueError("docker_unavailable")
570
+
571
+ env = os.environ.copy()
572
+ env.setdefault("WORKFRAME_COMPOSE_DIR", str(_compose_dir()))
573
+ env.setdefault("WORKFRAME_PROJECT_ROOT", str(_project_root()))
574
+ if workframe_version:
575
+ env["WORKFRAME_UPDATE_VERSION"] = workframe_version
576
+ if workframe_tarball:
577
+ env["WORKFRAME_UPDATE_TARBALL"] = workframe_tarball
578
+ return _run_apply_scripts(target, env)
579
+
580
+
468
581
  def restart_gateway() -> dict[str, Any]:
469
582
  if not _admin_stack_updates_enabled():
470
583
  raise ValueError("admin_updates_disabled")
471
- _, apply_ready, apply_reason = _update_apply_channel()
584
+ channel, apply_ready, apply_reason = _update_apply_channel()
472
585
  if not apply_ready:
473
- if not Path(DOCKER_SOCK).exists():
474
- raise ValueError("docker_unavailable")
475
586
  raise ValueError(str(apply_reason or "docker_apply_unavailable"))
587
+ if channel == "supervisor":
588
+ return _supervisor_stack_apply({"target": "gateway-restart"}, timeout=300.0)
476
589
  if not Path(DOCKER_SOCK).exists():
477
590
  raise ValueError("docker_unavailable")
478
591
  script = _script_path("restart-gateway-hermes.sh")
@@ -5,7 +5,7 @@ FROM python:3-alpine
5
5
  RUN apk add --no-cache docker-cli docker-cli-compose bash nodejs npm
6
6
 
7
7
  WORKDIR /app
8
- COPY server.py profile_secret_policy.py .
8
+ COPY server.py profile_secret_policy.py ./
9
9
 
10
10
  EXPOSE 8090
11
11
  CMD ["python3", "server.py"]
@@ -60,7 +60,7 @@ def _exec_targets_runtime_profile_secrets(cmd: list[str], acting_profile: str =
60
60
  return exec_blocked_for_profile(cmd, acting_profile)
61
61
 
62
62
 
63
- def _stack_apply(target: str, *, workframe_version: str = "") -> dict[str, Any]:
63
+ def _stack_apply(target: str, *, workframe_version: str = "", workframe_tarball: str = "") -> dict[str, Any]:
64
64
  target = str(target or "all").strip().lower()
65
65
  if target == "gateway-restart":
66
66
  script = SCRIPTS_DIR / "restart-gateway-hermes.sh"
@@ -92,7 +92,12 @@ def _stack_apply(target: str, *, workframe_version: str = "") -> dict[str, Any]:
92
92
  scripts.append(p)
93
93
  env = os.environ.copy()
94
94
  version = str(workframe_version or "").strip()
95
- if version and target in {"workframe", "all"}:
95
+ tarball = str(workframe_tarball or "").strip()
96
+ if tarball and target in {"workframe", "all"}:
97
+ env["WORKFRAME_UPDATE_TARBALL"] = tarball
98
+ if version:
99
+ env["WORKFRAME_UPDATE_VERSION"] = version
100
+ elif version and target in {"workframe", "all"}:
96
101
  env["WORKFRAME_UPDATE_ALLOW_NPM"] = "1"
97
102
  env["WORKFRAME_UPDATE_VERSION"] = version
98
103
  logs: list[str] = []
@@ -780,8 +785,16 @@ class Handler(BaseHTTPRequestHandler):
780
785
  if path == "/v1/stack.apply":
781
786
  target = str(body.get("target") or "all").strip().lower()
782
787
  workframe_version = str(body.get("workframe_version") or "").strip()
788
+ workframe_tarball = str(body.get("workframe_tarball") or "").strip()
783
789
  try:
784
- return self._json(200, _stack_apply(target, workframe_version=workframe_version))
790
+ return self._json(
791
+ 200,
792
+ _stack_apply(
793
+ target,
794
+ workframe_version=workframe_version,
795
+ workframe_tarball=workframe_tarball,
796
+ ),
797
+ )
785
798
  except ValueError as exc:
786
799
  return self._json(400, {"ok": False, "error": str(exc)})
787
800
  except Exception as exc: # noqa: BLE001
@@ -1 +1 @@
1
- import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-uZYeD3o1.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
1
+ import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-CPbiDkEZ.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -0,0 +1 @@
1
+ import"./chunk-NNHCCRGN-DlpIbxXb.js";import{x as e}from"./mermaid-parser.core-Dm2L9Ib_.js";export{e as createArchitectureServices};