mirror of
https://github.com/BillyOutlast/CLI-Anything-WEB.git
synced 2026-10-12 02:24:59 +00:00
Phase 3 (Generation v2):
- scaffold-cli.py migrated to Jinja2 (${} delimiters preserve existing
templates; StrictUndefined; TEMPLATE_VERSION 2.0.0; .manifest.json
provenance emission)
- auth.py.tpl unified (google-sso via {% if %} block; auth_google_sso.py.tpl
deleted); anchor-based method injection replaced by template conditionals
- New scaffolds: command_group.py.tpl (--resource flag), test_e2e.py.tpl
(canonical subprocess fixtures), README.md.tpl + SKILL.md.tpl (replace
dead Handlebars .template files, now actually rendered)
- 21-profile golden test matrix (protocol x http_client x auth) — compile-
clean, no placeholder leaks, profile-correct deps/files
- Skills consolidation: skills/shared/CONVENTIONS.md (single definition of
every implementation rule) + RECOVERY.md (per-gate failure decision
trees); boilerplate skill 829 -> 106 lines; HARNESS.md now navigational;
reviewer agents de-overlapped; gap-analyzer mandatory first step of
/refine; quality checklist tiered (38 Tier-1 critical checks) with
--tier1-only/--strict in validate-checklist.py
Phase 4 (Fleet ops):
- cli-web-devkit canary: registry-declared read-only live-site smoke
commands (12 no-auth CLIs) + daily canary.yml workflow that auto-files
site-breakage issues
- contract.yml workflow: fleet contract suite + vendored-file drift on PR
- release-please switched to manifest/monorepo mode (root + cli-web-core +
devkit packages, per-package changelogs); publish.yml with PyPI trusted
publishing (setup guide in docs/PUBLISHING.md)
- cli-web-devkit docs: README fleet table + install block generated from
registry.json between markers, --check freshness gate in CI (caught the
install list missing linkedin)
Phase 5 (Product leaps):
- MCP SERVE FLEET-WIDE: cli_web_core/mcp_server.py adapter (vendored to all
19 CLIs, synced by resync) exposes every Click command as a typed MCP
tool over stdio; mcp-serve wired into all 19 entry points;
contract-tested handshake x19
- api-spec.json IR: evidence-required endpoint schema + cli-web-devkit
spec validate; wired into methodology Phase 2 (structural enforcement of
never-invent-endpoints)
- cli-web-devkit gaps: deterministic captured-vs-implemented-vs-exposed
diff (AST-based), wired into gap-analyzer skill Step 0
- Capture quality scoring (0-100) in validate-capture report
Fleet contract fixes found by the new gates:
- gh-trending emitted bare JSON arrays instead of the success envelope
(fixed + e2e updated; stale version assertion fixed)
- notebooklm/stitch/codewiki/chatgpt lacked --version (fixed in Phase 2
commit); booking registry commands corrected
Verified: 514 plugin/devkit/core tests, 95 fleet contract tests (incl. 19
MCP handshakes), 19/19 CLI unit suites, gh-trending e2e live, ruff+format
clean (512 files), mypy strict clean, verify-plugin 28/28, drift 39/39 ok,
registry + README freshness gates green.
https://claude.ai/code/session_017wCNXuLy6UpGJ1jcPdsD5i
108 lines
4.2 KiB
Python
108 lines
4.2 KiB
Python
import json
|
|
|
|
from cli_web_devkit.paths import repo_root
|
|
from cli_web_devkit.registry import Registry
|
|
from cli_web_devkit.sync import MANIFEST_NAME, SHARED_FILES, drift, load_manifest, resync
|
|
|
|
ROOT = repo_root()
|
|
|
|
|
|
def _make_fleet(tmp_path, vendored_content: bytes | None, with_override: bool = False):
|
|
"""Build a minimal repo: canon files + one registered CLI."""
|
|
pkg = tmp_path / "demo/agent-harness/cli_web/demo"
|
|
(pkg / "utils").mkdir(parents=True)
|
|
for canon_rel, vendored_rel in SHARED_FILES.items():
|
|
canon = tmp_path / canon_rel
|
|
canon.parent.mkdir(parents=True, exist_ok=True)
|
|
canon.write_bytes(b"CANONICAL CONTENT v2\n")
|
|
# All vendored copies except repl_skin start in sync; repl_skin
|
|
# content is controlled by the test.
|
|
if vendored_rel != "utils/repl_skin.py":
|
|
target = pkg / vendored_rel
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_bytes(b"CANONICAL CONTENT v2\n")
|
|
if vendored_content is not None:
|
|
(pkg / "utils/repl_skin.py").write_bytes(vendored_content)
|
|
|
|
(tmp_path / "registry.json").write_text(
|
|
json.dumps(
|
|
{
|
|
"version": "1.0.0",
|
|
"clis": [
|
|
{
|
|
"name": "cli-web-demo",
|
|
"website": "demo.example",
|
|
"protocol": "REST",
|
|
"auth": "none",
|
|
"directory": "demo/agent-harness",
|
|
"namespace": "cli_web.demo",
|
|
"commands": ["x"],
|
|
"install": "pip install -e demo/agent-harness",
|
|
}
|
|
],
|
|
}
|
|
)
|
|
)
|
|
if with_override:
|
|
(tmp_path / "demo/agent-harness" / MANIFEST_NAME).write_text(
|
|
json.dumps(
|
|
{
|
|
"manifest_version": 1,
|
|
"cli": "cli-web-demo",
|
|
"shared_files": {},
|
|
"overrides": [{"file": "utils/repl_skin.py", "reason": "custom prompt"}],
|
|
}
|
|
)
|
|
)
|
|
return tmp_path
|
|
|
|
|
|
def test_drift_detects_divergence(tmp_path):
|
|
_make_fleet(tmp_path, b"OLD STALE COPY\n")
|
|
statuses = {(i.cli, i.file): i.status for i in drift(tmp_path) if i.cli == "cli-web-demo"}
|
|
assert statuses[("cli-web-demo", "utils/repl_skin.py")] == "drifted"
|
|
|
|
|
|
def test_drift_detects_missing(tmp_path):
|
|
_make_fleet(tmp_path, None)
|
|
statuses = [i.status for i in drift(tmp_path) if i.cli == "cli-web-demo"]
|
|
assert "missing" in statuses
|
|
|
|
|
|
def test_drift_respects_overrides(tmp_path):
|
|
_make_fleet(tmp_path, b"INTENTIONALLY DIFFERENT\n", with_override=True)
|
|
items = {i.file: i for i in drift(tmp_path) if i.cli == "cli-web-demo"}
|
|
assert items["utils/repl_skin.py"].status == "override"
|
|
assert "custom prompt" in items["utils/repl_skin.py"].detail
|
|
|
|
|
|
def test_resync_fixes_drift_and_writes_manifest(tmp_path):
|
|
root = _make_fleet(tmp_path, b"OLD STALE COPY\n")
|
|
changed = resync(root)
|
|
assert "demo/agent-harness/cli_web/demo/utils/repl_skin.py" in changed
|
|
|
|
vendored = root / "demo/agent-harness/cli_web/demo/utils/repl_skin.py"
|
|
assert vendored.read_bytes() == b"CANONICAL CONTENT v2\n"
|
|
|
|
reg = Registry.load(root / "registry.json")
|
|
manifest = load_manifest(root, reg.entry("cli-web-demo"))
|
|
rec = manifest["shared_files"]["utils/repl_skin.py"]
|
|
assert rec["source"] == next(iter(SHARED_FILES))
|
|
assert len(rec["sha256"]) == 64
|
|
|
|
# After resync, drift is clean for the CLI
|
|
assert all(i.status == "ok" for i in drift(root) if i.cli == "cli-web-demo")
|
|
|
|
|
|
def test_resync_skips_overridden_files(tmp_path):
|
|
root = _make_fleet(tmp_path, b"INTENTIONALLY DIFFERENT\n", with_override=True)
|
|
resync(root)
|
|
vendored = root / "demo/agent-harness/cli_web/demo/utils/repl_skin.py"
|
|
assert vendored.read_bytes() == b"INTENTIONALLY DIFFERENT\n"
|
|
|
|
|
|
def test_real_fleet_has_no_unexplained_drift():
|
|
"""The actual repo must be in sync (run `cli-web-devkit resync` if this fails)."""
|
|
bad = [i for i in drift(ROOT) if i.status in ("drifted", "missing")]
|
|
assert not bad, f"fleet drift detected: {[(i.cli, i.file, i.status) for i in bad]}"
|