boost-skill-cli 1.0.36__tar.gz → 1.0.38__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 (107) hide show
  1. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/output.py +14 -4
  4. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  5. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/design-roadmap.html +2 -2
  6. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/index.html +11 -3
  7. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_output.py +21 -0
  8. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/.gitignore +0 -0
  9. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/CLAUDE.md +0 -0
  10. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/CONTRIBUTING.md +0 -0
  11. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/LICENSE +0 -0
  12. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/MANIFEST.in +0 -0
  13. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/Makefile +0 -0
  14. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/README.md +0 -0
  15. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/SECURITY.md +0 -0
  16. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost +0 -0
  17. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/__init__.py +0 -0
  18. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/__main__.py +0 -0
  19. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/cli.py +0 -0
  20. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/cliparse.py +0 -0
  21. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/__init__.py +0 -0
  22. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/bmad.py +0 -0
  23. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/configuration.py +0 -0
  24. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/discovery.py +0 -0
  25. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/hooks.py +0 -0
  26. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/info.py +0 -0
  27. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/intelligence.py +0 -0
  28. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/pkg.py +0 -0
  29. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/quality.py +0 -0
  30. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/taps.py +0 -0
  31. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/commands/team.py +0 -0
  32. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/__init__.py +0 -0
  33. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/agents.py +0 -0
  34. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/ai.py +0 -0
  35. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/catalog.py +0 -0
  36. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/claude_settings.py +0 -0
  37. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/config.py +0 -0
  38. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/dense.py +0 -0
  39. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/embed.py +0 -0
  40. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/frontmatter.py +0 -0
  41. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/gitutil.py +0 -0
  42. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/journal.py +0 -0
  43. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/lockfile.py +0 -0
  44. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/logs.py +0 -0
  45. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/paths.py +0 -0
  46. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/policy.py +0 -0
  47. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/rag.py +0 -0
  48. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/registry.py +0 -0
  49. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/store.py +0 -0
  50. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/core/util.py +0 -0
  51. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/data/registries.json +0 -0
  52. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_cli/errors.py +0 -0
  53. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_skill_cli.egg-info/SOURCES.txt +0 -0
  54. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  55. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  56. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_skill_cli.egg-info/requires.txt +0 -0
  57. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/boost_skill_cli.egg-info/top_level.txt +0 -0
  58. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/.claude/settings.local.json +0 -0
  59. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/DEBUGGING.md +0 -0
  60. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/demo.gif +0 -0
  61. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/demo.tape +0 -0
  62. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/rag-architecture.md +0 -0
  63. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/docs/roadmap.html +0 -0
  64. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/pyproject.toml +0 -0
  65. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/scripts/build_registries.py +0 -0
  66. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/scripts/mutation_gate.py +0 -0
  67. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/setup.cfg +0 -0
  68. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/style/README.md +0 -0
  69. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/style/boost.css +0 -0
  70. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/style/boost.js +0 -0
  71. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/style/demo.html +0 -0
  72. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/conftest.py +0 -0
  73. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_bmad.py +0 -0
  74. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_configuration.py +0 -0
  75. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_discovery.py +0 -0
  76. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_hooks.py +0 -0
  77. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_info.py +0 -0
  78. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_intelligence.py +0 -0
  79. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_pkg.py +0 -0
  80. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_quality.py +0 -0
  81. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_taps.py +0 -0
  82. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_cli_team.py +0 -0
  83. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/functional/test_everyday_loop.py +0 -0
  84. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/make_fixture.py +0 -0
  85. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/smoke.sh +0 -0
  86. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_agents.py +0 -0
  87. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_ai.py +0 -0
  88. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_catalog.py +0 -0
  89. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_claude_settings.py +0 -0
  90. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_cliparse.py +0 -0
  91. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_config.py +0 -0
  92. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_dense.py +0 -0
  93. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_embed.py +0 -0
  94. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_errors_and_cli_table.py +0 -0
  95. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_frontmatter.py +0 -0
  96. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_gitutil.py +0 -0
  97. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_journal.py +0 -0
  98. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_lockfile.py +0 -0
  99. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_logs.py +0 -0
  100. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_mutation_hardening.py +0 -0
  101. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_paths.py +0 -0
  102. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_policy.py +0 -0
  103. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_rag.py +0 -0
  104. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_registry.py +0 -0
  105. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_store.py +0 -0
  106. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/tests/unit/test_util.py +0 -0
  107. {boost_skill_cli-1.0.36 → boost_skill_cli-1.0.38}/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.36
