@ictechgy/context-guard 0.4.0
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.
- package/CHANGELOG.md +49 -0
- package/LICENSE +201 -0
- package/NOTICE +4 -0
- package/README.ko.md +353 -0
- package/README.md +353 -0
- package/context-guard-kit/README.md +76 -0
- package/context-guard-kit/benchmark_runner.py +1898 -0
- package/context-guard-kit/claude_transcript_cost_audit.py +1591 -0
- package/context-guard-kit/context_compress.py +543 -0
- package/context-guard-kit/context_escrow.py +919 -0
- package/context-guard-kit/context_guard_cli.py +149 -0
- package/context-guard-kit/context_guard_diet.py +1036 -0
- package/context-guard-kit/context_pack.py +929 -0
- package/context-guard-kit/failed_attempt_nudge.py +567 -0
- package/context-guard-kit/guard_large_read.py +690 -0
- package/context-guard-kit/hook_secret_patterns.py +43 -0
- package/context-guard-kit/read_symbol.py +483 -0
- package/context-guard-kit/rewrite_bash_for_token_budget.py +501 -0
- package/context-guard-kit/sanitize_output.py +725 -0
- package/context-guard-kit/settings.example.json +67 -0
- package/context-guard-kit/setup_wizard.py +1724 -0
- package/context-guard-kit/statusline.sh +362 -0
- package/context-guard-kit/statusline_merged.sh +157 -0
- package/context-guard-kit/tool_schema_pruner.py +837 -0
- package/context-guard-kit/trim_command_output.py +1098 -0
- package/docs/distribution.md +55 -0
- package/package.json +70 -0
- package/packaging/homebrew/context-guard.rb.template +34 -0
- package/plugins/context-guard/.claude-plugin/plugin.json +41 -0
- package/plugins/context-guard/LICENSE +201 -0
- package/plugins/context-guard/NOTICE +4 -0
- package/plugins/context-guard/README.ko.md +135 -0
- package/plugins/context-guard/README.md +135 -0
- package/plugins/context-guard/bin/claude-read-symbol +6 -0
- package/plugins/context-guard/bin/claude-sanitize-output +6 -0
- package/plugins/context-guard/bin/claude-token-artifact +6 -0
- package/plugins/context-guard/bin/claude-token-audit +6 -0
- package/plugins/context-guard/bin/claude-token-bench +6 -0
- package/plugins/context-guard/bin/claude-token-diet +6 -0
- package/plugins/context-guard/bin/claude-token-failed-nudge +6 -0
- package/plugins/context-guard/bin/claude-token-guard-read +6 -0
- package/plugins/context-guard/bin/claude-token-rewrite-bash +6 -0
- package/plugins/context-guard/bin/claude-token-setup +6 -0
- package/plugins/context-guard/bin/claude-token-statusline +6 -0
- package/plugins/context-guard/bin/claude-token-statusline-merged +6 -0
- package/plugins/context-guard/bin/claude-trim-output +6 -0
- package/plugins/context-guard/bin/context-guard +149 -0
- package/plugins/context-guard/bin/context-guard-artifact +919 -0
- package/plugins/context-guard/bin/context-guard-audit +1591 -0
- package/plugins/context-guard/bin/context-guard-bench +1898 -0
- package/plugins/context-guard/bin/context-guard-compress +543 -0
- package/plugins/context-guard/bin/context-guard-diet +1036 -0
- package/plugins/context-guard/bin/context-guard-failed-nudge +567 -0
- package/plugins/context-guard/bin/context-guard-guard-read +690 -0
- package/plugins/context-guard/bin/context-guard-pack +929 -0
- package/plugins/context-guard/bin/context-guard-read-symbol +483 -0
- package/plugins/context-guard/bin/context-guard-rewrite-bash +501 -0
- package/plugins/context-guard/bin/context-guard-sanitize-output +725 -0
- package/plugins/context-guard/bin/context-guard-setup +1724 -0
- package/plugins/context-guard/bin/context-guard-statusline +362 -0
- package/plugins/context-guard/bin/context-guard-statusline-merged +157 -0
- package/plugins/context-guard/bin/context-guard-tool-prune +837 -0
- package/plugins/context-guard/bin/context-guard-trim-output +1098 -0
- package/plugins/context-guard/brief/README.md +65 -0
- package/plugins/context-guard/brief/brief-mode.lite.md +29 -0
- package/plugins/context-guard/brief/brief-mode.standard.md +31 -0
- package/plugins/context-guard/brief/brief-mode.ultra.md +32 -0
- package/plugins/context-guard/lib/hook_secret_patterns.py +43 -0
- package/plugins/context-guard/skills/audit/SKILL.md +39 -0
- package/plugins/context-guard/skills/optimize/SKILL.md +48 -0
- package/plugins/context-guard/skills/setup/SKILL.md +40 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Canonical ContextGuard command dispatcher.
|
|
3
|
+
|
|
4
|
+
The npm/Homebrew-friendly ``context-guard`` command is intentionally passive:
|
|
5
|
+
installation only exposes commands on PATH. Any project or user configuration is
|
|
6
|
+
performed later through explicit subcommands such as ``context-guard setup``.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
import subprocess
|
|
14
|
+
import sys
|
|
15
|
+
from typing import NoReturn
|
|
16
|
+
|
|
17
|
+
COMMAND_NAME = "context-guard"
|
|
18
|
+
PACKAGE_NAME = "@ictechgy/context-guard"
|
|
19
|
+
|
|
20
|
+
HELPER_SUBCOMMANDS: dict[str, tuple[str, ...]] = {
|
|
21
|
+
"setup": ("context-guard-setup",),
|
|
22
|
+
"audit": ("context-guard-audit",),
|
|
23
|
+
"diet": ("context-guard-diet",),
|
|
24
|
+
"scan": ("context-guard-diet", "scan"),
|
|
25
|
+
"trim-output": ("context-guard-trim-output",),
|
|
26
|
+
"trim": ("context-guard-trim-output",),
|
|
27
|
+
"sanitize-output": ("context-guard-sanitize-output",),
|
|
28
|
+
"sanitize": ("context-guard-sanitize-output",),
|
|
29
|
+
"artifact": ("context-guard-artifact",),
|
|
30
|
+
"pack": ("context-guard-pack",),
|
|
31
|
+
"tool-prune": ("context-guard-tool-prune",),
|
|
32
|
+
"compress": ("context-guard-compress",),
|
|
33
|
+
"bench": ("context-guard-bench",),
|
|
34
|
+
"read-symbol": ("context-guard-read-symbol",),
|
|
35
|
+
"rewrite-bash": ("context-guard-rewrite-bash",),
|
|
36
|
+
"guard-read": ("context-guard-guard-read",),
|
|
37
|
+
"failed-nudge": ("context-guard-failed-nudge",),
|
|
38
|
+
"statusline": ("context-guard-statusline",),
|
|
39
|
+
"statusline-merged": ("context-guard-statusline-merged",),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _script_dir() -> Path:
|
|
44
|
+
return Path(__file__).resolve().parent
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _candidate_roots() -> list[Path]:
|
|
48
|
+
script_dir = _script_dir()
|
|
49
|
+
roots = [script_dir.parent, script_dir.parent.parent, Path.cwd()]
|
|
50
|
+
# When run from context-guard-kit in a checkout, the repo root is one level up.
|
|
51
|
+
if script_dir.name == "context-guard-kit":
|
|
52
|
+
roots.insert(0, script_dir.parent)
|
|
53
|
+
return list(dict.fromkeys(roots))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _load_json(path: Path) -> dict[str, object] | None:
|
|
57
|
+
try:
|
|
58
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
59
|
+
except (OSError, json.JSONDecodeError):
|
|
60
|
+
return None
|
|
61
|
+
return data if isinstance(data, dict) else None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def project_version() -> str:
|
|
65
|
+
candidates: list[Path] = []
|
|
66
|
+
for root in _candidate_roots():
|
|
67
|
+
candidates.extend(
|
|
68
|
+
[
|
|
69
|
+
root / ".claude-plugin" / "plugin.json",
|
|
70
|
+
root / "plugins" / "context-guard" / ".claude-plugin" / "plugin.json",
|
|
71
|
+
root / "package.json",
|
|
72
|
+
]
|
|
73
|
+
)
|
|
74
|
+
for candidate in candidates:
|
|
75
|
+
data = _load_json(candidate)
|
|
76
|
+
version = data.get("version") if data else None
|
|
77
|
+
if isinstance(version, str) and version.strip():
|
|
78
|
+
return version.strip()
|
|
79
|
+
return "0.0.0+unknown"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def print_help() -> None:
|
|
83
|
+
version = project_version()
|
|
84
|
+
commands = "\n".join(f" {name}" for name in sorted(HELPER_SUBCOMMANDS))
|
|
85
|
+
sys.stdout.write(
|
|
86
|
+
f"ContextGuard {version}\n"
|
|
87
|
+
f"\n"
|
|
88
|
+
f"Usage:\n"
|
|
89
|
+
f" {COMMAND_NAME} --version\n"
|
|
90
|
+
f" {COMMAND_NAME} <subcommand> [args...]\n"
|
|
91
|
+
f"\n"
|
|
92
|
+
f"Install examples:\n"
|
|
93
|
+
f" npm install -g {PACKAGE_NAME}\n"
|
|
94
|
+
f" npx {PACKAGE_NAME} setup --agent codex --scope project --plan\n"
|
|
95
|
+
f"\n"
|
|
96
|
+
f"Common subcommands:\n"
|
|
97
|
+
f"{commands}\n"
|
|
98
|
+
f"\n"
|
|
99
|
+
f"Run '{COMMAND_NAME} <subcommand> --help' for helper-specific options.\n"
|
|
100
|
+
f"Installing ContextGuard never writes configuration; use 'setup' explicitly.\n"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def helper_path(name: str) -> Path | None:
|
|
105
|
+
script_dir = _script_dir()
|
|
106
|
+
candidates = [
|
|
107
|
+
script_dir / name,
|
|
108
|
+
script_dir.parent / "plugins" / "context-guard" / "bin" / name,
|
|
109
|
+
script_dir.parent.parent / "plugins" / "context-guard" / "bin" / name,
|
|
110
|
+
]
|
|
111
|
+
for candidate in candidates:
|
|
112
|
+
if candidate.is_file() and os.access(candidate, os.X_OK):
|
|
113
|
+
return candidate
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def fail(message: str, code: int = 2) -> NoReturn:
|
|
118
|
+
sys.stderr.write(f"{COMMAND_NAME}: {message}\n")
|
|
119
|
+
raise SystemExit(code)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def run_helper(command: str, argv: list[str]) -> int:
|
|
123
|
+
mapping = HELPER_SUBCOMMANDS[command]
|
|
124
|
+
helper = helper_path(mapping[0])
|
|
125
|
+
if helper is None:
|
|
126
|
+
fail(
|
|
127
|
+
f"could not find helper {mapping[0]!r}; reinstall {PACKAGE_NAME} "
|
|
128
|
+
"or run from a complete ContextGuard checkout."
|
|
129
|
+
)
|
|
130
|
+
proc = subprocess.run([str(helper), *mapping[1:], *argv])
|
|
131
|
+
return int(proc.returncode)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def main(argv: list[str] | None = None) -> int:
|
|
135
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
136
|
+
if not args or args[0] in {"-h", "--help", "help"}:
|
|
137
|
+
print_help()
|
|
138
|
+
return 0
|
|
139
|
+
if args[0] in {"-V", "--version", "version"}:
|
|
140
|
+
print(project_version())
|
|
141
|
+
return 0
|
|
142
|
+
command = args.pop(0).strip().lower()
|
|
143
|
+
if command not in HELPER_SUBCOMMANDS:
|
|
144
|
+
fail(f"unknown subcommand {command!r}. Run '{COMMAND_NAME} --help'.")
|
|
145
|
+
return run_helper(command, args)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
if __name__ == "__main__":
|
|
149
|
+
raise SystemExit(main())
|