boost-skill-cli 1.0.43__tar.gz → 1.0.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 (110) hide show
  1. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/output.py +9 -0
  4. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  5. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
  6. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/design-roadmap.html +3 -3
  7. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_output.py +30 -0
  8. boost_skill_cli-1.0.45/tests/unit/test_token_parity.py +32 -0
  9. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/.gitignore +0 -0
  10. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/CLAUDE.md +0 -0
  11. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/CONTRIBUTING.md +0 -0
  12. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/LICENSE +0 -0
  13. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/MANIFEST.in +0 -0
  14. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/Makefile +0 -0
  15. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/README.md +0 -0
  16. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/SECURITY.md +0 -0
  17. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost +0 -0
  18. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/__init__.py +0 -0
  19. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/__main__.py +0 -0
  20. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/cli.py +0 -0
  21. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/cliparse.py +0 -0
  22. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/__init__.py +0 -0
  23. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/bmad.py +0 -0
  24. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/configuration.py +0 -0
  25. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/discovery.py +0 -0
  26. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/hooks.py +0 -0
  27. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/info.py +0 -0
  28. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/intelligence.py +0 -0
  29. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/pkg.py +0 -0
  30. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/quality.py +0 -0
  31. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/taps.py +0 -0
  32. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/commands/team.py +0 -0
  33. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/__init__.py +0 -0
  34. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/agents.py +0 -0
  35. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/ai.py +0 -0
  36. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/catalog.py +0 -0
  37. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/claude_settings.py +0 -0
  38. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/config.py +0 -0
  39. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/dense.py +0 -0
  40. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/embed.py +0 -0
  41. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/frontmatter.py +0 -0
  42. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/gitutil.py +0 -0
  43. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/journal.py +0 -0
  44. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/lockfile.py +0 -0
  45. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/logs.py +0 -0
  46. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/paths.py +0 -0
  47. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/policy.py +0 -0
  48. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/rag.py +0 -0
  49. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/registry.py +0 -0
  50. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/store.py +0 -0
  51. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/core/util.py +0 -0
  52. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/data/registries.json +0 -0
  53. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/errors.py +0 -0
  54. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_cli/spin.py +0 -0
  55. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  56. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  57. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_skill_cli.egg-info/requires.txt +0 -0
  58. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/boost_skill_cli.egg-info/top_level.txt +0 -0
  59. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/.claude/settings.local.json +0 -0
  60. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/DEBUGGING.md +0 -0
  61. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/demo.gif +0 -0
  62. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/demo.tape +0 -0
  63. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/index.html +0 -0
  64. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/rag-architecture.md +0 -0
  65. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/docs/roadmap.html +0 -0
  66. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/pyproject.toml +0 -0
  67. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/scripts/build_registries.py +0 -0
  68. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/scripts/mutation_gate.py +0 -0
  69. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/setup.cfg +0 -0
  70. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/style/README.md +0 -0
  71. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/style/boost.css +0 -0
  72. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/style/boost.js +0 -0
  73. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/style/demo.html +0 -0
  74. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/conftest.py +0 -0
  75. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_bmad.py +0 -0
  76. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_configuration.py +0 -0
  77. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_discovery.py +0 -0
  78. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_hooks.py +0 -0
  79. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_info.py +0 -0
  80. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_intelligence.py +0 -0
  81. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_pkg.py +0 -0
  82. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_quality.py +0 -0
  83. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_taps.py +0 -0
  84. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_cli_team.py +0 -0
  85. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/functional/test_everyday_loop.py +0 -0
  86. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/make_fixture.py +0 -0
  87. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/smoke.sh +0 -0
  88. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_agents.py +0 -0
  89. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_ai.py +0 -0
  90. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_catalog.py +0 -0
  91. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_claude_settings.py +0 -0
  92. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_cliparse.py +0 -0
  93. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_config.py +0 -0
  94. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_dense.py +0 -0
  95. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_embed.py +0 -0
  96. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_errors_and_cli_table.py +0 -0
  97. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_frontmatter.py +0 -0
  98. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_gitutil.py +0 -0
  99. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_journal.py +0 -0
  100. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_lockfile.py +0 -0
  101. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_logs.py +0 -0
  102. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_mutation_hardening.py +0 -0
  103. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_paths.py +0 -0
  104. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_policy.py +0 -0
  105. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_rag.py +0 -0
  106. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_registry.py +0 -0
  107. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_spin.py +0 -0
  108. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_store.py +0 -0
  109. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_util.py +0 -0
  110. {boost_skill_cli-1.0.43 → boost_skill_cli-1.0.45}/tests/unit/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.43
