roadmodel 0.2.44__tar.gz → 0.2.45__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 (49) hide show
  1. {roadmodel-0.2.44 → roadmodel-0.2.45}/PKG-INFO +9 -9
  2. {roadmodel-0.2.44 → roadmodel-0.2.45}/README.md +8 -8
  3. {roadmodel-0.2.44 → roadmodel-0.2.45}/pyproject.toml +1 -1
  4. {roadmodel-0.2.44 → roadmodel-0.2.45}/scripts/update_projects.py +58 -8
  5. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/__init__.py +1 -1
  6. {roadmodel-0.2.44 → roadmodel-0.2.45}/.gitignore +0 -0
  7. {roadmodel-0.2.44 → roadmodel-0.2.45}/LICENSE +0 -0
  8. {roadmodel-0.2.44 → roadmodel-0.2.45}/NOTICE +0 -0
  9. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/benchmarks.json +0 -0
  10. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/catalog.json +0 -0
  11. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/model-selector.txt +0 -0
  12. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/model-tier-cost-scale.md +0 -0
  13. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/settings-display.md +0 -0
  14. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/templates/phase-roadmap-template.md +0 -0
  15. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/templates/planning-kit-how-to-use.md +0 -0
  16. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/templates/project-roadmap-template.md +0 -0
  17. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/templates/prompt-phase-roadmap.md +0 -0
  18. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/templates/prompt-project-roadmap.md +0 -0
  19. {roadmodel-0.2.44 → roadmodel-0.2.45}/docs/user-context.example.md +0 -0
  20. {roadmodel-0.2.44 → roadmodel-0.2.45}/hatch_build.py +0 -0
  21. {roadmodel-0.2.44 → roadmodel-0.2.45}/infra/README.md +0 -0
  22. {roadmodel-0.2.44 → roadmodel-0.2.45}/infra/gcp-killswitch/README.md +0 -0
  23. {roadmodel-0.2.44 → roadmodel-0.2.45}/infra/supabase/README.md +0 -0
  24. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/benchmarks.json +0 -0
  25. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/catalog.json +0 -0
  26. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/model-selector.txt +0 -0
  27. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/model-tier-cost-scale.md +0 -0
  28. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/phase-roadmap-template.md +0 -0
  29. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/planning-kit-how-to-use.md +0 -0
  30. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/project-roadmap-template.md +0 -0
  31. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/prompt-phase-roadmap.md +0 -0
  32. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/prompt-project-roadmap.md +0 -0
  33. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/settings-display.md +0 -0
  34. {roadmodel-0.2.44 → roadmodel-0.2.45}/roadmodel/data/user-context.example.md +0 -0
  35. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/__main__.py +0 -0
  36. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/cli.py +0 -0
  37. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/config.py +0 -0
  38. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/cost.py +0 -0
  39. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/errors.py +0 -0
  40. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/mcp_server.py +0 -0
  41. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/providers/__init__.py +0 -0
  42. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/providers/anthropic.py +0 -0
  43. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/providers/google.py +0 -0
  44. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/providers/openai.py +0 -0
  45. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/providers/openai_compatible.py +0 -0
  46. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/providers/registry.py +0 -0
  47. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/recommend.py +0 -0
  48. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/scoring.py +0 -0
  49. {roadmodel-0.2.44 → roadmodel-0.2.45}/src/roadmodel/user_context.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: roadmodel
3
- Version: 0.2.44
3
+ Version: 0.2.45
4
4
  Summary: BYO-key CLI that recommends the right AI model, platform, and settings for a prompt.
5
5
  Project-URL: Homepage, https://roadmodel.ai
6
6
  Project-URL: Repository, https://github.com/nathanramoscfa/roadmodel
@@ -323,7 +323,7 @@ What the loop guarantees, independent of the project:
323
323
  and a step that touches a deployed surface is done at post-deploy
324
324
  verification, not at merge.
325
325
 
