rhylthyme-cli-runner 0.2.4a0__tar.gz → 0.2.5a0__tar.gz

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 (87) hide show
  1. {rhylthyme_cli_runner-0.2.4a0/src/rhylthyme_cli_runner.egg-info → rhylthyme_cli_runner-0.2.5a0}/PKG-INFO +20 -8
  2. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/README.md +19 -7
  3. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/setup.py +1 -1
  4. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/__init__.py +1 -1
  5. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/cli.py +10 -0
  6. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/import_cli.py +13 -1
  7. rhylthyme_cli_runner-0.2.5a0/src/rhylthyme_cli_runner/render_cli.py +41 -0
  8. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0/src/rhylthyme_cli_runner.egg-info}/PKG-INFO +20 -8
  9. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner.egg-info/SOURCES.txt +2 -0
  10. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_import_cli.py +14 -0
  11. rhylthyme_cli_runner-0.2.5a0/tests/test_render_cli.py +33 -0
  12. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/LICENSE +0 -0
  13. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/pyproject.toml +0 -0
  14. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/setup.cfg +0 -0
  15. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/environment_icons.py +0 -0
  16. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/environment_loader.py +0 -0
  17. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/environment_schemas.py +0 -0
  18. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/__init__.py +0 -0
  19. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/cli.py +0 -0
  20. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/compare.py +0 -0
  21. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/gold.py +0 -0
  22. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/harness.py +0 -0
  23. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/llm.py +0 -0
  24. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/matcher.py +0 -0
  25. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/metrics.py +0 -0
  26. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/patterns/__init__.py +0 -0
  27. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/patterns/authoring_guide.md +0 -0
  28. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/patterns/baseline.md +0 -0
  29. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/patterns/baseline.py +0 -0
  30. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/patterns/extract.py +0 -0
  31. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/patterns/four_turn.py +0 -0
  32. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/eval/report.py +0 -0
  33. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/expand_replicates.py +0 -0
  34. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/__init__.py +0 -0
  35. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/calibrate.py +0 -0
  36. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/calibrate_cli.py +0 -0
  37. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/cli.py +0 -0
  38. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/evaluate.py +0 -0
  39. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/evaluate_cli.py +0 -0
  40. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/factors.py +0 -0
  41. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/hash.py +0 -0
  42. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/predict.py +0 -0
  43. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/recorder.py +0 -0
  44. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/render.py +0 -0
  45. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/replay.py +0 -0
  46. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/report.py +0 -0
  47. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/report_cli.py +0 -0
  48. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/store.py +0 -0
  49. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/synth.py +0 -0
  50. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/history/usable.py +0 -0
  51. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/instance_checks.py +0 -0
  52. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/program_planner.py +0 -0
  53. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/program_runner.py +0 -0
  54. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/remote/__init__.py +0 -0
  55. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/remote/auth.py +0 -0
  56. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/remote/checks.py +0 -0
  57. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/remote/cli.py +0 -0
  58. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/remote/mcp_client.py +0 -0
  59. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner/validate_program.py +0 -0
  60. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner.egg-info/dependency_links.txt +0 -0
  61. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner.egg-info/entry_points.txt +0 -0
  62. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner.egg-info/requires.txt +0 -0
  63. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/src/rhylthyme_cli_runner.egg-info/top_level.txt +0 -0
  64. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_calibrate.py +0 -0
  65. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_cli.py +0 -0
  66. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_eval_baseline.py +0 -0
  67. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_eval_harness.py +0 -0
  68. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_eval_providers.py +0 -0
  69. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_eval_scorer.py +0 -0
  70. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_evaluate.py +0 -0
  71. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_example_validation.py +0 -0
  72. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_examples_integration.py +0 -0
  73. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_expand_replicates.py +0 -0
  74. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_hash_parity.py +0 -0
  75. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_history_report.py +0 -0
  76. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_mcp_checks.py +0 -0
  77. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_planner_time_strings.py +0 -0
  78. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_predict.py +0 -0
  79. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_program_runner.py +0 -0
  80. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_remote.py +0 -0
  81. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_replay.py +0 -0
  82. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_run_recorder.py +0 -0
  83. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_skill.py +0 -0
  84. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_synth.py +0 -0
  85. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_usable.py +0 -0
  86. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_validate_examples_ci.py +0 -0
  87. {rhylthyme_cli_runner-0.2.4a0 → rhylthyme_cli_runner-0.2.5a0}/tests/test_validate_program.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rhylthyme-cli-runner