3
+ Version: 1.0.45
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.0.43'
22
- __version_tuple__ = version_tuple = (1, 0, 43)
21
+ __version__ = version = '1.0.45'
22
+ __version_tuple__ = version_tuple = (1, 0, 45)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -26,6 +26,15 @@ CYAN = "\033[36m"
26
26
 
27
27
 
28
28
  def use_color(stream=None) -> bool:
29
+ # BOOST_COLOR is boost's own explicit override and wins over everything
30
+ # else (most-specific-wins): always/never force it on/off regardless of
31
+ # NO_COLOR, CLICOLOR_FORCE or the TTY check. Anything else (incl. "auto")
32
+ # falls through to the standard detection below.
33
+ override = os.environ.get("BOOST_COLOR", "").lower()
34
+ if override in ("never", "off", "0"):
35
+ return False
36
+ if override in ("always", "force", "1"):
37
+ return True
29
38
  if os.environ.get("NO_COLOR"):
30
39
  return False
31
40
  if os.environ.get("CLICOLOR_FORCE"):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.43
3
+ Version: 1.0.45
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -104,5 +104,6 @@ tests/unit/test_rag.py
104
104
  tests/unit/test_registry.py
105
105
  tests/unit/test_spin.py
106
106
  tests/unit/test_store.py
107
+ tests/unit/test_token_parity.py
107
108
  tests/unit/test_util.py
108
109
  tests/unit/test_version.py
@@ -239,7 +239,7 @@
239
239
  </article>
240
240
 
241
241
  <article class="ritem" data-track="color" data-impact="high">
242
- <div class="ritem-top"><span class="rid">BOOST-D02</span><span class="rstatus progress">In progress</span></div>
242
+ <div class="ritem-top"><span class="rid">BOOST-D02</span><span class="rstatus done">Shipped</span></div>
243
243
  <h4>Terminal capability detection &amp; graceful degradation</h4>
244
244
  <p><code>use_color()</code> is binary — color or nothing. Add a tier ladder: <b>truecolor</b> (<code>COLORTERM=truecolor/24bit</code>) → <b>256</b> → <b>16</b> → <b>none</b>, so the Aurora tokens snap to the nearest available color instead of vanishing. Keep the existing <code>NO_COLOR</code> honor, add a <code>BOOST_COLOR=always/auto/never</code> override, and treat <code>TERM=dumb</code> as none.</p>
245
245
  <div class="rmeta"><span class="m-cat">color</span><span>Complexity M</span><span class="m-imp high">Impact High</span><span class="m-wow">★★★☆☆</span></div>
@@ -467,9 +467,9 @@
467
467
  </article>
468
468
 
469
469
  <article class="ritem" data-track="system" data-impact="med">
470
- <div class="ritem-top"><span class="rid">BOOST-D20</span><span class="rstatus progress">In progress</span></div>
470
+ <div class="ritem-top"><span class="rid">BOOST-D20</span><span class="rstatus done">Shipped</span></div>
471
471
  <h4>Single source of design tokens (web ↔ CLI)</h4>
472
- <p><b>Done:</b> the CLI palette is now single-sourced — one <code>output.TOKENS</code> dict holds every Aurora RGB triple, and the gradient, brand tints and badges all <em>derive</em> from it (previously cyan/violet/pink were re-typed across <code>_AURORA</code> and <code>_GRAD_STOPS</code>). A test locks the contract so a stray hex can't drift. <b>Remaining:</b> lift <code>TOKENS</code> into a shared <code>tokens.json</code> and generate <em>both</em> the CSS custom properties and this map from it, so the site and the terminal move in lockstep (the repo's "generate, never hand-edit" pattern, cf. <code>build_registries.py</code>).</p>
472
+ <p><b>Done:</b> the CLI palette is now single-sourced — one <code>output.TOKENS</code> dict holds every Aurora RGB triple, and the gradient, brand tints and badges all <em>derive</em> from it (previously cyan/violet/pink were re-typed across <code>_AURORA</code> and <code>_GRAD_STOPS</code>). A test locks the contract so a stray hex can't drift. <b>Remaining:</b> lift <code>TOKENS</code> into a shared <code>tokens.json</code> and generate <em>both</em> the CSS custom properties and this map from it, so the site and the terminal move in lockstep. <b>Shipped as enforcement instead of generation:</b> a unit test parses <code>style/boost.css</code> and asserts every <code>--token</code> matches <code>output.TOKENS</code>, so a hex changed in one place and not the other fails CI — the same guarantee without rewriting the hand-authored stylesheet.</p>
473
473
  <div class="rmeta"><span class="m-cat">system</span><span>Complexity M</span><span class="m-imp med">Impact Med</span><span class="m-wow">★★★★☆</span></div>