326
- Setup is once per machine (`/roadmodel-update` keeps every project's
326
+ Setup is once per machine (`/roadmodel-upgrade` keeps every project's
327
327
  copy current after that); the commands then work in any project.
328
328
  Step-by-step: [docs/planning-workflow.md](docs/planning-workflow.md).
329
329
 
@@ -360,15 +360,15 @@ pip install -U roadmodel
360
360
  **then** `roadmodel export-kit . --force` to refresh it. The `/roadmap-project`
361
361
  and `/roadmap-phase` commands do both as their Step 0.
362
362
 
363
- ### Every project on a machine — `/roadmodel-update`
363
+ ### Every project on a machine — `/roadmodel-upgrade`
364
364
 
365
365
  Projects that each carry roadmodel in their **own** conda env or venv would
366
366
  otherwise be upgraded one at a time. Instead, from any Claude Code chat:
367
367
 
368
368
  ```
369
- /roadmodel-update # every registered project
370
- /roadmodel-update ~/code/app-one … # register these dirs, then run
371
- /roadmodel-update --install-schedule # once: also run daily, unattended
369
+ /roadmodel-upgrade # every registered project
370
+ /roadmodel-upgrade ~/code/app-one … # register these dirs, then run
371
+ /roadmodel-upgrade --install-schedule # once: also run daily, unattended
372
372
  ```
373
373
 
374
374
  The command fetches [`scripts/update_projects.py`](scripts/update_projects.py)
@@ -446,14 +446,14 @@ hand; the `export-kit` command above avoids that entirely.
446
446
  `docs/claude-commands/` — `/roadmap-project`, `/roadmap-phase N`,
447
447
  `/roadmap-step P M` (executes a step), `/roadmap-refresh` (bookkeeping
448
448
  only: marks shipped steps and re-selects upcoming Settings, runs
449
- nothing), `/roadmodel-update` — see
449
+ nothing), `/roadmodel-upgrade` — see
450
450
  [The planning workflow](#the-planning-workflow) above for the loop and
451
451
  [docs/planning-workflow.md](docs/planning-workflow.md) for setup and
452
452
  per-command detail. The same five are generated for **Gemini CLI**
453
453
  (`~/.gemini/commands/*.toml`), **Codex** and **Cursor** (one
454
454
  `~/.agents/skills/*/SKILL.md` both read; `$roadmap-step` in Codex,
455
455
  `/roadmap-step` in Cursor), and **OpenCode**
456
- (`~/.config/opencode/commands/*.md`), installed by `/roadmodel-update`
456
+ (`~/.config/opencode/commands/*.md`), installed by `/roadmodel-upgrade`
457
457
  wherever those tools are present.
458
458
 
459
459
  Either way the in-editor AI runs the algorithm itself rather than calling
@@ -582,7 +582,7 @@ provider goes down, or a task suits a different model?
582
582
  (instructions, memory, skills, slash commands, MCP servers, model, effort,
583
583
  permissions) across Claude, Codex, Gemini and open-source clients in any
584
584
  direction, and carries one parameterised prompt that makes the target agent
585
- sync itself. `roadmodel-update` keeps the roadmap commands, the roadmodel MCP
585
+ sync itself. `roadmodel-upgrade` keeps the roadmap commands, the roadmodel MCP
586
586
  server and the reasoning-effort default in parity automatically.
587
587
 
588
588
  ## Subcommands
@@ -73,7 +73,7 @@ What the loop guarantees, independent of the project:
73
73
  and a step that touches a deployed surface is done at post-deploy
74
74
  verification, not at merge.
75
75
 
76
- Setup is once per machine (`/roadmodel-update` keeps every project's
76
+ Setup is once per machine (`/roadmodel-upgrade` keeps every project's
77
77
  copy current after that); the commands then work in any project.
78
78
  Step-by-step: [docs/planning-workflow.md](docs/planning-workflow.md).
79
79
 
@@ -110,15 +110,15 @@ pip install -U roadmodel
110
110
  **then** `roadmodel export-kit . --force` to refresh it. The `/roadmap-project`
111
111
  and `/roadmap-phase` commands do both as their Step 0.
112
112
 
113
- ### Every project on a machine — `/roadmodel-update`
113
+ ### Every project on a machine — `/roadmodel-upgrade`
114
114
 
115
115
  Projects that each carry roadmodel in their **own** conda env or venv would
116
116
  otherwise be upgraded one at a time. Instead, from any Claude Code chat:
117
117
 
118
118
  ```
119
- /roadmodel-update # every registered project
120
- /roadmodel-update ~/code/app-one … # register these dirs, then run
121
- /roadmodel-update --install-schedule # once: also run daily, unattended
119
+ /roadmodel-upgrade # every registered project
120
+ /roadmodel-upgrade ~/code/app-one … # register these dirs, then run
121
+ /roadmodel-upgrade --install-schedule # once: also run daily, unattended
122
122
  ```
123
123
 
124
124
  The command fetches [`scripts/update_projects.py`](scripts/update_projects.py)
@@ -196,14 +196,14 @@ hand; the `export-kit` command above avoids that entirely.
196
196
  `docs/claude-commands/` — `/roadmap-project`, `/roadmap-phase N`,
197
197
  `/roadmap-step P M` (executes a step), `/roadmap-refresh` (bookkeeping
198
198
  only: marks shipped steps and re-selects upcoming Settings, runs
199
- nothing), `/roadmodel-update` — see
199
+ nothing), `/roadmodel-upgrade` — see
200
200
  [The planning workflow](#the-planning-workflow) above for the loop and
201
201
  [docs/planning-workflow.md](docs/planning-workflow.md) for setup and
202
202
  per-command detail. The same five are generated for **Gemini CLI**
203
203
  (`~/.gemini/commands/*.toml`), **Codex** and **Cursor** (one
204
204
  `~/.agents/skills/*/SKILL.md` both read; `$roadmap-step` in Codex,
205
205
  `/roadmap-step` in Cursor), and **OpenCode**
206
- (`~/.config/opencode/commands/*.md`), installed by `/roadmodel-update`
206
+ (`~/.config/opencode/commands/*.md`), installed by `/roadmodel-upgrade`
207
207
  wherever those tools are present.
208
208
 
209
209
  Either way the in-editor AI runs the algorithm itself rather than calling
@@ -332,7 +332,7 @@ provider goes down, or a task suits a different model?
332
332
  (instructions, memory, skills, slash commands, MCP servers, model, effort,
333
333
  permissions) across Claude, Codex, Gemini and open-source clients in any
334
334
  direction, and carries one parameterised prompt that makes the target agent
335
- sync itself. `roadmodel-update` keeps the roadmap commands, the roadmodel MCP
335
+ sync itself. `roadmodel-upgrade` keeps the roadmap commands, the roadmodel MCP
336
336
  server and the reasoning-effort default in parity automatically.
337
337
 
338
338
  ## Subcommands
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "roadmodel"
7
- version = "0.2.44"
7
+ version = "0.2.45"
8
8
  description = "BYO-key CLI that recommends the right AI model, platform, and settings for a prompt."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -56,8 +56,12 @@ COMMANDS = (
56
56
  "roadmap-phase",
57
57
  "roadmap-step",
58
58
  "roadmap-refresh",
59
- "roadmodel-update",
59
+ "roadmodel-upgrade",
60
60
  )
61
+ # Commands this updater once installed under a name it no longer uses. Every
62
+ # run removes its own copies of them for every agent; a user's own command of
63
+ # the same name is left alone.
64
+ RETIRED_COMMANDS = ("roadmodel-update",) # renamed roadmodel-upgrade in 0.2.45
61
65
  CONFIG_DIR = Path.home() / ".config" / "roadmodel"
62
66
  DEFAULT_PROJECTS_FILE = CONFIG_DIR / "projects.txt"
63
67
  CLAUDE_DIR = Path.home() / ".claude"
@@ -789,7 +793,7 @@ def _sync_antigravity_trust(projects: list[Path], dry_run: bool) -> list[str]:
789
793
  ``trustedWorkspaces`` in its own settings file — NOT in the legacy CLI's
790
794
  ``trustedFolders.json``, which it never reads. A project missing from this
791
795
  list is one the operator has to approve by hand on first open, which is
792
- exactly the friction `roadmodel-update` exists to remove when a machine
796
+ exactly the friction `roadmodel-upgrade` exists to remove when a machine
793
797
  carries seven or eight active projects."""
794
798
  if not projects:
795
799
  return []
@@ -956,6 +960,8 @@ def sync_agent_runtime(
956
960
  # --------------------------------------------------------------------------
957
961
 
958
962
  AGENTS_MEMORY_REL = Path(".agents") / "memory.md"
963
+ # Keeps the updater's old name: an existing memory file is overwritten only
964
+ # when it starts with this exact line.
959
965
  _MEMORY_HEADER = "<!-- generated by roadmodel-update from Claude Code auto-memory -->"
960
966
  # A whole memory directory can be 400 KB (~100k tokens) — a context bomb for an
961
967
  # agent that reads the file at session start, and most of it is the long tail.
@@ -1004,7 +1010,7 @@ def export_claude_memory(project: Path) -> Optional[str]:
1004
1010
  "",
1005
1011
  "Durable facts about this project, carried over from Claude Code's",
1006
1012
  "auto-memory so every agent starts from the same knowledge. Local only:",
1007
- "this file is git-excluded and is regenerated by `roadmodel-update`.",
1013
+ "this file is git-excluded and is regenerated by `roadmodel-upgrade`.",
1008
1014
  "",
1009
1015
  ]
1010
1016
  if index_text:
@@ -1044,7 +1050,7 @@ def _git_exclude(project: Path, pattern: str, dry_run: bool) -> bool:
1044
1050
  if not dry_run:
1045
1051
  info.mkdir(parents=True, exist_ok=True)
1046
1052
  body = existing.rstrip("\n")
1047
- block = "# roadmodel-update: agent memory export (personal, never commit)"
1053
+ block = "# roadmodel-upgrade: agent memory export (personal, never commit)"
1048
1054
  exclude.write_text(
1049
1055
  (body + "\n\n" if body else "") + block + "\n" + pattern + "\n", encoding="utf-8"
1050
1056
  )
@@ -1078,7 +1084,7 @@ def _agents_md(project: Path) -> str:
1078
1084
  f"If [`{AGENTS_MEMORY_REL.as_posix()}`]({AGENTS_MEMORY_REL.as_posix()}) exists, read it at the",
1079
1085
  "start of a session: it carries the durable facts about this project that",
1080
1086
  "Claude Code's auto-memory holds — decisions, conventions, gotchas. It is",
1081
- "local-only (git-excluded) and regenerated by `roadmodel-update`, so it may be",
1087
+ "local-only (git-excluded) and regenerated by `roadmodel-upgrade`, so it may be",
1082
1088
  "absent on a fresh clone; that is expected.",
1083
1089
  "",
1084
1090
  "It is git-excluded, so a file-reading tool that honours ignore rules will",
@@ -1087,10 +1093,13 @@ def _agents_md(project: Path) -> str:
1087
1093
  "",
1088
1094
  "## Commands",
1089
1095
  "",
1090
- "`roadmap-project`, `roadmap-phase`, `roadmap-step` and `roadmodel-update` are",
1091
- "installed for every agent on this machine (Codex: `/prompts:roadmap-phase 1`;",
1092
- "elsewhere: `/roadmap-phase 1`). See docs/agent-parity.md in the roadmodel repo.",
1096
+ "`roadmap-project`, `roadmap-phase`, `roadmap-step`, `roadmap-refresh` and",
1097
+ "`roadmodel-upgrade` are installed for every agent on this machine (Codex:",
1098
+ "`/prompts:roadmap-phase 1`; elsewhere: `/roadmap-phase 1`). See",
1099
+ "docs/agent-parity.md in the roadmodel repo.",
1093
1100
  "",
1101
+ # The marker keeps the updater's old name: /roadmap-step and
1102
+ # /roadmap-refresh recognise the file by this exact line.
1094
1103
  "<!-- Created once by roadmodel-update. Edit freely: it is never overwritten. -->",
1095
1104
  ]
1096
1105
  return "\n".join(lines) + "\n"
@@ -1194,6 +1203,47 @@ def refresh_commands(dry_run: bool = False, agents: Optional[list[str]] = None)
1194
1203
  target = OPENCODE_DIR / "commands" / f"{name}.md"
1195
1204
  states.append(f"opencode {_install(target, cmd_md, dry_run)}")
1196
1205
  report.append(f"{name}: " + " · ".join(states))
1206
+ return report + retire_commands(dry_run)
1207
+
1208
+
1209
+ def _command_files(name: str) -> list[Path]:
1210
+ """Every file refresh_commands can install for ``name``, for every agent."""
1211
+ files = [
1212
+ CLAUDE_DIR / "commands" / f"{name}.md",
1213
+ CLAUDE_DIR / "skills" / name / "SKILL.md",
1214
+ GEMINI_DIR / "commands" / f"{name}.toml",
1215
+ ANTIGRAVITY_SKILLS_DIR / name / "SKILL.md",
1216
+ CODEX_DIR / "prompts" / f"{name}.md",
1217
+ AGENTS_SKILLS_DIR / name / "SKILL.md",
1218
+ CODEX_LEGACY_SKILLS_DIR / name / "SKILL.md",
1219
+ OPENCODE_DIR / "commands" / f"{name}.md",
1220
+ ]
1221
+ return files + [d / "prompts" / f"{name}.prompt.md" for d in _vscode_user_dirs()]
1222
+
1223
+
1224
+ def retire_commands(dry_run: bool = False) -> list[str]:
1225
+ """Remove this updater's copies of RETIRED_COMMANDS. A copy is ours when it
1226
+ carries the updater's filename, which every port of a command body does."""
1227
+ report: list[str] = []
1228
+ for name in RETIRED_COMMANDS:
1229
+ removed = 0
1230
+ for path in _command_files(name):
1231
+ try:
1232
+ ours = path.is_file() and "update_projects.py" in path.read_text(encoding="utf-8")
1233
+ except (OSError, UnicodeDecodeError):
1234
+ ours = False
1235
+ if not ours:
1236
+ continue
1237
+ removed += 1
1238
+ if not dry_run:
1239
+ path.unlink()
1240
+ if path.name == "SKILL.md":
1241
+ with contextlib.suppress(OSError):
1242
+ path.parent.rmdir()
1243
+ if removed:
1244
+ report.append(
1245
+ f"{name}: retired — removed {removed} old cop{'y' if removed == 1 else 'ies'}"
1246
+ )
1197
1247
  return report
1198
1248
 
1199
1249
 
@@ -1,2 +1,2 @@
1
1
  # src/roadmodel/__init__.py
2
- __version__ = "0.2.44"
2
+ __version__ = "0.2.45"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes