@11agents/cli 0.1.42 → 0.1.43

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.
@@ -745,6 +745,10 @@ def main() -> None:
745
745
  print(
746
746
  f"{result.device_id}: status={result.status} duration={result.duration_seconds}s "
747
747
  f"record_id={result.record_id} screenshot={result.screenshot_path}"
748
+ + (f" permalink={result.platform_permalink}" if result.platform_permalink else "")
749
+ + (f" post_id={result.platform_post_id}" if result.platform_post_id else "")
750
+ + (f" link_status={result.link_status}" if result.link_status else "")
751
+ + (f" link_error={result.link_error}" if result.link_error else "")
748
752
  + (f" error={result.error}" if result.error else "")
749
753
  )
750
754
 
@@ -781,6 +785,10 @@ def main() -> None:
781
785
  print(
782
786
  f"{result.device_id}: status={result.status} duration={result.duration_seconds}s "
783
787
  f"record_id={result.record_id} screenshot={result.screenshot_path}"
788
+ + (f" permalink={result.platform_permalink}" if result.platform_permalink else "")
789
+ + (f" post_id={result.platform_post_id}" if result.platform_post_id else "")
790
+ + (f" link_status={result.link_status}" if result.link_status else "")
791
+ + (f" link_error={result.link_error}" if result.link_error else "")
784
792
  + (f" error={result.error}" if result.error else "")
785
793
  )
786
794
 
@@ -921,7 +929,7 @@ def main() -> None:
921
929
  if args.account_id and len(selected) != 1:
922
930
  raise SystemExit("--account-id is only allowed with exactly one target device")
923
931
  post_text = _x_publish_text(args)
924
- if args.text_input in {"auto", "appium"} and not post_text.isascii():
932
+ if not args.dry_run or (args.text_input in {"auto", "appium"} and not post_text.isascii()):
925
933
  _ensure_appium_preflight(args, selected)
926
934
  publisher = XAdbPublisher(adb, appium_server=args.appium_server, records_path=args.records)
927
935
 
@@ -947,6 +955,9 @@ def main() -> None:
947
955
  print(
948
956
  f"{result.device_id}: status={result.status} duration={result.duration_seconds}s "
949
957
  f"record_id={result.record_id} screenshot={result.screenshot_path}"
958
+ + (f" permalink={result.platform_permalink}" if result.platform_permalink else "")
959
+ + (f" link_status={result.link_status}" if result.link_status else "")
960
+ + (f" link_error={result.link_error}" if result.link_error else "")
950
961
  + (f" error={result.error}" if result.error else "")
951
962
  )
952
963
 
@@ -1316,7 +1327,11 @@ def _add_publish_x_args(parser: argparse.ArgumentParser) -> None:
1316
1327
  parser.add_argument("--account-id", default="", help="Single account id. Use only with one target device.")
1317
1328
  parser.add_argument("--account-prefix", default="x", help="Fallback account id prefix for multi-device runs.")
1318
1329
  parser.add_argument("--dry-run", action="store_true", help="Stop at X compose form without tapping Post.")
1319
- parser.add_argument("--no-verify-profile", action="store_true", help="Do not open the X profile page to verify the published post text.")
1330
+ parser.add_argument(
1331
+ "--no-verify-profile",
1332
+ action="store_true",
1333
+ help="Skip the standalone post-publish profile confirmation; live publish still opens the profile for permalink recovery.",
1334
+ )
1320
1335
  parser.add_argument("--parallel", action="store_true", help="Run target devices concurrently. Hard-capped at 5.")
1321
1336
  parser.add_argument("--max-concurrency", type=int, default=MAX_PARALLEL_DEVICES, help="Max concurrent devices, 1-5.")
1322
1337
  parser.add_argument("--json", action="store_true", help="Print JSON lines")
@@ -560,9 +560,14 @@ def _find_profile_video_nodes(root, width: int, height: int):
560
560
  if not ui.is_visible(node) or node.attrib.get("clickable") != "true":
561
561
  continue
562
562
  resource_id = node.attrib.get("resource-id", "")
563
- if resource_id and not resource_id.endswith(":id/ekl"):
563
+ has_video_tile_id = resource_id.endswith((":id/ekl", ":id/ej9"))
564
+ has_cover_child = any(
565
+ child.attrib.get("resource-id", "").endswith(":id/cover")
566
+ for child in node.iter("node")
567
+ )
568
+ if resource_id and not has_video_tile_id and not has_cover_child:
564
569
  continue
565
- if resource_id.endswith(":id/ekl") and node.attrib.get("long-clickable") != "true":
570
+ if (has_video_tile_id or has_cover_child) and node.attrib.get("long-clickable") != "true":
566
571
  continue
567
572
  value = ui.bounds(node)
568
573
  if not value:
@@ -572,7 +577,7 @@ def _find_profile_video_nodes(root, width: int, height: int):
572
577
  node_height = bottom - top
573
578
  if top < int(height * 0.25):
574
579
  continue
575
- if bottom > int(height * 0.93):
580
+ if bottom > int(height * 0.98):
576
581
  continue
577
582
  if node_width < int(width * 0.20) or node_height < int(height * 0.10):
578
583
  continue