@ictechgy/context-guard 0.4.10 → 0.4.12
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 +17 -1
- package/README.ko.md +46 -28
- package/README.md +42 -33
- package/docs/benchmark-fixtures/token-savings-12task.evidence.example.jsonl +24 -0
- package/docs/benchmark-workflow-examples.md +3 -0
- package/docs/benchmark-workflows/context-pack-byte-proxy.example.json +278 -137
- package/docs/benchmark-workflows/measured-token-workflow.example.json +279 -138
- package/docs/benchmark-workflows/provider-cache-telemetry.example.json +279 -138
- package/docs/experimental-benchmark-fixtures.md +24 -7
- package/package.json +2 -1
- package/plugins/context-guard/.claude-plugin/plugin.json +1 -1
- package/plugins/context-guard/README.ko.md +14 -11
- package/plugins/context-guard/README.md +15 -14
- package/plugins/context-guard/bin/context-guard +48 -17
- package/plugins/context-guard/bin/context-guard-artifact +342 -33
- package/plugins/context-guard/bin/context-guard-audit +36 -5
- package/plugins/context-guard/bin/context-guard-bench +1675 -44
- package/plugins/context-guard/bin/context-guard-cache-score +347 -35
- package/plugins/context-guard/bin/context-guard-compress +89 -27
- package/plugins/context-guard/bin/context-guard-cost +7 -2
- package/plugins/context-guard/bin/context-guard-experiments +364 -8
- package/plugins/context-guard/bin/context-guard-failed-nudge +6 -2
- package/plugins/context-guard/bin/context-guard-filter +88 -18
- package/plugins/context-guard/bin/context-guard-pack +329 -19
- package/plugins/context-guard/bin/context-guard-read-symbol +27 -0
- package/plugins/context-guard/bin/context-guard-sanitize-output +245 -18
- package/plugins/context-guard/bin/context-guard-setup +21 -5
- package/plugins/context-guard/bin/context-guard-tool-prune +287 -62
- package/plugins/context-guard/bin/context-guard-trim-output +394 -90
- package/plugins/context-guard/brief/README.md +5 -5
- package/plugins/context-guard/lib/context_guard_command_manifest_loader.py +123 -0
- package/plugins/context-guard/lib/context_guard_commands.py +217 -190
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# ContextGuard brief mode (advisory)
|
|
2
2
|
|
|
3
|
-
Brief mode is a set of **agent-neutral, advisory** rule snippets that ask a coding
|
|
4
|
-
agent to cut filler from its responses while preserving the technical evidence a
|
|
5
|
-
needs. It is guidance text, not an enforcement mechanism.
|
|
3
|
+
Brief mode is a set of **agent-neutral, advisory** rule snippets that ask a coding or
|
|
4
|
+
tool-using agent to cut filler from its responses while preserving the technical evidence a
|
|
5
|
+
reviewer needs. It is guidance text, not an enforcement mechanism.
|
|
6
6
|
|
|
7
7
|
- **Advisory / best-effort.** Compatible agents may follow these rules fully, partially, or
|
|
8
8
|
ignore them. Brief mode does not intercept, rewrite, or block model output.
|
|
9
9
|
- **No guaranteed savings.** Brief mode does **not** promise any token or cost reduction.
|
|
10
|
-
Verbosity behavior varies by agent and model. Measure real before
|
|
10
|
+
Verbosity behavior varies by agent and model. Measure real before-and-after results for your
|
|
11
11
|
own tasks with `context-guard-bench` before making any savings claim.
|
|
12
12
|
- **Evidence first.** Every level keeps the same mandatory evidence floor (see below). Brief
|
|
13
13
|
mode trims wording, never correctness-critical content.
|
|
@@ -56,7 +56,7 @@ context-guard setup --agent codex --scope project --brief-mode standard --yes
|
|
|
56
56
|
context-guard setup --agent codex --scope project --brief-mode off --yes
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
Per the project safety rules it stays dry-run first, writes only local files, backs up
|
|
59
|
+
Per the project safety rules, it stays dry-run first, writes only local files, backs up
|
|
60
60
|
existing rule files before changing anything, and applies only with explicit approval.
|
|
61
61
|
|
|
62
62
|
Each block is wrapped in stable markers:
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Trusted literal loader for the ContextGuard command manifest.
|
|
2
|
+
|
|
3
|
+
The command manifest is intentionally a literal-only Python data file so release
|
|
4
|
+
gates and runtime dispatchers can inspect it without executing manifest code.
|
|
5
|
+
This helper centralizes the bounded no-follow read and AST-literal parsing logic
|
|
6
|
+
used by the runtime dispatcher, release gates, and tests.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import ast
|
|
11
|
+
import os
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
import stat
|
|
14
|
+
from typing import Any, Iterable, Mapping
|
|
15
|
+
|
|
16
|
+
MAX_COMMAND_MANIFEST_BYTES = 128 * 1024
|
|
17
|
+
|
|
18
|
+
COMMAND_MANIFEST_LITERAL_NAMES = frozenset(
|
|
19
|
+
{
|
|
20
|
+
"IMPLEMENTATION_PAIRS",
|
|
21
|
+
"HELPER_PAIRS",
|
|
22
|
+
"NPM_BINS",
|
|
23
|
+
"NPM_BIN_PATHS",
|
|
24
|
+
"DISPATCHER_SUBCOMMANDS",
|
|
25
|
+
"LEGACY_WRAPPERS",
|
|
26
|
+
"ENTRYPOINT_SMOKE_CASES",
|
|
27
|
+
"PLUGIN_ENTRYPOINTS",
|
|
28
|
+
"DISPATCHER_SMOKE_CASES",
|
|
29
|
+
"EXPECTED_COMMAND_PACK_FILES",
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def manifest_open_flags() -> int | None:
|
|
35
|
+
if not hasattr(os, "O_NOFOLLOW"):
|
|
36
|
+
return None
|
|
37
|
+
flags = os.O_RDONLY | os.O_NOFOLLOW
|
|
38
|
+
if hasattr(os, "O_CLOEXEC"):
|
|
39
|
+
flags |= os.O_CLOEXEC
|
|
40
|
+
if hasattr(os, "O_NONBLOCK"):
|
|
41
|
+
flags |= os.O_NONBLOCK
|
|
42
|
+
if hasattr(os, "O_NOCTTY"):
|
|
43
|
+
flags |= os.O_NOCTTY
|
|
44
|
+
return flags
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def read_manifest_source(path: Path, *, max_bytes: int = MAX_COMMAND_MANIFEST_BYTES) -> str | None:
|
|
48
|
+
flags = manifest_open_flags()
|
|
49
|
+
if flags is None:
|
|
50
|
+
return None
|
|
51
|
+
fd = -1
|
|
52
|
+
try:
|
|
53
|
+
fd = os.open(path, flags)
|
|
54
|
+
st = os.fstat(fd)
|
|
55
|
+
if not stat.S_ISREG(st.st_mode) or st.st_size > max_bytes:
|
|
56
|
+
return None
|
|
57
|
+
chunks: list[bytes] = []
|
|
58
|
+
total = 0
|
|
59
|
+
while True:
|
|
60
|
+
chunk = os.read(fd, min(64 * 1024, max_bytes + 1 - total))
|
|
61
|
+
if not chunk:
|
|
62
|
+
break
|
|
63
|
+
chunks.append(chunk)
|
|
64
|
+
total += len(chunk)
|
|
65
|
+
if total > max_bytes:
|
|
66
|
+
return None
|
|
67
|
+
return b"".join(chunks).decode("utf-8")
|
|
68
|
+
except (OSError, UnicodeDecodeError):
|
|
69
|
+
return None
|
|
70
|
+
finally:
|
|
71
|
+
if fd >= 0:
|
|
72
|
+
try:
|
|
73
|
+
os.close(fd)
|
|
74
|
+
except OSError:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def literal_command_manifest_from_source(
|
|
79
|
+
source: str,
|
|
80
|
+
*,
|
|
81
|
+
allowed_names: Iterable[str] = COMMAND_MANIFEST_LITERAL_NAMES,
|
|
82
|
+
) -> dict[str, Any]:
|
|
83
|
+
try:
|
|
84
|
+
tree = ast.parse(source)
|
|
85
|
+
except SyntaxError as exc:
|
|
86
|
+
raise ValueError(f"invalid Python manifest syntax: line {exc.lineno}: {exc.msg}") from exc
|
|
87
|
+
allowed = set(allowed_names)
|
|
88
|
+
values: dict[str, Any] = {}
|
|
89
|
+
for node in tree.body:
|
|
90
|
+
if isinstance(node, ast.Expr) and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):
|
|
91
|
+
continue
|
|
92
|
+
target: str | None = None
|
|
93
|
+
value: ast.expr | None = None
|
|
94
|
+
if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
|
|
95
|
+
target = node.target.id
|
|
96
|
+
value = node.value
|
|
97
|
+
elif isinstance(node, ast.Assign) and len(node.targets) == 1 and isinstance(node.targets[0], ast.Name):
|
|
98
|
+
target = node.targets[0].id
|
|
99
|
+
value = node.value
|
|
100
|
+
if target is None:
|
|
101
|
+
raise ValueError(f"unsupported executable manifest statement: {type(node).__name__}")
|
|
102
|
+
if target not in allowed or value is None:
|
|
103
|
+
raise ValueError(f"unsupported manifest assignment: {target}")
|
|
104
|
+
try:
|
|
105
|
+
values[target] = ast.literal_eval(value)
|
|
106
|
+
except (SyntaxError, ValueError) as exc:
|
|
107
|
+
raise ValueError(f"manifest assignment must be a literal: {target}") from exc
|
|
108
|
+
return values
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def command_manifest_namespace(values: Mapping[str, Any], *, required: Iterable[str] = ()) -> type:
|
|
112
|
+
missing = sorted(set(required) - set(values))
|
|
113
|
+
if missing:
|
|
114
|
+
raise ValueError(f"trusted command manifest missing required literals: {', '.join(missing)}")
|
|
115
|
+
return type("CommandManifest", (), dict(values))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def load_command_manifest(path: Path, *, required: Iterable[str] = ()) -> type:
|
|
119
|
+
source = read_manifest_source(path)
|
|
120
|
+
if source is None:
|
|
121
|
+
raise ValueError(f"could not load trusted command manifest source: {path}")
|
|
122
|
+
values = literal_command_manifest_from_source(source)
|
|
123
|
+
return command_manifest_namespace(values, required=required)
|
|
@@ -1,206 +1,233 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
1
|
"""Canonical ContextGuard command/package manifest.
|
|
3
2
|
|
|
4
3
|
This module is intentionally side-effect free. It centralizes command, copy,
|
|
5
4
|
package, and smoke-test inventories that were previously repeated across the
|
|
6
5
|
runtime dispatcher, release gates, sync tooling, smoke tests, and unit tests.
|
|
7
6
|
"""
|
|
8
|
-
from __future__ import annotations
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
IMPLEMENTATION_PAIRS = (('context_guard_cli.py', 'context-guard'),
|
|
9
|
+
('cost_guard.py', 'context-guard-cost'),
|
|
10
|
+
('cache_score.py', 'context-guard-cache-score'),
|
|
11
|
+
('benchmark_runner.py', 'context-guard-bench'),
|
|
12
|
+
('context_escrow.py', 'context-guard-artifact'),
|
|
13
|
+
('context_compress.py', 'context-guard-compress'),
|
|
14
|
+
('context_pack.py', 'context-guard-pack'),
|
|
15
|
+
('context_filter.py', 'context-guard-filter'),
|
|
16
|
+
('tool_schema_pruner.py', 'context-guard-tool-prune'),
|
|
17
|
+
('claude_transcript_cost_audit.py', 'context-guard-audit'),
|
|
18
|
+
('context_guard_diet.py', 'context-guard-diet'),
|
|
19
|
+
('experimental_registry.py', 'context-guard-experiments'),
|
|
20
|
+
('failed_attempt_nudge.py', 'context-guard-failed-nudge'),
|
|
21
|
+
('guard_large_read.py', 'context-guard-guard-read'),
|
|
22
|
+
('read_symbol.py', 'context-guard-read-symbol'),
|
|
23
|
+
('rewrite_bash_for_token_budget.py', 'context-guard-rewrite-bash'),
|
|
24
|
+
('sanitize_output.py', 'context-guard-sanitize-output'),
|
|
25
|
+
('setup_wizard.py', 'context-guard-setup'),
|
|
26
|
+
('statusline.sh', 'context-guard-statusline'),
|
|
27
|
+
('statusline_merged.sh', 'context-guard-statusline-merged'),
|
|
28
|
+
('trim_command_output.py', 'context-guard-trim-output'))
|
|
11
29
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
("benchmark_runner.py", "context-guard-bench"),
|
|
17
|
-
("context_escrow.py", "context-guard-artifact"),
|
|
18
|
-
("context_compress.py", "context-guard-compress"),
|
|
19
|
-
("context_pack.py", "context-guard-pack"),
|
|
20
|
-
("context_filter.py", "context-guard-filter"),
|
|
21
|
-
("tool_schema_pruner.py", "context-guard-tool-prune"),
|
|
22
|
-
("claude_transcript_cost_audit.py", "context-guard-audit"),
|
|
23
|
-
("context_guard_diet.py", "context-guard-diet"),
|
|
24
|
-
("experimental_registry.py", "context-guard-experiments"),
|
|
25
|
-
("failed_attempt_nudge.py", "context-guard-failed-nudge"),
|
|
26
|
-
("guard_large_read.py", "context-guard-guard-read"),
|
|
27
|
-
("read_symbol.py", "context-guard-read-symbol"),
|
|
28
|
-
("rewrite_bash_for_token_budget.py", "context-guard-rewrite-bash"),
|
|
29
|
-
("sanitize_output.py", "context-guard-sanitize-output"),
|
|
30
|
-
("setup_wizard.py", "context-guard-setup"),
|
|
31
|
-
("statusline.sh", "context-guard-statusline"),
|
|
32
|
-
("statusline_merged.sh", "context-guard-statusline-merged"),
|
|
33
|
-
("trim_command_output.py", "context-guard-trim-output"),
|
|
34
|
-
)
|
|
30
|
+
HELPER_PAIRS = (('hook_secret_patterns.py', 'lib/hook_secret_patterns.py'),
|
|
31
|
+
('context_guard_commands.py', 'lib/context_guard_commands.py'),
|
|
32
|
+
('context_guard_command_manifest_loader.py',
|
|
33
|
+
'lib/context_guard_command_manifest_loader.py'))
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
NPM_BINS = ('context-guard',
|
|
36
|
+
'context-guard-cost',
|
|
37
|
+
'context-guard-cache-score',
|
|
38
|
+
'context-guard-bench',
|
|
39
|
+
'context-guard-artifact',
|
|
40
|
+
'context-guard-compress',
|
|
41
|
+
'context-guard-pack',
|
|
42
|
+
'context-guard-filter',
|
|
43
|
+
'context-guard-tool-prune',
|
|
44
|
+
'context-guard-audit',
|
|
45
|
+
'context-guard-diet',
|
|
46
|
+
'context-guard-experiments',
|
|
47
|
+
'context-guard-failed-nudge',
|
|
48
|
+
'context-guard-guard-read',
|
|
49
|
+
'context-guard-read-symbol',
|
|
50
|
+
'context-guard-rewrite-bash',
|
|
51
|
+
'context-guard-sanitize-output',
|
|
52
|
+
'context-guard-setup',
|
|
53
|
+
'context-guard-statusline',
|
|
54
|
+
'context-guard-statusline-merged',
|
|
55
|
+
'context-guard-trim-output')
|
|
40
56
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"context-guard-trim-output",
|
|
63
|
-
)
|
|
64
|
-
NPM_BIN_PATHS: dict[str, str] = {
|
|
65
|
-
name: f"plugins/context-guard/bin/{name}" for name in NPM_BINS
|
|
66
|
-
}
|
|
57
|
+
NPM_BIN_PATHS = {'context-guard': 'plugins/context-guard/bin/context-guard',
|
|
58
|
+
'context-guard-cost': 'plugins/context-guard/bin/context-guard-cost',
|
|
59
|
+
'context-guard-cache-score': 'plugins/context-guard/bin/context-guard-cache-score',
|
|
60
|
+
'context-guard-bench': 'plugins/context-guard/bin/context-guard-bench',
|
|
61
|
+
'context-guard-artifact': 'plugins/context-guard/bin/context-guard-artifact',
|
|
62
|
+
'context-guard-compress': 'plugins/context-guard/bin/context-guard-compress',
|
|
63
|
+
'context-guard-pack': 'plugins/context-guard/bin/context-guard-pack',
|
|
64
|
+
'context-guard-filter': 'plugins/context-guard/bin/context-guard-filter',
|
|
65
|
+
'context-guard-tool-prune': 'plugins/context-guard/bin/context-guard-tool-prune',
|
|
66
|
+
'context-guard-audit': 'plugins/context-guard/bin/context-guard-audit',
|
|
67
|
+
'context-guard-diet': 'plugins/context-guard/bin/context-guard-diet',
|
|
68
|
+
'context-guard-experiments': 'plugins/context-guard/bin/context-guard-experiments',
|
|
69
|
+
'context-guard-failed-nudge': 'plugins/context-guard/bin/context-guard-failed-nudge',
|
|
70
|
+
'context-guard-guard-read': 'plugins/context-guard/bin/context-guard-guard-read',
|
|
71
|
+
'context-guard-read-symbol': 'plugins/context-guard/bin/context-guard-read-symbol',
|
|
72
|
+
'context-guard-rewrite-bash': 'plugins/context-guard/bin/context-guard-rewrite-bash',
|
|
73
|
+
'context-guard-sanitize-output': 'plugins/context-guard/bin/context-guard-sanitize-output',
|
|
74
|
+
'context-guard-setup': 'plugins/context-guard/bin/context-guard-setup',
|
|
75
|
+
'context-guard-statusline': 'plugins/context-guard/bin/context-guard-statusline',
|
|
76
|
+
'context-guard-statusline-merged': 'plugins/context-guard/bin/context-guard-statusline-merged',
|
|
77
|
+
'context-guard-trim-output': 'plugins/context-guard/bin/context-guard-trim-output'}
|
|
67
78
|
|
|
68
|
-
DISPATCHER_SUBCOMMANDS:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"statusline-merged": ("context-guard-statusline-merged",),
|
|
95
|
-
}
|
|
79
|
+
DISPATCHER_SUBCOMMANDS = {'setup': ('context-guard-setup',),
|
|
80
|
+
'doctor': ('context-guard-setup', '--verify'),
|
|
81
|
+
'audit': ('context-guard-audit',),
|
|
82
|
+
'diet': ('context-guard-diet',),
|
|
83
|
+
'experiments': ('context-guard-experiments',),
|
|
84
|
+
'scan': ('context-guard-diet', 'scan'),
|
|
85
|
+
'trim-output': ('context-guard-trim-output',),
|
|
86
|
+
'trim': ('context-guard-trim-output',),
|
|
87
|
+
'sanitize-output': ('context-guard-sanitize-output',),
|
|
88
|
+
'sanitize': ('context-guard-sanitize-output',),
|
|
89
|
+
'filter': ('context-guard-filter',),
|
|
90
|
+
'artifact': ('context-guard-artifact',),
|
|
91
|
+
'pack': ('context-guard-pack',),
|
|
92
|
+
'tool-prune': ('context-guard-tool-prune',),
|
|
93
|
+
'compress': ('context-guard-compress',),
|
|
94
|
+
'cost': ('context-guard-cost',),
|
|
95
|
+
'route-advisor': ('context-guard-cost', 'route-advisor'),
|
|
96
|
+
'route': ('context-guard-cost', 'route-advisor'),
|
|
97
|
+
'cache-score': ('context-guard-cache-score',),
|
|
98
|
+
'bench': ('context-guard-bench',),
|
|
99
|
+
'read-symbol': ('context-guard-read-symbol',),
|
|
100
|
+
'rewrite-bash': ('context-guard-rewrite-bash',),
|
|
101
|
+
'guard-read': ('context-guard-guard-read',),
|
|
102
|
+
'failed-nudge': ('context-guard-failed-nudge',),
|
|
103
|
+
'statusline': ('context-guard-statusline',),
|
|
104
|
+
'statusline-merged': ('context-guard-statusline-merged',)}
|
|
96
105
|
|
|
97
|
-
LEGACY_WRAPPERS
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
"claude-trim-output",
|
|
111
|
-
)
|
|
106
|
+
LEGACY_WRAPPERS = ('claude-read-symbol',
|
|
107
|
+
'claude-sanitize-output',
|
|
108
|
+
'claude-token-artifact',
|
|
109
|
+
'claude-token-audit',
|
|
110
|
+
'claude-token-bench',
|
|
111
|
+
'claude-token-diet',
|
|
112
|
+
'claude-token-failed-nudge',
|
|
113
|
+
'claude-token-guard-read',
|
|
114
|
+
'claude-token-rewrite-bash',
|
|
115
|
+
'claude-token-setup',
|
|
116
|
+
'claude-token-statusline',
|
|
117
|
+
'claude-token-statusline-merged',
|
|
118
|
+
'claude-trim-output')
|
|
112
119
|
|
|
113
|
-
ENTRYPOINT_SMOKE_CASES:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
"claude-token-statusline-merged": {"args": [], "mode": "statusline"},
|
|
148
|
-
"claude-trim-output": {"args": ["--help"], "mode": "text"},
|
|
149
|
-
}
|
|
120
|
+
ENTRYPOINT_SMOKE_CASES = {'context-guard': {'args': ['--version'], 'mode': 'text'},
|
|
121
|
+
'context-guard-read-symbol': {'args': ['--help'], 'mode': 'text'},
|
|
122
|
+
'context-guard-sanitize-output': {'args': ['--help'], 'mode': 'text'},
|
|
123
|
+
'context-guard-artifact': {'args': ['--help'], 'mode': 'text'},
|
|
124
|
+
'context-guard-audit': {'args': ['--help'], 'mode': 'text'},
|
|
125
|
+
'context-guard-bench': {'args': ['--help'], 'mode': 'text'},
|
|
126
|
+
'context-guard-compress': {'args': ['--help'], 'mode': 'text'},
|
|
127
|
+
'context-guard-cost': {'args': ['--help'], 'mode': 'text'},
|
|
128
|
+
'context-guard-cache-score': {'args': ['--help'], 'mode': 'text'},
|
|
129
|
+
'context-guard-pack': {'args': ['--help'], 'mode': 'text'},
|
|
130
|
+
'context-guard-tool-prune': {'args': ['--help'], 'mode': 'text'},
|
|
131
|
+
'context-guard-diet': {'args': ['--help'], 'mode': 'text'},
|
|
132
|
+
'context-guard-experiments': {'args': ['--help'], 'mode': 'text'},
|
|
133
|
+
'context-guard-failed-nudge': {'args': [], 'mode': 'hook-json'},
|
|
134
|
+
'context-guard-filter': {'args': ['--help'], 'mode': 'text'},
|
|
135
|
+
'context-guard-guard-read': {'args': [], 'mode': 'hook-json'},
|
|
136
|
+
'context-guard-rewrite-bash': {'args': [], 'mode': 'hook-json'},
|
|
137
|
+
'context-guard-setup': {'args': ['--help'], 'mode': 'text'},
|
|
138
|
+
'context-guard-statusline': {'args': [], 'mode': 'statusline'},
|
|
139
|
+
'context-guard-statusline-merged': {'args': [], 'mode': 'statusline'},
|
|
140
|
+
'context-guard-trim-output': {'args': ['--help'], 'mode': 'text'},
|
|
141
|
+
'claude-read-symbol': {'args': ['--help'], 'mode': 'text'},
|
|
142
|
+
'claude-sanitize-output': {'args': ['--help'], 'mode': 'text'},
|
|
143
|
+
'claude-token-artifact': {'args': ['--help'], 'mode': 'text'},
|
|
144
|
+
'claude-token-audit': {'args': ['--help'], 'mode': 'text'},
|
|
145
|
+
'claude-token-bench': {'args': ['--help'], 'mode': 'text'},
|
|
146
|
+
'claude-token-diet': {'args': ['--help'], 'mode': 'text'},
|
|
147
|
+
'claude-token-failed-nudge': {'args': [], 'mode': 'hook-json'},
|
|
148
|
+
'claude-token-guard-read': {'args': [], 'mode': 'hook-json'},
|
|
149
|
+
'claude-token-rewrite-bash': {'args': [], 'mode': 'hook-json'},
|
|
150
|
+
'claude-token-setup': {'args': ['--help'], 'mode': 'text'},
|
|
151
|
+
'claude-token-statusline': {'args': [], 'mode': 'statusline'},
|
|
152
|
+
'claude-token-statusline-merged': {'args': [], 'mode': 'statusline'},
|
|
153
|
+
'claude-trim-output': {'args': ['--help'], 'mode': 'text'}}
|
|
150
154
|
|
|
151
|
-
PLUGIN_ENTRYPOINTS
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
"context-guard-trim-output",
|
|
186
|
-
)
|
|
155
|
+
PLUGIN_ENTRYPOINTS = ('claude-read-symbol',
|
|
156
|
+
'claude-sanitize-output',
|
|
157
|
+
'claude-token-artifact',
|
|
158
|
+
'claude-token-audit',
|
|
159
|
+
'claude-token-bench',
|
|
160
|
+
'claude-token-diet',
|
|
161
|
+
'claude-token-failed-nudge',
|
|
162
|
+
'claude-token-guard-read',
|
|
163
|
+
'claude-token-rewrite-bash',
|
|
164
|
+
'claude-token-setup',
|
|
165
|
+
'claude-token-statusline',
|
|
166
|
+
'claude-token-statusline-merged',
|
|
167
|
+
'claude-trim-output',
|
|
168
|
+
'context-guard',
|
|
169
|
+
'context-guard-artifact',
|
|
170
|
+
'context-guard-audit',
|
|
171
|
+
'context-guard-bench',
|
|
172
|
+
'context-guard-compress',
|
|
173
|
+
'context-guard-cost',
|
|
174
|
+
'context-guard-cache-score',
|
|
175
|
+
'context-guard-diet',
|
|
176
|
+
'context-guard-experiments',
|
|
177
|
+
'context-guard-failed-nudge',
|
|
178
|
+
'context-guard-filter',
|
|
179
|
+
'context-guard-guard-read',
|
|
180
|
+
'context-guard-pack',
|
|
181
|
+
'context-guard-read-symbol',
|
|
182
|
+
'context-guard-rewrite-bash',
|
|
183
|
+
'context-guard-sanitize-output',
|
|
184
|
+
'context-guard-setup',
|
|
185
|
+
'context-guard-statusline',
|
|
186
|
+
'context-guard-statusline-merged',
|
|
187
|
+
'context-guard-tool-prune',
|
|
188
|
+
'context-guard-trim-output')
|
|
187
189
|
|
|
188
|
-
DISPATCHER_SMOKE_CASES:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
{"entrypoint": "context-guard-pack", "args": ["auto", "--help"], "mode": "text"},
|
|
195
|
-
)
|
|
190
|
+
DISPATCHER_SMOKE_CASES = ({'entrypoint': 'context-guard', 'args': ['experiments', 'list', '--json'], 'mode': 'json'},
|
|
191
|
+
{'entrypoint': 'context-guard', 'args': ['cost', '--help'], 'mode': 'text'},
|
|
192
|
+
{'entrypoint': 'context-guard', 'args': ['route-advisor', '--help'], 'mode': 'text'},
|
|
193
|
+
{'entrypoint': 'context-guard', 'args': ['cache-score', '--help'], 'mode': 'text'},
|
|
194
|
+
{'entrypoint': 'context-guard-pack', 'args': ['suggest', '--help'], 'mode': 'text'},
|
|
195
|
+
{'entrypoint': 'context-guard-pack', 'args': ['auto', '--help'], 'mode': 'text'})
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
197
|
+
EXPECTED_COMMAND_PACK_FILES = ('plugins/context-guard/bin/claude-read-symbol',
|
|
198
|
+
'plugins/context-guard/bin/claude-sanitize-output',
|
|
199
|
+
'plugins/context-guard/bin/claude-token-artifact',
|
|
200
|
+
'plugins/context-guard/bin/claude-token-audit',
|
|
201
|
+
'plugins/context-guard/bin/claude-token-bench',
|
|
202
|
+
'plugins/context-guard/bin/claude-token-diet',
|
|
203
|
+
'plugins/context-guard/bin/claude-token-failed-nudge',
|
|
204
|
+
'plugins/context-guard/bin/claude-token-guard-read',
|
|
205
|
+
'plugins/context-guard/bin/claude-token-rewrite-bash',
|
|
206
|
+
'plugins/context-guard/bin/claude-token-setup',
|
|
207
|
+
'plugins/context-guard/bin/claude-token-statusline',
|
|
208
|
+
'plugins/context-guard/bin/claude-token-statusline-merged',
|
|
209
|
+
'plugins/context-guard/bin/claude-trim-output',
|
|
210
|
+
'plugins/context-guard/bin/context-guard',
|
|
211
|
+
'plugins/context-guard/bin/context-guard-artifact',
|
|
212
|
+
'plugins/context-guard/bin/context-guard-audit',
|
|
213
|
+
'plugins/context-guard/bin/context-guard-bench',
|
|
214
|
+
'plugins/context-guard/bin/context-guard-cache-score',
|
|
215
|
+
'plugins/context-guard/bin/context-guard-compress',
|
|
216
|
+
'plugins/context-guard/bin/context-guard-cost',
|
|
217
|
+
'plugins/context-guard/bin/context-guard-diet',
|
|
218
|
+
'plugins/context-guard/bin/context-guard-experiments',
|
|
219
|
+
'plugins/context-guard/bin/context-guard-failed-nudge',
|
|
220
|
+
'plugins/context-guard/bin/context-guard-filter',
|
|
221
|
+
'plugins/context-guard/bin/context-guard-guard-read',
|
|
222
|
+
'plugins/context-guard/bin/context-guard-pack',
|
|
223
|
+
'plugins/context-guard/bin/context-guard-read-symbol',
|
|
224
|
+
'plugins/context-guard/bin/context-guard-rewrite-bash',
|
|
225
|
+
'plugins/context-guard/bin/context-guard-sanitize-output',
|
|
226
|
+
'plugins/context-guard/bin/context-guard-setup',
|
|
227
|
+
'plugins/context-guard/bin/context-guard-statusline',
|
|
228
|
+
'plugins/context-guard/bin/context-guard-statusline-merged',
|
|
229
|
+
'plugins/context-guard/bin/context-guard-tool-prune',
|
|
230
|
+
'plugins/context-guard/bin/context-guard-trim-output',
|
|
231
|
+
'plugins/context-guard/lib/context_guard_command_manifest_loader.py',
|
|
232
|
+
'plugins/context-guard/lib/context_guard_commands.py',
|
|
233
|
+
'plugins/context-guard/lib/hook_secret_patterns.py')
|