anolisa-tokenless 0.7.7

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 (70) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +770 -0
  3. package/adapters/tokenless/claude-code/.claude-plugin/marketplace.json +15 -0
  4. package/adapters/tokenless/claude-code/.claude-plugin/plugin.json +9 -0
  5. package/adapters/tokenless/claude-code/hooks/hooks.json +38 -0
  6. package/adapters/tokenless/claude-code/scripts/detect.sh +193 -0
  7. package/adapters/tokenless/claude-code/scripts/install.sh +92 -0
  8. package/adapters/tokenless/claude-code/scripts/uninstall.sh +50 -0
  9. package/adapters/tokenless/codex/.codex-plugin/plugin.json +20 -0
  10. package/adapters/tokenless/codex/README.md +160 -0
  11. package/adapters/tokenless/codex/hooks/hooks.json +52 -0
  12. package/adapters/tokenless/codex/scripts/_common.sh +25 -0
  13. package/adapters/tokenless/codex/scripts/check-tokenless +94 -0
  14. package/adapters/tokenless/codex/scripts/compress-response +441 -0
  15. package/adapters/tokenless/codex/scripts/detect.sh +61 -0
  16. package/adapters/tokenless/codex/scripts/install.sh +151 -0
  17. package/adapters/tokenless/codex/scripts/rewrite-hook +282 -0
  18. package/adapters/tokenless/codex/scripts/tool-ready +303 -0
  19. package/adapters/tokenless/codex/scripts/uninstall.sh +78 -0
  20. package/adapters/tokenless/common/commands/tokenless-stats.toml +2 -0
  21. package/adapters/tokenless/common/cosh-extension.json +65 -0
  22. package/adapters/tokenless/common/hooks/compress_response_hook.py +487 -0
  23. package/adapters/tokenless/common/hooks/compress_schema_hook.py +144 -0
  24. package/adapters/tokenless/common/hooks/compress_toon_hook.py +160 -0
  25. package/adapters/tokenless/common/hooks/hook_utils.py +584 -0
  26. package/adapters/tokenless/common/hooks/rewrite_hook.py +223 -0
  27. package/adapters/tokenless/common/hooks/run-hook.sh +62 -0
  28. package/adapters/tokenless/common/hooks/tool_categories.json +99 -0
  29. package/adapters/tokenless/common/hooks/tool_ready_hook.sh +571 -0
  30. package/adapters/tokenless/common/tokenless-env-fix.sh +730 -0
  31. package/adapters/tokenless/common/tool-ready-spec.json +113 -0
  32. package/adapters/tokenless/dsh/cordis.patch.yml +8 -0
  33. package/adapters/tokenless/dsh/dist/index.js +399 -0
  34. package/adapters/tokenless/dsh/package.json +26 -0
  35. package/adapters/tokenless/hermes/__init__.py +572 -0
  36. package/adapters/tokenless/hermes/plugin.yaml +9 -0
  37. package/adapters/tokenless/hermes/scripts/detect.sh +80 -0
  38. package/adapters/tokenless/hermes/scripts/install.sh +60 -0
  39. package/adapters/tokenless/hermes/scripts/uninstall.sh +45 -0
  40. package/adapters/tokenless/manifest.json +147 -0
  41. package/adapters/tokenless/openclaw/dist/index.d.ts +27 -0
  42. package/adapters/tokenless/openclaw/dist/index.js +598 -0
  43. package/adapters/tokenless/openclaw/dist/tool_categories.json +99 -0
  44. package/adapters/tokenless/openclaw/index.ts +720 -0
  45. package/adapters/tokenless/openclaw/openclaw.plugin.json +40 -0
  46. package/adapters/tokenless/openclaw/package.json +24 -0
  47. package/adapters/tokenless/openclaw/scripts/detect.sh +102 -0
  48. package/adapters/tokenless/openclaw/scripts/install.sh +75 -0
  49. package/adapters/tokenless/openclaw/scripts/uninstall.sh +46 -0
  50. package/adapters/tokenless/openclaw/tsconfig.json +13 -0
  51. package/adapters/tokenless/opencode/plugin.js +246 -0
  52. package/adapters/tokenless/opencode/scripts/detect.sh +38 -0
  53. package/adapters/tokenless/opencode/scripts/install.sh +56 -0
  54. package/adapters/tokenless/opencode/scripts/uninstall.sh +29 -0
  55. package/adapters/tokenless/qoder/.qoder-plugin/plugin.json +11 -0
  56. package/adapters/tokenless/qoder/commands/tokenless-stats.md +8 -0
  57. package/adapters/tokenless/qoder/hooks/hooks.json +36 -0
  58. package/adapters/tokenless/qoder/hooks/run-hook.sh +51 -0
  59. package/adapters/tokenless/qoder/scripts/detect.sh +35 -0
  60. package/adapters/tokenless/qoder/scripts/install.sh +136 -0
  61. package/adapters/tokenless/qoder/scripts/uninstall.sh +106 -0
  62. package/adapters/tokenless/qwencode/qwen-extension.json +69 -0
  63. package/adapters/tokenless/qwencode/scripts/detect.sh +125 -0
  64. package/adapters/tokenless/qwencode/scripts/install.sh +128 -0
  65. package/adapters/tokenless/qwencode/scripts/uninstall.sh +62 -0
  66. package/bin/rtk +6 -0
  67. package/bin/tokenless +6 -0
  68. package/bin/toon +6 -0
  69. package/package.json +57 -0
  70. package/scripts/postinstall.js +208 -0
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env python3
2
+ """Tokenless standalone TOON encoding hook.
3
+
4
+ Reads a PostToolUse JSON from stdin, encodes the tool response
5
+ to TOON format via ``tokenless compress-toon``, and writes a
6
+ HookOutput JSON to stdout.
7
+
8
+ This is a standalone TOON-only hook for users who want pure TOON
9
+ encoding without response compression. The combined pipeline
10
+ (response compression + TOON) is in compress_response_hook.py.
11
+
12
+ Hook point: **PostToolUse**
13
+
14
+ The agent ID is read from the TOKENLESS_AGENT_ID environment variable
15
+ (set by the install action script).
16
+ """
17
+
18
+ import json
19
+ import os
20
+ import subprocess
21
+ import sys
22
+
23
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
24
+
25
+ from hook_utils import (
26
+ _TOKENLESS_FALLBACK,
27
+ _TOKENLESS_LOCAL_LIB,
28
+ _TOKENLESS_LOCAL_SHARE,
29
+ CONTENT_RETRIEVAL_TOOLS,
30
+ is_skill_file,
31
+ resolve_agent_id,
32
+ resolve_binary,
33
+ skip,
34
+ try_parse_json,
35
+ unwrap_string_json,
36
+ warn,
37
+ )
38
+
39
+ # -- constants ---------------------------------------------------------------
40
+
41
+ _AGENT_ID = resolve_agent_id()
42
+ _MIN_RESPONSE_CHARS = 200
43
+
44
+
45
+ # -- main --------------------------------------------------------------------
46
+
47
+
48
+ def main() -> None:
49
+ # 1. Resolve binaries
50
+ tokenless_bin = resolve_binary(
51
+ "tokenless",
52
+ _TOKENLESS_FALLBACK,
53
+ _TOKENLESS_LOCAL_SHARE,
54
+ _TOKENLESS_LOCAL_LIB,
55
+ )
56
+ if not tokenless_bin:
57
+ warn("tokenless is not installed. TOON compression hook disabled.")
58
+ skip()
59
+
60
+ # 2. Read stdin JSON
61
+ try:
62
+ input_data = json.load(sys.stdin)
63
+ except (json.JSONDecodeError, EOFError, ValueError):
64
+ warn("failed to read PostToolUse payload. Passing through unchanged.")
65
+ skip()
66
+
67
+ # 3. Skip content-retrieval tools (preserve integrity)
68
+ tool_name = input_data.get("tool_name", "unknown")
69
+ if tool_name in CONTENT_RETRIEVAL_TOOLS:
70
+ skip()
71
+
72
+ # 4. Extract tool_response
73
+ tool_response_raw = input_data.get("tool_response", "")
74
+ if not tool_response_raw or tool_response_raw == "{}":
75
+ skip()
76
+
77
+ # 5. Skip skill files (YAML frontmatter)
78
+ if isinstance(tool_response_raw, str) and is_skill_file(tool_response_raw):
79
+ skip()
80
+
81
+ # 6. Normalize: unwrap string-wrapped JSON
82
+ if isinstance(tool_response_raw, str):
83
+ tool_response = unwrap_string_json(tool_response_raw)
84
+ if tool_response is None:
85
+ skip() # Plain text, not JSON
86
+ elif isinstance(tool_response_raw, (dict, list)):
87
+ tool_response = json.dumps(tool_response_raw, separators=(",", ":"))
88
+ else:
89
+ skip()
90
+
91
+ if not tool_response:
92
+ skip()
93
+
94
+ # 7. Skip small responses (character count, not byte length)
95
+ if len(tool_response) < _MIN_RESPONSE_CHARS:
96
+ skip()
97
+
98
+ # 8. Validate it's JSON
99
+ parsed = try_parse_json(tool_response)
100
+ if parsed is None:
101
+ skip()
102
+
103
+ # 9. Extract caller context
104
+ session_id = input_data.get("session_id", "")
105
+ tool_use_id = input_data.get("tool_use_id") or input_data.get(
106
+ "toolCallId", ""
107
+ )
108
+
109
+ # 10. Encode to TOON via tokenless compress-toon
110
+ cmd = [tokenless_bin, "compress-toon", "--agent-id", _AGENT_ID]
111
+ if session_id:
112
+ cmd.extend(["--session-id", session_id])
113
+ if tool_use_id:
114
+ cmd.extend(["--tool-use-id", tool_use_id])
115
+
116
+ try:
117
+ proc = subprocess.run(
118
+ cmd,
119
+ input=tool_response,
120
+ capture_output=True,
121
+ text=True,
122
+ timeout=10,
123
+ )
124
+ except Exception as e:
125
+ warn(f"TOON encoding failed: {e}. Passing through unchanged.")
126
+ skip()
127
+
128
+ if proc.returncode != 0:
129
+ detail = (proc.stderr or "").strip()[:200]
130
+ warn(
131
+ f"TOON encoding exited with code {proc.returncode}: {detail}"
132
+ if detail
133
+ else f"TOON encoding exited with code {proc.returncode}. Passing through unchanged."
134
+ )
135
+ skip()
136
+
137
+ toon_output = proc.stdout.strip()
138
+ if not toon_output:
139
+ warn("TOON encoding returned empty output. Passing through unchanged.")
140
+ skip()
141
+
142
+ # 11. Size guard — skip if TOON output is not smaller
143
+ before_chars = len(tool_response)
144
+ after_chars = len(toon_output)
145
+ if after_chars >= before_chars:
146
+ skip()
147
+
148
+ # 12. Build response
149
+ output = {
150
+ "suppressOutput": True,
151
+ "hookSpecificOutput": {
152
+ "hookEventName": "PostToolUse",
153
+ "additionalContext": toon_output,
154
+ },
155
+ }
156
+ print(json.dumps(output, ensure_ascii=False))
157
+
158
+
159
+ if __name__ == "__main__":
160
+ main()