474
474
  <div class="rref"><code>core/output.py TOKENS · style/boost.css · future build_tokens.py</code></div>
475
475
  </article>
@@ -14,6 +14,7 @@ def clean_env(monkeypatch):
14
14
  """Neutral color/confirm environment; each test opts in explicitly."""
15
15
  monkeypatch.delenv("NO_COLOR", raising=False)
16
16
  monkeypatch.delenv("CLICOLOR_FORCE", raising=False)
17
+ monkeypatch.delenv("BOOST_COLOR", raising=False)
17
18
  monkeypatch.delenv("BOOST_ASSUME_YES", raising=False)
18
19
  monkeypatch.setattr(sys, "argv", ["boost"])
19
20
 
@@ -46,6 +47,35 @@ class TestUseColor:
46
47
  def test_tty_true(self):
47
48
  assert output.use_color(FakeStream(tty=True)) is True
48
49
 
50
+ def test_boost_color_never_beats_clicolor_force(self, monkeypatch):
51
+ monkeypatch.setenv("BOOST_COLOR", "never")
52
+ monkeypatch.setenv("CLICOLOR_FORCE", "1")
53
+ assert output.use_color(FakeStream(tty=True)) is False
54
+
55
+ def test_boost_color_always_beats_no_color(self, monkeypatch):
56
+ monkeypatch.setenv("BOOST_COLOR", "always")
57
+ monkeypatch.setenv("NO_COLOR", "1")
58
+ assert output.use_color(FakeStream(tty=False)) is True
59
+
60
+ def test_boost_color_off_alias(self, monkeypatch):
61
+ monkeypatch.setenv("BOOST_COLOR", "off")
62
+ assert output.use_color(FakeStream(tty=True)) is False
63
+
64
+ def test_boost_color_auto_falls_through_to_tty(self, monkeypatch):
65
+ monkeypatch.setenv("BOOST_COLOR", "auto")
66
+ assert output.use_color(FakeStream(tty=True)) is True
67
+ assert output.use_color(FakeStream(tty=False)) is False
68
+
69
+ def test_boost_color_all_off_aliases(self, monkeypatch):
70
+ for val in ("never", "off", "0"):
71
+ monkeypatch.setenv("BOOST_COLOR", val)
72
+ assert output.use_color(FakeStream(tty=True)) is False, val
73
+
74
+ def test_boost_color_all_on_aliases(self, monkeypatch):
75
+ for val in ("always", "force", "1"):
76
+ monkeypatch.setenv("BOOST_COLOR", val)
77
+ assert output.use_color(FakeStream(tty=False)) is True, val
78
+
49
79
  def test_stream_without_isatty_false(self):
50
80
  assert output.use_color(object()) is False
51
81
 
@@ -0,0 +1,32 @@
1
+ """Web ↔ CLI palette lockstep (BOOST-D20).
2
+
3
+ Enforces that the CLI's single source of truth, ``output.TOKENS``, stays in
4
+ lockstep with the web design system's tokens in ``style/boost.css``. If a hex
5
+ is changed in one place and not the other, this test fails.
6
+
7
+ Skips when ``style/boost.css`` isn't reachable (e.g. the mutation sandbox,
8
+ which only copies ``boost_cli/``).
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import re
13
+ from pathlib import Path
14
+
15
+ import pytest
16
+
17
+ from boost_cli.core import output
18
+
19
+ _CSS = Path(__file__).resolve().parents[2] / "style" / "boost.css"
20
+
21
+
22
+ @pytest.mark.skipif(not _CSS.exists(),
23
+ reason="style/boost.css not reachable (e.g. mutation sandbox)")
24
+ def test_cli_tokens_match_style_css():
25
+ text = _CSS.read_text()
26
+ for name, rgb in output.TOKENS.items():
27
+ m = re.search(r"--%s:\s*#([0-9a-fA-F]{6})" % name, text)
28
+ assert m, "style/boost.css is missing a --%s token" % name
29
+ css_rgb = tuple(int(m.group(1)[i:i + 2], 16) for i in (0, 2, 4))
30
+ assert css_rgb == rgb, (
31
+ "palette drift: output.TOKENS[%r]=%r but style/boost.css --%s=#%s"
32
+ % (name, rgb, name, m.group(1)))
File without changes