3
- Version: 0.2.4a0
3
+ Version: 0.2.5a0
4
4
  Summary: CLI runner for Rhylthyme real-time program schedules
5
5
  Home-page: https://github.com/rhylthyme/rhylthyme-cli-runner
6
6
  Author: Rhylthyme Team
@@ -64,7 +64,7 @@ Command-line interface for validating and running Rhylthyme real-time program sc
64
64
  and for turning a plain-language request into one through the hosted Rhylthyme MCP server.
65
65
 
66
66
  ```bash
67
- pip install rhylthyme-cli-runner
67
+ pip install rhylthyme
68
68
  rhylthyme login
69
69
  rhylthyme generate "roast chicken, potatoes and green beans for 6" -e kitchen --by 19:00 --with "one oven"
70
70
  ```
@@ -76,7 +76,7 @@ the oven, when do the balloons go up, and do the pizzas and the cake ever want
76
76
  the oven at the same time?
77
77
 
78
78
  ```bash
79
- pip install rhylthyme-cli-runner
79
+ pip install rhylthyme
80
80
 
81
81
  # 1. a program: the party, the kitchen and the setup crew, 13 steps
82
82
  curl -sO https://raw.githubusercontent.com/rhylthyme/rhylthyme-cli-runner/main/examples/recipe/birthday-party.json
@@ -117,8 +117,8 @@ Start Sat 12:50, finish Sat 16:00 (local time)
117
117
  # 4. a live timeline for the fridge door (or a phone): timers, cues, and you end the piñata when it breaks
118
118
  rhylthyme publish birthday-party.json --open --image party-preview.png
119
119
 
120
- # 5. a picture for the group chat, on the wall clock (needs Node; nothing to install)
121
- npx -y github:rhylthyme/rhylthyme-timeline birthday-party.json -o birthday-party.png \
120
+ # 5. a picture for the group chat, on the wall clock (needs Node.js)
121
+ rhylthyme render birthday-party.json -o birthday-party.png \
122
122
  --style web --palette vivid --label-overflow outside --start-at "$(date +%F)T12:50:00"
123
123
  ```
124
124
 
@@ -141,7 +141,7 @@ is the **server an AI assistant talks to**.
141
141
  |---|---|---|
142
142
  | What it is | The MCP **server**: the tools an AI assistant calls | A command-line **program**: the `rhylthyme` command |
143
143
  | Who uses it | Claude, ChatGPT, Cursor or any MCP client, on a person's behalf | A person at a terminal, a script, or CI |
144
- | Where it runs | Hosted at `mcp.rhylthyme.com`; nothing to install | On your machine: `pip install rhylthyme-cli-runner` |
144
+ | Where it runs | Hosted at `mcp.rhylthyme.com`; nothing to install | On your machine: `pip install rhylthyme` |
145
145
  | Language | JavaScript (Node 20+) | Python 3.12+ |
146
146
  | Input | A program the assistant builds in conversation | A program file on disk (JSON or YAML) |
147
147
  | Validate a program | `validate_program` | `rhylthyme validate` (works offline) |
@@ -189,7 +189,8 @@ pip install -e ".[dev]"
189
189
  ### From PyPI
190
190
 
191
191
  ```bash
192
- pip install rhylthyme-cli-runner
192
+ pip install rhylthyme # this package, the importers and the renderer
193
+ pip install rhylthyme-cli-runner # this package alone
193
194
  ```
194
195
 
195
196
  ## Getting the Examples
