boost-skill-cli 1.0.49__tar.gz → 1.0.51__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.
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/PKG-INFO +1 -1
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/index.html +1 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/roadmap.html +232 -0
- boost_skill_cli-1.0.51/index.html +15 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/.gitignore +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/LICENSE +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/Makefile +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/README.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/setup.cfg +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/style/README.md +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/style/boost.css +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/style/boost.js +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/style/demo.html +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/unit/test_version.py +0 -0
|
@@ -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.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
21
|
+
__version__ = version = '1.0.51'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 51)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -425,6 +425,7 @@
|
|
|
425
425
|
<li><a href="#capabilities">Capabilities</a></li>
|
|
426
426
|
<li><a href="#registries">Registries</a></li>
|
|
427
427
|
<li><a href="roadmap.html">Roadmap ↗</a></li>
|
|
428
|
+
<li><a href="https://jonnyeclectic.github.io/portfolio/">Portfolio ↗</a></li>
|
|
428
429
|
<li><a class="cta" href="#start">Get started</a></li>
|
|
429
430
|
</ul>
|
|
430
431
|
</div>
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
<a class="logo" href="index.html">boost<span>Roadmap</span></a>
|
|
85
85
|
<nav>
|
|
86
86
|
<a href="index.html">Visual guide</a>
|
|
87
|
+
<a href="https://jonnyeclectic.github.io/portfolio/">Portfolio</a>
|
|
87
88
|
<a href="https://github.com/jonnyeclectic/boost">GitHub</a>
|
|
88
89
|
<a href="https://pypi.org/project/boost-skill-cli/">PyPI</a>
|
|
89
90
|
</nav>
|
|
@@ -311,6 +312,237 @@
|
|
|
311
312
|
</div>
|
|
312
313
|
</section>
|
|
313
314
|
|
|
315
|
+
<!-- ============ ENGINE & COMMAND INTERNALS ============ -->
|
|
316
|
+
<section class="block reveal" id="internals">
|
|
317
|
+
<div class="block-head">
|
|
318
|
+
<h2>Engine & command internals</h2><span class="count">// concrete file:line findings from the code scan</span>
|
|
319
|
+
<span class="rule"></span>
|
|
320
|
+
</div>
|
|
321
|
+
<div class="rgrid">
|
|
322
|
+
|
|
323
|
+
<article class="cap rcard">
|
|
324
|
+
<div class="head"><span class="pill next">Next</span><span class="cat">Correctness · Robustness</span></div>
|
|
325
|
+
<h3>Atomic, corruption-safe lock-file writes</h3>
|
|
326
|
+
<p><code>read()</code> returns an empty skeleton on <b>any</b> JSON error and <code>write()</code> is a bare <code>write_text</code> at <code>core/lockfile.py:55</code>. An interrupted or concurrent write truncates the lock — the next <code>set_skill()</code> then <b>permanently drops every prior install record</b> while store dirs linger as orphans. Write to a temp file + <code>os.replace()</code>, and tell "empty" apart from "corrupt".</p>
|
|
327
|
+
<div class="meta">
|
|
328
|
+
<span class="m">Complexity <b>M</b></span>
|
|
329
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
330
|
+
<span class="m">Wow <b class="wow">★★★★</b></span>
|
|
331
|
+
</div>
|
|
332
|
+
</article>
|
|
333
|
+
|
|
334
|
+
<article class="cap rcard">
|
|
335
|
+
<div class="head"><span class="pill next">Next</span><span class="cat">Correctness</span></div>
|
|
336
|
+
<h3>Fix <code>self-update</code> version detection (dead branch)</h3>
|
|
337
|
+
<p><code>cmd_self_update</code> greps <code>__init__.py</code> for a <code>__version__ = "…"</code> literal (<code>commands/configuration.py:1090</code>), but the constant is <code>_detect_version()</code> (setuptools-scm — no literal). The regex never matches, so it reports <b>"already up to date"</b> even after a pull brings a newer tag. The success path is unreachable.</p>
|
|
338
|
+
<div class="meta">
|
|
339
|
+
<span class="m">Complexity <b>S</b></span>
|
|
340
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
341
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
342
|
+
</div>
|
|
343
|
+
</article>
|
|
344
|
+
|
|
345
|
+
<article class="cap rcard">
|
|
346
|
+
<div class="head"><span class="pill next">Next</span><span class="cat">Correctness</span></div>
|
|
347
|
+
<h3>Consolidate skill-staleness / drift logic into core</h3>
|
|
348
|
+
<p>The "is this skill outdated" decision — <code>semver_gt</code> → commit compare → <code>sha256_dir</code> vs lock — is reimplemented nearly verbatim in <code>cmd_update</code>, <code>cmd_outdated</code> and <code>_drift_status</code> (<code>pkg.py:277 · taps.py:225 · quality.py:120</code>). Three copies of core business logic that <b>will drift apart</b>. Make it one <code>core</code> function the commands render.</p>
|
|
349
|
+
<div class="meta">
|
|
350
|
+
<span class="m">Complexity <b>M</b></span>
|
|
351
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
352
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
353
|
+
</div>
|
|
354
|
+
</article>
|
|
355
|
+
|
|
356
|
+
<article class="cap rcard">
|
|
357
|
+
<div class="head"><span class="pill next">Next</span><span class="cat">Performance</span></div>
|
|
358
|
+
<h3>Memoize <code>config.load()</code> in-process</h3>
|
|
359
|
+
<p>Every <code>config.get()</code> re-reads <code>config.json</code> and runs a recursive <code>deepcopy</code> of <code>DEFAULTS</code> (<code>core/config.py:80–102</code>). It's called all over hot paths — <code>ai.enabled</code>, per-skill <code>enabled_agents</code> in sync loops, log-level and policy checks — so one command triggers <b>dozens of full reads + deep-copies</b>. Cache the load, invalidate on <code>save</code>.</p>
|
|
360
|
+
<div class="meta">
|
|
361
|
+
<span class="m">Complexity <b>S</b></span>
|
|
362
|
+
<span class="m hi">Impact <b>Med-High</b></span>
|
|
363
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
364
|
+
</div>
|
|
365
|
+
</article>
|
|
366
|
+
|
|
367
|
+
<article class="cap rcard">
|
|
368
|
+
<div class="head"><span class="pill next">Next</span><span class="cat">Tech-debt</span></div>
|
|
369
|
+
<h3>Extract MCP + HTTP servers out of <code>configuration.py</code></h3>
|
|
370
|
+
<p>~290 lines implement a full HTTP catalog server <b>and</b> a JSON-RPC 2.0 MCP server — with search/install/doctor dispatch that duplicates the CLI — inside a "configuration" command module (<code>commands/configuration.py:741–1028</code>). Move to <code>core/mcp.py</code> / <code>core/serve.py</code>, leaving thin wrappers. It's the biggest driver of the file's 1,099 lines and nearly untestable in place.</p>
|
|
371
|
+
<div class="meta">
|
|
372
|
+
<span class="m">Complexity <b>L</b></span>
|
|
373
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
374
|
+
<span class="m">Wow <b class="wow">★★★★</b></span>
|
|
375
|
+
</div>
|
|
376
|
+
</article>
|
|
377
|
+
|
|
378
|
+
<article class="cap rcard">
|
|
379
|
+
<div class="head"><span class="pill next">Next</span><span class="cat">Security</span></div>
|
|
380
|
+
<h3>End-of-options <code>--</code> guard on git commands</h3>
|
|
381
|
+
<p><code>clone_shallow</code>/<code>fetch</code>/<code>reset</code> pass the URL & ref as positionals with no <code>--</code> separator (<code>core/gitutil.py:34–46</code>), so a value starting with <code>-</code> is parsed as a git option. <code>parse_spec</code> constrains most URL shapes, but adding <code>--</code> before positionals and rejecting <code>ext::</code>/<code>file::</code>/<code>fd::</code> transports closes the argument-injection surface as defense-in-depth.</p>
|
|
382
|
+
<div class="meta">
|
|
383
|
+
<span class="m">Complexity <b>S</b></span>
|
|
384
|
+
<span class="m hi">Impact <b>Med</b></span>
|
|
385
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
386
|
+
</div>
|
|
387
|
+
</article>
|
|
388
|
+
|
|
389
|
+
<article class="cap rcard">
|
|
390
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Robustness</span></div>
|
|
391
|
+
<h3>Atomic skill install (temp-dir swap)</h3>
|
|
392
|
+
<p><code>_copy_skill</code> does <code>rmtree(dest)</code> then <code>copytree()</code> (<code>core/store.py:108–131</code>); an interrupt between the two leaves a missing or half-copied skill, and the lock is written afterward — so a mid-copy failure leaves store and lock <b>disagreeing</b>. Copy to a temp dir and atomically swap into place.</p>
|
|
393
|
+
<div class="meta">
|
|
394
|
+
<span class="m">Complexity <b>M</b></span>
|
|
395
|
+
<span class="m">Impact <b>Med</b></span>
|
|
396
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
397
|
+
</div>
|
|
398
|
+
</article>
|
|
399
|
+
|
|
400
|
+
<article class="cap rcard">
|
|
401
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Robustness</span></div>
|
|
402
|
+
<h3>One shared atomic-write helper</h3>
|
|
403
|
+
<p><code>journal._maybe_rotate</code> is a racy read-modify-write that concurrent appends can truncate mid-line; <code>rag._save</code> and <code>config.save</code> repeat the non-atomic pattern (<code>journal.py:63 · rag.py:252 · config.py:93</code>). Factor a single <code>atomic_write</code> into <code>core</code> and route all four through it.</p>
|
|
404
|
+
<div class="meta">
|
|
405
|
+
<span class="m">Complexity <b>S</b></span>
|
|
406
|
+
<span class="m">Impact <b>Med</b></span>
|
|
407
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
408
|
+
</div>
|
|
409
|
+
</article>
|
|
410
|
+
|
|
411
|
+
<article class="cap rcard">
|
|
412
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Correctness</span></div>
|
|
413
|
+
<h3>Unify <code>_tilde()</code> — two copies have a boundary bug</h3>
|
|
414
|
+
<p>Eight command modules each define <code>_tilde</code>; the <code>quality</code> and <code>intelligence</code> versions use <code>startswith(home)</code> with no separator check (<code>quality.py:78</code>), so <code>/Users/bob-backup</code> wrongly contracts to <code>~-backup</code>. Collapse to one helper in <code>core/paths</code>.</p>
|
|
415
|
+
<div class="meta">
|
|
416
|
+
<span class="m">Complexity <b>S</b></span>
|
|
417
|
+
<span class="m">Impact <b>Med</b></span>
|
|
418
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
419
|
+
</div>
|
|
420
|
+
</article>
|
|
421
|
+
|
|
422
|
+
<article class="cap rcard">
|
|
423
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Performance</span></div>
|
|
424
|
+
<h3>Cache the catalog entry-set across RAG queries</h3>
|
|
425
|
+
<p><code>rag.retrieve()</code> calls <code>all_entries()</code>, which reads & <code>json.loads</code> <b>every tap cache on every search</b> to build the live map (<code>rag.py:323 · catalog.py:166–181</code>) — the BM25 index is mtime-cached, the entry set is not. Memoize the entry set on cache mtime the same way.</p>
|
|
426
|
+
<div class="meta">
|
|
427
|
+
<span class="m">Complexity <b>M</b></span>
|
|
428
|
+
<span class="m">Impact <b>Med</b></span>
|
|
429
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
430
|
+
</div>
|
|
431
|
+
</article>
|
|
432
|
+
|
|
433
|
+
<article class="cap rcard">
|
|
434
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Performance</span></div>
|
|
435
|
+
<h3>Stop re-serializing entry meta on every search</h3>
|
|
436
|
+
<p><code>catalog.search</code> computes <code>json.dumps(meta).lower()</code> for <b>every entry on every query</b> just to substring-match (<code>catalog.py:222</code>). Precompute a lowercased search blob at index time, or match structured fields directly.</p>
|
|
437
|
+
<div class="meta">
|
|
438
|
+
<span class="m">Complexity <b>S</b></span>
|
|
439
|
+
<span class="m">Impact <b>Med</b></span>
|
|
440
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
441
|
+
</div>
|
|
442
|
+
</article>
|
|
443
|
+
|
|
444
|
+
<article class="cap rcard">
|
|
445
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Performance</span></div>
|
|
446
|
+
<h3>Prune ignored dirs during <code>scan_dir</code> walk</h3>
|
|
447
|
+
<p>Two full <code>rglob</code> passes descend <b>into</b> <code>.git</code>/<code>node_modules</code> and only filter afterward, and the skill-dir membership test is O(files × skill_dirs) (<code>catalog.py:106,119–123</code>). Switch to an <code>os.walk</code> that prunes ignored dirs in place; index skill dirs in a set.</p>
|
|
448
|
+
<div class="meta">
|
|
449
|
+
<span class="m">Complexity <b>M</b></span>
|
|
450
|
+
<span class="m">Impact <b>Low-Med</b></span>
|
|
451
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
452
|
+
</div>
|
|
453
|
+
</article>
|
|
454
|
+
|
|
455
|
+
<article class="cap rcard">
|
|
456
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Tech-debt</span></div>
|
|
457
|
+
<h3>Single tech-stack prober</h3>
|
|
458
|
+
<p>Stack detection exists three times — <code>discovery.detect_stack</code>, <code>intelligence._local_stack</code>, <code>quality._STACK_MARKERS</code> (<code>discovery.py:74 · intelligence.py:359 · quality.py:55</code>) — and two already <code>import detect_stack</code> yet still carry a parallel marker table "as a fallback". Consolidate into one core prober.</p>
|
|
459
|
+
<div class="meta">
|
|
460
|
+
<span class="m">Complexity <b>M</b></span>
|
|
461
|
+
<span class="m">Impact <b>Med</b></span>
|
|
462
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
463
|
+
</div>
|
|
464
|
+
</article>
|
|
465
|
+
|
|
466
|
+
<article class="cap rcard">
|
|
467
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Tech-debt</span></div>
|
|
468
|
+
<h3>Single imperative-rule extractor</h3>
|
|
469
|
+
<p>Three separate regexes scan SKILL.md bodies for "Always / Never / Must / Do not" lines across <code>cmd_explain</code>, <code>simulate</code> and <code>conflict</code> (<code>info.py:363 · intelligence.py:254 · quality.py:822</code>) — same concept, three implementations. Extract one shared <code>core</code> extractor.</p>
|
|
470
|
+
<div class="meta">
|
|
471
|
+
<span class="m">Complexity <b>M</b></span>
|
|
472
|
+
<span class="m">Impact <b>Med</b></span>
|
|
473
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
474
|
+
</div>
|
|
475
|
+
</article>
|
|
476
|
+
|
|
477
|
+
<article class="cap rcard">
|
|
478
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Maintainability</span></div>
|
|
479
|
+
<h3>Split oversized command modules</h3>
|
|
480
|
+
<p><code>quality.py</code> (14 cmds / 1,051 lines) mixes audit regexes, conflict NLP, decay scoring, fingerprinting and a health dashboard; <code>intelligence.py</code> and <code>configuration.py</code> are similarly overloaded. Split along cohesive seams to shrink blast radius and sharpen mutation-gate targeting.</p>
|
|
481
|
+
<div class="meta">
|
|
482
|
+
<span class="m">Complexity <b>L</b></span>
|
|
483
|
+
<span class="m">Impact <b>Med</b></span>
|
|
484
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
485
|
+
</div>
|
|
486
|
+
</article>
|
|
487
|
+
|
|
488
|
+
<article class="cap rcard">
|
|
489
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Maintainability</span></div>
|
|
490
|
+
<h3>Robust <code>tag</code> argument parsing</h3>
|
|
491
|
+
<p>Because <code>-tag</code> looks like an option, <code>cmd_tag</code> calls <code>parse_known_args</code> then re-walks raw <code>argv</code> to reorder tokens (<code>info.py:575–584</code>) — fragile enough that the comment calls it "defensive". Replace with a positional-only sub-parser or an explicit <code>--add/--remove</code> design.</p>
|
|
492
|
+
<div class="meta">
|
|
493
|
+
<span class="m">Complexity <b>M</b></span>
|
|
494
|
+
<span class="m">Impact <b>Med</b></span>
|
|
495
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
496
|
+
</div>
|
|
497
|
+
</article>
|
|
498
|
+
|
|
499
|
+
<article class="cap rcard">
|
|
500
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Tech-debt · RAG</span></div>
|
|
501
|
+
<h3>Localize the stored BM25 snippet</h3>
|
|
502
|
+
<p><code>_make_docs</code> stores <code>piece[:200]</code> — the head of the best chunk — and <code>retrieve</code> surfaces it verbatim (<code>rag.py:154–172,337–341</code>), yet the docstrings promise the "best-matching passage". Center the snippet on the matched terms to improve display and the rerank context sent to the LLM.</p>
|
|
503
|
+
<div class="meta">
|
|
504
|
+
<span class="m">Complexity <b>M</b></span>
|
|
505
|
+
<span class="m">Impact <b>Low</b></span>
|
|
506
|
+
<span class="m">Wow <b class="wow">★★★</b></span>
|
|
507
|
+
</div>
|
|
508
|
+
</article>
|
|
509
|
+
|
|
510
|
+
<article class="cap rcard">
|
|
511
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Correctness</span></div>
|
|
512
|
+
<h3>Frontmatter scalar over-coercion</h3>
|
|
513
|
+
<p><code>_scalar</code> turns <code>no</code>/<code>on</code>/<code>off</code>/<code>null</code> into bool/None (<code>core/frontmatter.py:32–53</code>), so a tag or name literally equal to one of those parses to the wrong type and leaks into search/ranking meta. Restrict boolean coercion to <code>true</code>/<code>false</code>.</p>
|
|
514
|
+
<div class="meta">
|
|
515
|
+
<span class="m">Complexity <b>S</b></span>
|
|
516
|
+
<span class="m">Impact <b>Low</b></span>
|
|
517
|
+
<span class="m">Wow <b class="wow">★★</b></span>
|
|
518
|
+
</div>
|
|
519
|
+
</article>
|
|
520
|
+
|
|
521
|
+
<article class="cap rcard">
|
|
522
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Robustness</span></div>
|
|
523
|
+
<h3>Guard <code>output.table</code> against ragged rows</h3>
|
|
524
|
+
<p>Column-width computation does <code>max(… for r in rows if i < len(r))</code> (<code>core/output.py:300</code>), which raises <code>max() arg is empty</code> when a header column has no matching cell in any row. Add <code>default=0</code>.</p>
|
|
525
|
+
<div class="meta">
|
|
526
|
+
<span class="m">Complexity <b>S</b></span>
|
|
527
|
+
<span class="m">Impact <b>Low</b></span>
|
|
528
|
+
<span class="m">Wow <b class="wow">★</b></span>
|
|
529
|
+
</div>
|
|
530
|
+
</article>
|
|
531
|
+
|
|
532
|
+
<article class="cap rcard">
|
|
533
|
+
<div class="head"><span class="pill planned">Planned</span><span class="cat">Tech-debt</span></div>
|
|
534
|
+
<h3>Reuse helpers; kill minor dead work</h3>
|
|
535
|
+
<p><code>cmd_migrate</code> re-implements agent validation instead of calling <code>_check_agents</code>; <code>_user()</code> is copy-pasted between <code>configuration</code> and <code>team</code>; <code>cmd_simulate</code> parses the same frontmatter twice (<code>pkg.py:38,577 · configuration.py:39 · team.py:30</code>). Small, satisfying cleanups.</p>
|
|
536
|
+
<div class="meta">
|
|
537
|
+
<span class="m">Complexity <b>S</b></span>
|
|
538
|
+
<span class="m">Impact <b>Low</b></span>
|
|
539
|
+
<span class="m">Wow <b class="wow">★</b></span>
|
|
540
|
+
</div>
|
|
541
|
+
</article>
|
|
542
|
+
|
|
543
|
+
</div>
|
|
544
|
+
</section>
|
|
545
|
+
|
|
314
546
|
<!-- ============ CODE HEALTH & SECURITY ============ -->
|
|
315
547
|
<section class="block reveal" id="health">
|
|
316
548
|
<div class="block-head">
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<!-- GitHub Pages serves this repo at /boost/. Send the bare site root to the
|
|
6
|
+
visual guide under docs/ so jonnyeclectic.github.io/boost/ lands somewhere
|
|
7
|
+
useful instead of a 404. -->
|
|
8
|
+
<meta http-equiv="refresh" content="0; url=docs/index.html">
|
|
9
|
+
<link rel="canonical" href="docs/index.html">
|
|
10
|
+
<title>boost — redirecting to the guide…</title>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<p>Redirecting to the <a href="docs/index.html">boost visual guide</a>…</p>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/boost_skill_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boost_skill_cli-1.0.49 → boost_skill_cli-1.0.51}/tests/functional/test_cli_configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|