@craftsamo/whatsapp-tools 0.1.0 → 0.1.2
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/.antigravity-plugin/plugin.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -1
- package/README.md +58 -12
- package/dist/cli.js +212 -146
- package/dist/mcp.js +206 -107
- package/dist/opencode.js +192 -105
- package/package.json +1 -1
- package/plugin.yaml +1 -1
- package/src/hermes/whatsapp_tools_hermes/approval.py +1 -6
- package/src/hermes/whatsapp_tools_hermes/plugin.py +2 -2
- package/src/hermes/whatsapp_tools_hermes/project.py +4 -4
- package/src/hermes/whatsapp_tools_hermes/settings.py +15 -69
|
@@ -24,64 +24,6 @@ def _names(key: str, value: Any) -> str | None:
|
|
|
24
24
|
return ",".join(value) or None
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def _directory_flags(ctx: PluginContext, key: str, flag: str) -> list[str]:
|
|
28
|
-
"""Read the directory setting ``key`` and return ``[flag, value]``, or ``[]`` when absent.
|
|
29
|
-
|
|
30
|
-
Raises:
|
|
31
|
-
SettingsError: the setting is present but not a non-empty string.
|
|
32
|
-
"""
|
|
33
|
-
value = ctx.get_config(key)
|
|
34
|
-
if value is None:
|
|
35
|
-
return []
|
|
36
|
-
if not isinstance(value, str) or not value.strip():
|
|
37
|
-
raise SettingsError(f'setting "{key}" must be a path')
|
|
38
|
-
return [flag, value]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def state_dir_flags(ctx: PluginContext) -> list[str]:
|
|
42
|
-
"""Read ``state_dir`` and return ``["--state-dir", value]``, or ``[]`` when absent.
|
|
43
|
-
|
|
44
|
-
Raises:
|
|
45
|
-
SettingsError: the setting is present but not a non-empty string.
|
|
46
|
-
"""
|
|
47
|
-
return _directory_flags(ctx, "state_dir", "--state-dir")
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def download_dir_flags(ctx: PluginContext) -> list[str]:
|
|
51
|
-
"""Read ``download_dir`` and return ``["--download-dir", value]``, or ``[]`` when absent.
|
|
52
|
-
|
|
53
|
-
Raises:
|
|
54
|
-
SettingsError: the setting is present but not a non-empty string.
|
|
55
|
-
"""
|
|
56
|
-
return _directory_flags(ctx, "download_dir", "--download-dir")
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _is_path_item(item: Any) -> bool:
|
|
60
|
-
"""Whether ``item`` is a non-empty string that survives the flag's comma-separated form whole."""
|
|
61
|
-
return isinstance(item, str) and bool(item.strip()) and "," not in item
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def send_dirs_flags(ctx: PluginContext) -> list[str]:
|
|
65
|
-
"""Read ``send_dirs`` and return ``["--send-dirs", "a,b"]``, or ``[]`` when absent or empty.
|
|
66
|
-
|
|
67
|
-
The flag is comma-separated, so a path holding a comma is refused rather than split in two.
|
|
68
|
-
|
|
69
|
-
Raises:
|
|
70
|
-
SettingsError: the setting is present but not a list of non-empty strings without commas.
|
|
71
|
-
"""
|
|
72
|
-
value = ctx.get_config("send_dirs")
|
|
73
|
-
if value is None:
|
|
74
|
-
return []
|
|
75
|
-
if not isinstance(value, list) or not all(_is_path_item(item) for item in value):
|
|
76
|
-
raise SettingsError('setting "send_dirs" must be a list of paths without commas')
|
|
77
|
-
return ["--send-dirs", ",".join(value)] if value else []
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def directory_flags(ctx: PluginContext) -> list[str]:
|
|
81
|
-
"""The flags of the directory settings, which is all the ``target`` command takes."""
|
|
82
|
-
return state_dir_flags(ctx) + download_dir_flags(ctx) + send_dirs_flags(ctx)
|
|
83
|
-
|
|
84
|
-
|
|
85
27
|
def language_setting(ctx: PluginContext) -> str | None:
|
|
86
28
|
"""The ``language`` setting, stripped; ``None`` when it is absent, blank or not a string.
|
|
87
29
|
|
|
@@ -105,11 +47,13 @@ def emoji_setting(ctx: PluginContext, defaults: Mapping[str, str] | None = None)
|
|
|
105
47
|
return merged
|
|
106
48
|
|
|
107
49
|
|
|
108
|
-
def _option_flag(name: str,
|
|
50
|
+
def _option_flag(name: str, declaration: str | dict[str, object], value: Any) -> list[str]:
|
|
51
|
+
kind = declaration["type"] if isinstance(declaration, dict) else declaration
|
|
109
52
|
flag = f"--{name.replace('_', '-')}"
|
|
110
|
-
if kind
|
|
53
|
+
if kind in ("text", "path"):
|
|
111
54
|
if not isinstance(value, str):
|
|
112
|
-
|
|
55
|
+
expected = "a path" if kind == "path" else "text"
|
|
56
|
+
raise SettingsError(f'setting "{name}" must be {expected}')
|
|
113
57
|
return [flag, text] if (text := value.strip()) else []
|
|
114
58
|
if kind == "boolean":
|
|
115
59
|
if not isinstance(value, bool):
|
|
@@ -119,21 +63,25 @@ def _option_flag(name: str, kind: str, value: Any) -> list[str]:
|
|
|
119
63
|
if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value):
|
|
120
64
|
raise SettingsError(f'setting "{name}" must be a finite number')
|
|
121
65
|
return [flag, str(value)]
|
|
122
|
-
if kind
|
|
66
|
+
if kind in ("list", "paths"):
|
|
123
67
|
if not isinstance(value, list) or not all(isinstance(item, str) and "," not in item for item in value):
|
|
124
|
-
|
|
68
|
+
expected = "paths" if kind == "paths" else "strings"
|
|
69
|
+
raise SettingsError(f'setting "{name}" must be a list of {expected} without commas')
|
|
125
70
|
items = [item.strip() for item in value if item.strip()]
|
|
126
71
|
return [flag, ",".join(items)] if items else []
|
|
127
72
|
raise SettingsError(f'unknown option type "{kind}" for "{name}"')
|
|
128
73
|
|
|
129
74
|
|
|
130
|
-
def option_flags(ctx: PluginContext, options: Mapping[str, str] | None = None) -> list[str]:
|
|
131
|
-
"""The package's tool options as flags, with absent settings left to the command line's environment.
|
|
75
|
+
def option_flags(ctx: PluginContext, options: Mapping[str, str | dict[str, object]] | None = None) -> list[str]:
|
|
76
|
+
"""The package's tool options as flags, with absent settings left to the command line's environment.
|
|
77
|
+
|
|
78
|
+
Bounds and path absoluteness are checked by the command line, not here.
|
|
79
|
+
"""
|
|
132
80
|
flags: list[str] = []
|
|
133
|
-
for name,
|
|
81
|
+
for name, declaration in (project.OPTIONS if options is None else options).items():
|
|
134
82
|
value = ctx.get_config(name)
|
|
135
83
|
if value is not None:
|
|
136
|
-
flags += _option_flag(name,
|
|
84
|
+
flags += _option_flag(name, declaration, value)
|
|
137
85
|
return flags
|
|
138
86
|
|
|
139
87
|
|
|
@@ -166,6 +114,4 @@ def settings_flags(ctx: PluginContext) -> list[str]:
|
|
|
166
114
|
if value is not None and (names := _names(key, value)):
|
|
167
115
|
flags += [flag, names]
|
|
168
116
|
|
|
169
|
-
flags += directory_flags(ctx)
|
|
170
|
-
|
|
171
117
|
return [*flags, *option_flags(ctx)]
|