3
+ Version: 1.0.38
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.36'
22
- __version_tuple__ = version_tuple = (1, 0, 36)
21
+ __version__ = version = '1.0.38'
22
+ __version_tuple__ = version_tuple = (1, 0, 38)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -272,19 +272,29 @@ def kv(key: str, value: str, width: int = 14) -> None:
272
272
  print(" " + c(key.ljust(width), DIM) + str(value))
273
273
 
274
274
 
275
+ def _pad(cell: str, width: int) -> str:
276
+ """Left-justify by *visible* width, so ANSI-colored cells still align
277
+ (str.ljust counts the invisible escape bytes and under-pads)."""
278
+ return cell + " " * (width - visible_len(cell))
279
+
280
+
275
281
  def table(rows, headers=None) -> None:
276
- """Print an aligned table. rows: list of tuples of strings."""
282
+ """Print an aligned table. rows: list of tuples of strings.
283
+
284
+ Column widths are measured by visible width (ignoring ANSI color codes),
285
+ so colored cells line up the same as plain ones.
286
+ """
277
287
  rows = [[str(x) for x in r] for r in rows]
278
288
  all_rows = ([list(map(str, headers))] if headers else []) + rows
279
289
  if not all_rows:
280
290
  return
281
- widths = [max(len(r[i]) for r in all_rows if i < len(r))
291
+ widths = [max(visible_len(r[i]) for r in all_rows if i < len(r))
282
292
  for i in range(max(len(r) for r in all_rows))]
283
293
  if headers:
284
- line = " ".join(str(h).ljust(widths[i]) for i, h in enumerate(headers))
294
+ line = " ".join(_pad(str(h), widths[i]) for i, h in enumerate(headers))
285
295
  print(c(line, BOLD))
286
296
  for r in rows:
287
- print(" ".join(cell.ljust(widths[i]) for i, cell in enumerate(r)).rstrip())
297
+ print(" ".join(_pad(cell, widths[i]) for i, cell in enumerate(r)).rstrip())
288
298
 
289
299
 
290
300
  def confirm(prompt: str, default: bool = False) -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.36
3
+ Version: 1.0.38
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -302,7 +302,7 @@
302
302
  </article>
303
303
 
304
304
  <article class="ritem" data-track="layout" data-impact="med">
305
- <div class="ritem-top"><span class="rid">BOOST-D08</span><span class="rstatus proposed">Proposed</span></div>
305
+ <div class="ritem-top"><span class="rid">BOOST-D08</span><span class="rstatus progress">In progress</span></div>
306
306
  <h4>Width-aware, right-aligned tables</h4>
307
307
  <p><code>table()</code> is a naive <code>ljust</code> that ignores terminal width and left-aligns numeric columns. Make it width-aware (shrink the widest text column to fit), right-align counts with tabular figures, and add dim column separators — matching the web's <code>font-variant-numeric: tabular-nums</code> stat blocks.</p>
308
308
  <div class="rmeta"><span class="m-cat">layout</span><span>Complexity M</span><span class="m-imp med">Impact Med</span><span class="m-wow">★★★☆☆</span></div>
@@ -483,7 +483,7 @@
483
483
  </article>
484
484
 
485
485
  <article class="ritem" data-track="system" data-impact="med">
486
- <div class="ritem-top"><span class="rid">BOOST-D22</span><span class="rstatus progress">In progress</span></div>
486
+ <div class="ritem-top"><span class="rid">BOOST-D22</span><span class="rstatus done">Shipped</span></div>
487
487
  <h4>README / portfolio terminal parity</h4>
488
488
  <p>The web <code>.window</code> mock shows an <em>idealized</em> boost session — gradient prompt, clean checks — that the real CLI doesn't yet produce. Once D01–D15 land, update the mock (and README code blocks) to mirror the true output 1:1, so every screenshot is honest and the brand reads identically across web, README and terminal.</p>
489
489
  <div class="rmeta"><span class="m-cat">system</span><span>Complexity S</span><span class="m-imp med">Impact Med</span><span class="m-wow">★★★★☆</span></div>
@@ -224,6 +224,8 @@
224
224
  .tok { color: var(--green); } /* ✓ */
225
225
  .tstar { color: var(--amber); }
226
226
  .tdim { color: #9d9dbd; }
227
+ .tacc { color: var(--cyan); font-weight: 700; } /* Aurora accent: meters, names, ==> */
228
+ .tbox { color: var(--green); } /* framed-card border (panel hue=green) */
227
229
 
228
230
  /* ---------- architecture ---------- */
229
231
  .flow { max-width: 860px; margin: 64px auto 0; display: flex; flex-direction: column; align-items: center; }
@@ -587,19 +589,25 @@ facilitate structured divergent thinking:
587
589
  <div class="bar"><div class="dots"><i></i><i></i><i></i></div>
588
590
  <div class="bar-title">zsh — boost</div></div>
589
591
  <pre><span class="tp">$</span> <span class="tv">boost</span> <span class="tc">search</span> jira
590
- jira-integration Sync commits and PRs to Jira tickets <span class="tstar">★ curated</span>
591
- commit-messages Conventional, atomic commit message discipline
592
+ <span class="tacc">▰▰▰▰</span> <span class="tacc">jira-integration</span> Sync commits and PRs to Jira tickets <span class="tstar">★ curated</span>
593
+ <span class="tacc">▰▰▱▱</span> <span class="tacc">commit-messages</span> Conventional, atomic commit message discipline
592
594
  <span class="tdim">2 matches · ranked by Claude Haiku relevance</span>
593
595
 
594
596
  <span class="tp">$</span> <span class="tv">boost</span> <span class="tc">install</span> jira-integration
595
597
  <span class="tok">✓</span> copied to ~/.agents/skills/jira-integration
596
598
  <span class="tok">✓</span> linked → claude-code · windsurf · cursor
597
599
  <span class="tok">✓</span> lock updated (.skill-lock.json)
598
- Installed 1 new skill; quality score 92/100
600
+ <span class="tbox">╭─ </span><b>installed</b><span class="tbox"> ────────────────────────────────────────╮</span>
601
+ <span class="tbox">│</span> Installed 1 new skill; quality score 92/100 <span class="tbox">│</span>
602
+ <span class="tbox">│</span> <span class="tdim">jira-integration → claude-code · windsurf · cursor</span> <span class="tbox">│</span>
603
+ <span class="tbox">│</span> <span class="tdim">next: boost info jira-integration</span> <span class="tbox">│</span>
604
+ <span class="tbox">╰────────────────────────────────────────────────────╯</span>
599
605
 
600
606
  <span class="tp">$</span> <span class="tv">boost</span> <span class="tc">doctor</span>
607
+ <span class="tacc">==&gt;</span> <b>boost doctor</b>
601
608
  <span class="tok">✓</span> 14 skills installed · 2 taps synced · 0 broken links
602
609
  <span class="tok">✓</span> lock file integrity OK · log rotation healthy
610
+ <span class="tok">● healthy</span>
603
611
 
604
612
  <span class="cm"># share the whole setup with your team:</span>
605
613
  <span class="tp">$</span> <span class="tv">boost</span> <span class="tc">bundle</span> dump &gt; Boostfile <span class="cm"># teammates run: boost bundle install</span></pre>
@@ -501,6 +501,27 @@ class TestHelpers:
501
501
  assert capsys.readouterr().out == " n 42\n"
502
502
 
503
503
 
504
+ class TestTableColor:
505
+ def test_pad_uses_visible_width(self, monkeypatch):
506
+ monkeypatch.setenv("CLICOLOR_FORCE", "1")
507
+ colored = output.aurora("ab", "cyan") # visible width 2
508
+ assert output._pad(colored, 5) == colored + " " # 3 trailing spaces
509
+
510
+ def test_colored_cells_align_by_visible_width(self, capsys, monkeypatch):
511
+ import re
512
+ monkeypatch.setenv("CLICOLOR_FORCE", "1")
513
+ # a colored cell must not push the next column out of alignment
514
+ output.table([[output.aurora("ab", "cyan"), "x"], ["cd", "y"]])
515
+ vis = [re.sub(r"\x1b\[[0-9;]*m", "", ln)
516
+ for ln in capsys.readouterr().out.splitlines()]
517
+ assert vis == ["ab x", "cd y"]
518
+
519
+ def test_header_row_is_bold_when_forced(self, capsys, monkeypatch):
520
+ monkeypatch.setenv("CLICOLOR_FORCE", "1")
521
+ output.table([["x", "1"]], headers=["NAME", "N"])
522
+ assert capsys.readouterr().out.startswith("\033[1mNAME")
523
+
524
+
504
525
  class TestTable:
505
526
  @pytest.fixture(autouse=True)
506
527
  def plain(self, monkeypatch):
File without changes