@@ -553,7 +554,7 @@ writes `<programId>.json`. Needs `rhylthyme-importers` (included in
553
554
  rhylthyme import https://www.seriouseats.com/the-best-chili-recipe # any of ~580 recipe sites
554
555
  rhylthyme import 52772 -i themealdb --publish # a TheMealDB id, straight to a live timeline
555
556
  rhylthyme import https://www.protocols.io/view/western-blot-... # needs PROTOCOLS_IO_TOKEN
556
- rhylthyme import protocol.py -o protocol.json # an Opentrons file
557
+ rhylthyme import https://raw.githubusercontent.com/Opentrons/Protocols/develop/protocols/007992/rna_isolation.ot2.apiv2.py # an Opentrons protocol
557
558
  rhylthyme import "Neapolitan Pizza.cook" -i cooklang
558
559
  rhylthyme importers # what is installed
559
560
  rhylthyme search "pad thai" -i spoonacular # then import a hit's URL
@@ -563,6 +564,17 @@ rhylthyme search "pad thai" -i spoonacular # then impo
563
564
  `--stdout`, `--publish` (and `--open`), `--no-validate`. `-` reads pasted
564
565
  source from stdin (with `-i`).
565
566
 
567
+ ### `rhylthyme render`
568
+
569
+ Draws a program as an SVG, PNG or PDF figure through the `rhylthyme-timeline`
570
+ package (included in `pip install rhylthyme`; needs Node.js 18+). Every
571
+ option of `rhylthyme-render` is accepted: `rhylthyme render --help`.
572
+
573
+ ```bash
574
+ rhylthyme render dinner.json -o dinner.png --style web --palette vivid --color-by task
575
+ rhylthyme render blot.json -o figure.pdf --style publication --legend right
576
+ ```
577
+
566
578
  ### `rhylthyme plan`
567
579
 
568
580
  An older stagger heuristic. It reads the pre-0.2 program format and leaves
@@ -4,7 +4,7 @@ Command-line interface for validating and running Rhylthyme real-time program sc
4
4
  and for turning a plain-language request into one through the hosted Rhylthyme MCP server.
5
5
 
6
6
  ```bash
7
- pip install rhylthyme-cli-runner
7
+ pip install rhylthyme
8
8
  rhylthyme login
9
9
  rhylthyme generate "roast chicken, potatoes and green beans for 6" -e kitchen --by 19:00 --with "one oven"
10
10
  ```
@@ -16,7 +16,7 @@ the oven, when do the balloons go up, and do the pizzas and the cake ever want
16
16
  the oven at the same time?
17
17
 
18
18
  ```bash
19
- pip install rhylthyme-cli-runner
19
+ pip install rhylthyme
20
20
 
21
21
  # 1. a program: the party, the kitchen and the setup crew, 13 steps
22
22
  curl -sO https://raw.githubusercontent.com/rhylthyme/rhylthyme-cli-runner/main/examples/recipe/birthday-party.json
@@ -57,8 +57,8 @@ Start Sat 12:50, finish Sat 16:00 (local time)
57
57
  # 4. a live timeline for the fridge door (or a phone): timers, cues, and you end the piñata when it breaks
58
58
  rhylthyme publish birthday-party.json --open --image party-preview.png
59
59
 
60
- # 5. a picture for the group chat, on the wall clock (needs Node; nothing to install)
61
- npx -y github:rhylthyme/rhylthyme-timeline birthday-party.json -o birthday-party.png \
60
+ # 5. a picture for the group chat, on the wall clock (needs Node.js)
61
+ rhylthyme render birthday-party.json -o birthday-party.png \
62
62
  --style web --palette vivid --label-overflow outside --start-at "$(date +%F)T12:50:00"
63
63
  ```
64
64
 
@@ -81,7 +81,7 @@ is the **server an AI assistant talks to**.
81
81
  |---|---|---|
82
82
  | What it is | The MCP **server**: the tools an AI assistant calls | A command-line **program**: the `rhylthyme` command |
83
83
  | Who uses it | Claude, ChatGPT, Cursor or any MCP client, on a person's behalf | A person at a terminal, a script, or CI |
84
- | Where it runs | Hosted at `mcp.rhylthyme.com`; nothing to install | On your machine: `pip install rhylthyme-cli-runner` |
84
+ | Where it runs | Hosted at `mcp.rhylthyme.com`; nothing to install | On your machine: `pip install rhylthyme` |
85
85
  | Language | JavaScript (Node 20+) | Python 3.12+ |
86
86
  | Input | A program the assistant builds in conversation | A program file on disk (JSON or YAML) |
87
87
  | Validate a program | `validate_program` | `rhylthyme validate` (works offline) |
@@ -129,7 +129,8 @@ pip install -e ".[dev]"
129
129
  ### From PyPI
130
130
 
131
131
  ```bash
132
- pip install rhylthyme-cli-runner
132
+ pip install rhylthyme # this package, the importers and the renderer
133
+ pip install rhylthyme-cli-runner # this package alone
133
134
  ```
134
135
 
135
136
  ## Getting the Examples
@@ -493,7 +494,7 @@ writes `<programId>.json`. Needs `rhylthyme-importers` (included in
493
494
  rhylthyme import https://www.seriouseats.com/the-best-chili-recipe # any of ~580 recipe sites
494
495
  rhylthyme import 52772 -i themealdb --publish # a TheMealDB id, straight to a live timeline
495
496
  rhylthyme import https://www.protocols.io/view/western-blot-... # needs PROTOCOLS_IO_TOKEN
496
- rhylthyme import protocol.py -o protocol.json # an Opentrons file
497
+ rhylthyme import https://raw.githubusercontent.com/Opentrons/Protocols/develop/protocols/007992/rna_isolation.ot2.apiv2.py # an Opentrons protocol
497
498
  rhylthyme import "Neapolitan Pizza.cook" -i cooklang
498
499
  rhylthyme importers # what is installed
499
500
  rhylthyme search "pad thai" -i spoonacular # then import a hit's URL
@@ -503,6 +504,17 @@ rhylthyme search "pad thai" -i spoonacular # then impo
503
504
  `--stdout`, `--publish` (and `--open`), `--no-validate`. `-` reads pasted
504
505
  source from stdin (with `-i`).
505
506
 
507
+ ### `rhylthyme render`
508
+
509
+ Draws a program as an SVG, PNG or PDF figure through the `rhylthyme-timeline`
510
+ package (included in `pip install rhylthyme`; needs Node.js 18+). Every
511
+ option of `rhylthyme-render` is accepted: `rhylthyme render --help`.
512
+
513
+ ```bash
514
+ rhylthyme render dinner.json -o dinner.png --style web --palette vivid --color-by task
515
+ rhylthyme render blot.json -o figure.pdf --style publication --legend right
516
+ ```
517
+
506
518
  ### `rhylthyme plan`
507
519
 
508
520
  An older stagger heuristic. It reads the pre-0.2 program format and leaves
@@ -19,7 +19,7 @@ def read_readme():
19
19
 
20
20
  setup(
21
21
  name="rhylthyme-cli-runner",
22
- version="0.2.4a0",
22
+ version="0.2.5a0",
23
23
  description="CLI runner for Rhylthyme real-time program schedules",
24
24
  long_description=read_readme(),
25
25
  long_description_content_type="text/markdown",
@@ -6,7 +6,7 @@ This package provides the command-line interface for running and validating
6
6
  Rhylthyme real-time program schedules.
7
7
  """
8
8
 
9
- __version__ = "0.2.4a0"
9
+ __version__ = "0.2.5a0"
10
10
  __author__ = "Rhylthyme Team"
11
11
  __description__ = "CLI runner for Rhylthyme real-time program schedules"
12
12
 
@@ -554,6 +554,16 @@ def _register_import_commands():
554
554
  _register_import_commands()
555
555
 
556
556
 
557
+ def _register_render_command():
558
+ """Attach `render` (rhylthyme_cli_runner.render_cli)."""
559
+ from .render_cli import register as register_render
560
+
561
+ register_render(cli)
562
+
563
+
564
+ _register_render_command()
565
+
566
+
557
567
  def main():
558
568
  """Entry point for the CLI."""
559
569
  cli()
@@ -49,6 +49,18 @@ def _pick(registry, source: str, importer_name: Optional[str]):
49
49
 
50
50
 
51
51
  def _import_one(importer, source: str, text: Optional[str]):
52
+ # An importer that works on text (Opentrons) gets a URL's body fetched
53
+ # for it; the URL-native importers fetch for themselves.
54
+ url_native = bool(getattr(importer, "supported_domains", None))
55
+ if (
56
+ text is None
57
+ and source.startswith(("http://", "https://"))
58
+ and hasattr(importer, "import_from_source")
59
+ and not url_native
60
+ ):
61
+ from .remote.cli import _fetch_bytes
62
+
63
+ text = _fetch_bytes(source).decode("utf-8")
52
64
  if text is not None and hasattr(importer, "import_from_source"):
53
65
  return importer.import_from_source(text)
54
66
  if text is not None and hasattr(importer, "import_from_content"):
@@ -129,7 +141,7 @@ def import_command(
129
141
  .cook or .pptx file. `-` reads the source text from stdin (with -i).
130
142
  rhylthyme import https://www.seriouseats.com/the-best-chili-recipe
131
143
  rhylthyme import 52772 -i themealdb --publish
132
- rhylthyme import protocol.py -o protocol.json
144
+ rhylthyme import https://raw.githubusercontent.com/Opentrons/Protocols/develop/protocols/007992/rna_isolation.ot2.apiv2.py
133
145
  rhylthyme importers # what is installed
134
146
  """
135
147
  registry = _registry()
@@ -0,0 +1,41 @@
1
+ """``rhylthyme render``: the timeline renderer from rhylthyme-timeline,
2
+ reached from the one command people already have. Every option of the
3
+ ``rhylthyme-render`` command is accepted unchanged."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import click
8
+
9
+ INSTALL_HINT = (
10
+ "The renderer is a separate package: pip install rhylthyme-timeline "
11
+ "(or pip install rhylthyme, which includes it). It runs on Node.js 18 or newer."
12
+ )
13
+
14
+
15
+ @click.command(
16
+ "render",
17
+ context_settings={
18
+ "ignore_unknown_options": True,
19
+ "allow_extra_args": True,
20
+ "help_option_names": [],
21
+ },
22
+ )
23
+ @click.argument("args", nargs=-1, type=click.UNPROCESSED)
24
+ @click.pass_context
25
+ def render_command(ctx, args):
26
+ """Draw a program as an SVG, PNG or PDF figure (needs Node.js).
27
+
28
+ \b
29
+ rhylthyme render dinner.json -o dinner.png --style web --palette vivid
30
+ rhylthyme render blot.json -o figure.pdf --style publication --legend right
31
+ rhylthyme render --help # every option
32
+ """
33
+ try:
34
+ from rhylthyme_timeline import main as render_main
35
+ except ImportError:
36
+ raise click.ClickException(INSTALL_HINT)
37
+ ctx.exit(render_main(list(args)))
38
+
39
+
40
+ def register(cli_group: click.Group) -> None:
41
+ cli_group.add_command(render_command)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rhylthyme-cli-runner
3
- Version: 0.2.4a0
3
+ Version: 0.2.5a0
4
4
  Summary: CLI runner for Rhylthyme real-time program schedules
5
5
  Home-page: https://github.com/rhylthyme/rhylthyme-cli-runner
6
6
  Author: Rhylthyme Team
@@ -64,7 +64,7 @@ Command-line interface for validating and running Rhylthyme real-time program sc
64
64
  and for turning a plain-language request into one through the hosted Rhylthyme MCP server.
65
65
 
66
66
  ```bash
67
- pip install rhylthyme-cli-runner
67
+ pip install rhylthyme
68
68
  rhylthyme login
69
69
  rhylthyme generate "roast chicken, potatoes and green beans for 6" -e kitchen --by 19:00 --with "one oven"
70
70
  ```
@@ -76,7 +76,7 @@ the oven, when do the balloons go up, and do the pizzas and the cake ever want
76
76
  the oven at the same time?
77
77
 
78
78
  ```bash
79
- pip install rhylthyme-cli-runner
79
+ pip install rhylthyme
80
80
 
81
81
  # 1. a program: the party, the kitchen and the setup crew, 13 steps
82
82
  curl -sO https://raw.githubusercontent.com/rhylthyme/rhylthyme-cli-runner/main/examples/recipe/birthday-party.json
@@ -117,8 +117,8 @@ Start Sat 12:50, finish Sat 16:00 (local time)
117
117
  # 4. a live timeline for the fridge door (or a phone): timers, cues, and you end the piñata when it breaks
118
118
  rhylthyme publish birthday-party.json --open --image party-preview.png
119
119
 
120
- # 5. a picture for the group chat, on the wall clock (needs Node; nothing to install)
121
- npx -y github:rhylthyme/rhylthyme-timeline birthday-party.json -o birthday-party.png \
120
+ # 5. a picture for the group chat, on the wall clock (needs Node.js)
121
+ rhylthyme render birthday-party.json -o birthday-party.png \
122
122
  --style web --palette vivid --label-overflow outside --start-at "$(date +%F)T12:50:00"
123
123
  ```
124
124
 
@@ -141,7 +141,7 @@ is the **server an AI assistant talks to**.
141
141
  |---|---|---|
142
142
  | What it is | The MCP **server**: the tools an AI assistant calls | A command-line **program**: the `rhylthyme` command |
143
143
  | Who uses it | Claude, ChatGPT, Cursor or any MCP client, on a person's behalf | A person at a terminal, a script, or CI |
144
- | Where it runs | Hosted at `mcp.rhylthyme.com`; nothing to install | On your machine: `pip install rhylthyme-cli-runner` |
144
+ | Where it runs | Hosted at `mcp.rhylthyme.com`; nothing to install | On your machine: `pip install rhylthyme` |
145
145
  | Language | JavaScript (Node 20+) | Python 3.12+ |
146
146
  | Input | A program the assistant builds in conversation | A program file on disk (JSON or YAML) |
147
147
  | Validate a program | `validate_program` | `rhylthyme validate` (works offline) |
@@ -189,7 +189,8 @@ pip install -e ".[dev]"
189
189
  ### From PyPI
190
190
 
191
191
  ```bash
192
- pip install rhylthyme-cli-runner
192
+ pip install rhylthyme # this package, the importers and the renderer
193
+ pip install rhylthyme-cli-runner # this package alone
193
194
  ```
194
195
 
195
196
  ## Getting the Examples
@@ -553,7 +554,7 @@ writes `<programId>.json`. Needs `rhylthyme-importers` (included in
553
554
  rhylthyme import https://www.seriouseats.com/the-best-chili-recipe # any of ~580 recipe sites
554
555
  rhylthyme import 52772 -i themealdb --publish # a TheMealDB id, straight to a live timeline
555
556
  rhylthyme import https://www.protocols.io/view/western-blot-... # needs PROTOCOLS_IO_TOKEN
556
- rhylthyme import protocol.py -o protocol.json # an Opentrons file
557
+ rhylthyme import https://raw.githubusercontent.com/Opentrons/Protocols/develop/protocols/007992/rna_isolation.ot2.apiv2.py # an Opentrons protocol
557
558
  rhylthyme import "Neapolitan Pizza.cook" -i cooklang
558
559
  rhylthyme importers # what is installed
559
560
  rhylthyme search "pad thai" -i spoonacular # then import a hit's URL
@@ -563,6 +564,17 @@ rhylthyme search "pad thai" -i spoonacular # then impo
563
564
  `--stdout`, `--publish` (and `--open`), `--no-validate`. `-` reads pasted
564
565
  source from stdin (with `-i`).
565
566
 
567
+ ### `rhylthyme render`
568
+
569
+ Draws a program as an SVG, PNG or PDF figure through the `rhylthyme-timeline`
570
+ package (included in `pip install rhylthyme`; needs Node.js 18+). Every
571
+ option of `rhylthyme-render` is accepted: `rhylthyme render --help`.
572
+
573
+ ```bash
574
+ rhylthyme render dinner.json -o dinner.png --style web --palette vivid --color-by task
575
+ rhylthyme render blot.json -o figure.pdf --style publication --legend right
576
+ ```
577
+
566
578
  ### `rhylthyme plan`
567
579
 
568
580
  An older stagger heuristic. It reads the pre-0.2 program format and leaves
@@ -12,6 +12,7 @@ src/rhylthyme_cli_runner/import_cli.py
12
12
  src/rhylthyme_cli_runner/instance_checks.py
13
13
  src/rhylthyme_cli_runner/program_planner.py
14
14
  src/rhylthyme_cli_runner/program_runner.py
15
+ src/rhylthyme_cli_runner/render_cli.py
15
16
  src/rhylthyme_cli_runner/validate_program.py
16
17
  src/rhylthyme_cli_runner.egg-info/PKG-INFO
17
18
  src/rhylthyme_cli_runner.egg-info/SOURCES.txt
@@ -74,6 +75,7 @@ tests/test_planner_time_strings.py
74
75
  tests/test_predict.py
75
76
  tests/test_program_runner.py
76
77
  tests/test_remote.py
78
+ tests/test_render_cli.py
77
79
  tests/test_replay.py
78
80
  tests/test_run_recorder.py
79
81
  tests/test_skill.py
@@ -226,3 +226,17 @@ def test_without_the_importers_package_the_message_says_how_to_get_it(monkeypatc
226
226
  monkeypatch.setitem(sys.modules, "rhylthyme_importers", None)
227
227
  r = CliRunner().invoke(cli, ["import", "https://fake.example/dinner"])
228
228
  assert r.exit_code != 0 and "pip install rhylthyme-importers" in r.output
229
+
230
+
231
+ def test_a_text_importer_gets_a_urls_body(fake, monkeypatch):
232
+ from rhylthyme_cli_runner.remote import cli as remote
233
+
234
+ monkeypatch.setattr(
235
+ remote, "_fetch_bytes", lambda url, limit=0: b"def run(protocol): pass\n"
236
+ )
237
+ fake.supported_domains = [] # a file/text importer, like Opentrons
238
+ r = CliRunner().invoke(
239
+ cli, ["import", "https://fake.example/protocol.py", "-i", "fake", "--stdout"]
240
+ )
241
+ assert r.exit_code == 0, r.output
242
+ assert fake.calls[-1] == ("text", "def run(protocol): pass\n", None)
@@ -0,0 +1,33 @@
1
+ """`rhylthyme render` hands its arguments to the rhylthyme-timeline package."""
2
+
3
+ import sys
4
+ import types
5
+
6
+ from click.testing import CliRunner
7
+
8
+ from rhylthyme_cli_runner.cli import cli
9
+
10
+
11
+ def test_arguments_pass_through_unchanged(monkeypatch):
12
+ seen = {}
13
+ module = types.ModuleType("rhylthyme_timeline")
14
+ module.main = lambda argv: seen.setdefault("argv", argv) and 0
15
+ monkeypatch.setitem(sys.modules, "rhylthyme_timeline", module)
16
+ r = CliRunner().invoke(
17
+ cli, ["render", "p.json", "-o", "p.png", "--style", "web", "--help"]
18
+ )
19
+ assert r.exit_code == 0, r.output
20
+ assert seen["argv"] == ["p.json", "-o", "p.png", "--style", "web", "--help"]
21
+
22
+
23
+ def test_exit_code_is_the_renderers(monkeypatch):
24
+ module = types.ModuleType("rhylthyme_timeline")
25
+ module.main = lambda argv: 2
26
+ monkeypatch.setitem(sys.modules, "rhylthyme_timeline", module)
27
+ assert CliRunner().invoke(cli, ["render", "p.json"]).exit_code == 2
28
+
29
+
30
+ def test_without_the_package_the_message_says_how_to_get_it(monkeypatch):
31
+ monkeypatch.setitem(sys.modules, "rhylthyme_timeline", None)
32
+ r = CliRunner().invoke(cli, ["render", "p.json"])
33
+ assert r.exit_code != 0 and "pip install rhylthyme-timeline" in r.output