lithermes-ai 0.8.3 → 0.8.5
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/README.md +1 -1
- package/README_Ko-KR.md +1 -1
- package/assets/lithermes-plugin/README.md +4 -4
- package/assets/lithermes-plugin/__init__.py +40 -3
- package/assets/lithermes-plugin/core.py +104 -0
- package/assets/lithermes-plugin/payload-version.json +151 -7
- package/assets/lithermes-plugin/plugin.yaml +1 -1
- package/assets/lithermes-plugin/skills/debugging/SKILL.md +42 -0
- package/assets/lithermes-plugin/skills/litresearch/SKILL.md +241 -0
- package/assets/lithermes-plugin/skills/lsp-setup/SKILL.md +153 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/bash/README.md +68 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/c-cpp/README.md +78 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/csharp/README.md +90 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/dart/README.md +59 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/elixir/README.md +61 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/go/README.md +63 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/haskell/README.md +69 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/java/README.md +70 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/julia/README.md +70 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/kotlin/README.md +72 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/lua/README.md +68 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/php/README.md +61 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/python/README.md +73 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/ruby/README.md +67 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/rust/README.md +65 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/swift/README.md +64 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/terraform/README.md +66 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/typescript/README.md +82 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/yaml/README.md +65 -0
- package/assets/lithermes-plugin/skills/lsp-setup/references/zig/README.md +59 -0
- package/assets/lithermes-plugin/skills/lsp-setup/scripts/detect-lsp.ts +221 -0
- package/assets/lithermes-plugin/skills/lsp-setup/scripts/lsp-server-table.ts +146 -0
- package/assets/lithermes-plugin/skills/lsp-setup/scripts/tsconfig.json +18 -0
- package/assets/lithermes-plugin/skills/lsp-setup/scripts/verify-lsp.ts +252 -0
- package/assets/lithermes-plugin/skills/visual-qa/SKILL.md +282 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/ansi.ts +17 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/cli.ts +96 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/east-asian-width.ts +72 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/image-diff.ts +109 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/png-crc.ts +27 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/png-decode.ts +206 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/png-synth.ts +57 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/tui-grid.ts +88 -0
- package/assets/lithermes-plugin/skills/visual-qa/scripts/types.ts +54 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ Restart any running Hermes CLI or Hermes gateway process. Then open Hermes and t
|
|
|
59
59
|
- LitHermes workflow skill set: `ai-slop-remover`, `comment-checker`,
|
|
60
60
|
`debugging`, `deep-interview`, `frontend-ui-ux`, `git-master`, `init-deep`,
|
|
61
61
|
`lsp`, `programming`, `refactor`,
|
|
62
|
-
`remove-ai-slops`, `review-work`, `rules`, `start-work`, `lit-plan`,
|
|
62
|
+
`remove-ai-slops`, `review-work`, `rules`, `visual-qa`, `lsp-setup`, `litresearch`, `start-work`, `lit-plan`,
|
|
63
63
|
`litgoal`, and `litwork` are installed as `lithermes:*` skills.
|
|
64
64
|
- The full plugin payload — the `pre_llm_call` / `subagent_stop` hooks, every
|
|
65
65
|
skill, and the durable goal tooling — ships in the bundle exactly as installed,
|
package/README_Ko-KR.md
CHANGED
|
@@ -59,7 +59,7 @@ npx lithermes-ai install --yes
|
|
|
59
59
|
- LitHermes workflow skill set: `ai-slop-remover`, `comment-checker`,
|
|
60
60
|
`debugging`, `deep-interview`, `frontend-ui-ux`, `git-master`, `init-deep`,
|
|
61
61
|
`lsp`, `programming`, `refactor`,
|
|
62
|
-
`remove-ai-slops`, `review-work`, `rules`, `start-work`, `lit-plan`,
|
|
62
|
+
`remove-ai-slops`, `review-work`, `rules`, `visual-qa`, `lsp-setup`, `litresearch`, `start-work`, `lit-plan`,
|
|
63
63
|
`litgoal`, `litwork`가 `lithermes:*` skill로 함께 설치됩니다.
|
|
64
64
|
- 전체 plugin payload — `pre_llm_call` / `subagent_stop`
|
|
65
65
|
hook, 모든 skill, durable goal tooling — 이 설치 상태 그대로 번들에 들어가므로,
|
|
@@ -16,11 +16,11 @@ first-class Hermes skills:
|
|
|
16
16
|
`lithermes:ai-slop-remover`, `lithermes:comment-checker`,
|
|
17
17
|
`lithermes:debugging`, `lithermes:deep-interview`,
|
|
18
18
|
`lithermes:frontend-ui-ux`, `lithermes:git-master`,
|
|
19
|
-
`lithermes:init-deep`, `lithermes:lsp`,
|
|
20
|
-
`lithermes:programming`, `lithermes:refactor`,
|
|
19
|
+
`lithermes:init-deep`, `lithermes:lsp`, `lithermes:lsp-setup`,
|
|
20
|
+
`lithermes:litresearch`, `lithermes:programming`, `lithermes:refactor`,
|
|
21
21
|
`lithermes:remove-ai-slops`, `lithermes:review-work`,
|
|
22
|
-
`lithermes:rules`, `lithermes:start-work`, `lithermes:
|
|
23
|
-
`lithermes:litgoal`, and `lithermes:litwork`.
|
|
22
|
+
`lithermes:rules`, `lithermes:start-work`, `lithermes:visual-qa`,
|
|
23
|
+
`lithermes:lit-plan`, `lithermes:litgoal`, and `lithermes:litwork`.
|
|
24
24
|
- Delegation fans lanes out through the native `delegate_task` tool (children
|
|
25
25
|
run in parallel, the parent blocks for all); there is no named-agent registry
|
|
26
26
|
and no per-child model selection.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import argparse
|
|
3
4
|
import functools
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Any
|
|
@@ -79,6 +80,18 @@ PORTED_SKILLS = [
|
|
|
79
80
|
"litwork",
|
|
80
81
|
"Hermes-native Litwork execution discipline.",
|
|
81
82
|
),
|
|
83
|
+
(
|
|
84
|
+
"visual-qa",
|
|
85
|
+
"Rigorously verify any web/TUI UI you built or changed with screenshot/terminal diffs and oracle passes.",
|
|
86
|
+
),
|
|
87
|
+
(
|
|
88
|
+
"lsp-setup",
|
|
89
|
+
"Configure a language server for LitHermes LSP diagnostics across 20+ languages.",
|
|
90
|
+
),
|
|
91
|
+
(
|
|
92
|
+
"litresearch",
|
|
93
|
+
"Run the LitHermes maximum-saturation research orchestrator: decompose, parallel delegate_task swarms, verify, synthesize cited.",
|
|
94
|
+
),
|
|
82
95
|
]
|
|
83
96
|
|
|
84
97
|
|
|
@@ -104,16 +117,40 @@ def _pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
|
104
117
|
|
|
105
118
|
|
|
106
119
|
def _setup_lithermes_cli(parser) -> None:
|
|
120
|
+
try:
|
|
121
|
+
parser.formatter_class = argparse.RawDescriptionHelpFormatter
|
|
122
|
+
except Exception:
|
|
123
|
+
pass
|
|
124
|
+
parser.description = "LitHermes — Hermes-native Litwork toolkit (litgoal runtime, skills, hooks)."
|
|
125
|
+
parser.epilog = (
|
|
126
|
+
"slash commands: /lit /lit-loop /lit-plan /litgoal /review-work /start-work /deep-interview\n"
|
|
127
|
+
"skills: 20 lithermes:* skills — `hermes lithermes status` lists them\n"
|
|
128
|
+
"hooks: pre_llm_call, subagent_stop, transform_llm_output\n"
|
|
129
|
+
"run `hermes lithermes status` for versions + full surface, or `doctor` for health checks"
|
|
130
|
+
)
|
|
131
|
+
parser.add_argument("--version", action="store_true", help="print the LitHermes plugin version")
|
|
107
132
|
sub = parser.add_subparsers(dest="lh_cmd")
|
|
133
|
+
sub.add_parser("version", help="print the LitHermes plugin version")
|
|
134
|
+
sub.add_parser("status", help="show LitHermes + Hermes versions, hooks, commands, skills")
|
|
135
|
+
sub.add_parser("doctor", help="run LitHermes health checks")
|
|
108
136
|
goal_parser = sub.add_parser("goal", help="LitHermes litgoal durable runtime")
|
|
109
137
|
litgoal_cli.setup(goal_parser)
|
|
110
138
|
|
|
111
139
|
|
|
112
140
|
def _handle_lithermes_cli(args) -> int:
|
|
113
|
-
|
|
141
|
+
cmd = getattr(args, "lh_cmd", None)
|
|
142
|
+
if getattr(args, "version", False) or cmd == "version":
|
|
143
|
+
print(core.version_line())
|
|
144
|
+
return 0
|
|
145
|
+
if cmd == "doctor":
|
|
146
|
+
lines, code = core.doctor_report()
|
|
147
|
+
print("\n".join(lines))
|
|
148
|
+
return code
|
|
149
|
+
if cmd == "goal":
|
|
114
150
|
return litgoal_cli.handle(args)
|
|
115
|
-
|
|
116
|
-
|
|
151
|
+
# status, or bare `hermes lithermes` → the most useful "who am I" answer
|
|
152
|
+
print(core.status_report())
|
|
153
|
+
return 0
|
|
117
154
|
|
|
118
155
|
|
|
119
156
|
def _ignited(handler):
|
|
@@ -981,3 +981,107 @@ def command_start_work(raw_args: str) -> str | dict[str, str]:
|
|
|
981
981
|
"display": display,
|
|
982
982
|
"agent_message": build_run_agent_message(load_run_state(run_dir)),
|
|
983
983
|
}
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
# ---------------------------------------------------------------------------
|
|
987
|
+
# Management / diagnostics surface (hermes lithermes version|status|doctor).
|
|
988
|
+
# Hermes plugins otherwise can't answer "who am I and what version" — these
|
|
989
|
+
# helpers back the CLI subcommands wired in __init__.py.
|
|
990
|
+
# ---------------------------------------------------------------------------
|
|
991
|
+
|
|
992
|
+
PLUGIN_ROOT = Path(__file__).resolve().parent
|
|
993
|
+
# These mirror what register()/register_hook()/litgoal tools wire up in __init__.py.
|
|
994
|
+
# They are hardcoded (not introspected) so `status` works without a live ctx —
|
|
995
|
+
# keep them in sync when adding a hook / slash command / goal tool.
|
|
996
|
+
HOOKS = ("pre_llm_call", "subagent_stop", "transform_llm_output")
|
|
997
|
+
SLASH_COMMANDS = (
|
|
998
|
+
"lit", "lit-loop", "lit-plan", "litgoal", "review-work",
|
|
999
|
+
"start-work", "deep-interview", "litwork-loop", "litwork-plan",
|
|
1000
|
+
)
|
|
1001
|
+
GOAL_TOOLS = (
|
|
1002
|
+
"goal_set", "goal_status", "goal_add_criterion", "goal_evidence",
|
|
1003
|
+
"goal_criterion_status", "goal_steer", "goal_checkpoint", "goal_complete",
|
|
1004
|
+
)
|
|
1005
|
+
_VERSION_RE = re.compile(r"^version:\s*(.+)$", re.MULTILINE)
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
def plugin_version() -> str:
|
|
1009
|
+
"""Read the LitHermes plugin version from the bundled plugin.yaml."""
|
|
1010
|
+
try:
|
|
1011
|
+
m = _VERSION_RE.search((PLUGIN_ROOT / "plugin.yaml").read_text(encoding="utf-8"))
|
|
1012
|
+
return m.group(1).strip().strip("\"'") if m else "unknown"
|
|
1013
|
+
except (OSError, ValueError):
|
|
1014
|
+
return "unknown"
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
def hermes_host_version() -> str:
|
|
1018
|
+
"""Best-effort Hermes host runtime version (unknown outside Hermes)."""
|
|
1019
|
+
try:
|
|
1020
|
+
import hermes_cli
|
|
1021
|
+
return str(getattr(hermes_cli, "__version__", "") or "unknown")
|
|
1022
|
+
except Exception:
|
|
1023
|
+
return "unknown"
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
def version_line() -> str:
|
|
1027
|
+
return f"lithermes {plugin_version()}"
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
def _evidence_kinds() -> tuple[str, ...]:
|
|
1031
|
+
try:
|
|
1032
|
+
from .litgoal import model
|
|
1033
|
+
return tuple(model.EVIDENCE_KINDS)
|
|
1034
|
+
except Exception:
|
|
1035
|
+
return ("red", "green", "scenario", "cleanup", "note")
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
def _skill_names() -> list[str]:
|
|
1039
|
+
skills_dir = PLUGIN_ROOT / "skills"
|
|
1040
|
+
if not skills_dir.is_dir():
|
|
1041
|
+
return []
|
|
1042
|
+
return sorted(d.name for d in skills_dir.iterdir() if (d / "SKILL.md").is_file())
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
def status_report() -> str:
|
|
1046
|
+
"""One-glance health/identity line for `hermes lithermes status`."""
|
|
1047
|
+
skills = _skill_names()
|
|
1048
|
+
return "\n".join([
|
|
1049
|
+
f"LitHermes plugin {plugin_version()} (Hermes host {hermes_host_version()})",
|
|
1050
|
+
f"plugin dir: {PLUGIN_ROOT}",
|
|
1051
|
+
f"hooks ({len(HOOKS)}): {', '.join(HOOKS)}",
|
|
1052
|
+
f"slash commands ({len(SLASH_COMMANDS)}): {', '.join('/' + c for c in SLASH_COMMANDS)}",
|
|
1053
|
+
f"skills ({len(skills)}): {', '.join(skills)}",
|
|
1054
|
+
f"goal tools ({len(GOAL_TOOLS)}): {', '.join(GOAL_TOOLS)}",
|
|
1055
|
+
"litgoal state: .hermes/lithermes/litgoal/ (drive via: hermes lithermes goal status)",
|
|
1056
|
+
f"litgoal evidence kinds: {', '.join(_evidence_kinds())}",
|
|
1057
|
+
])
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
def doctor_report() -> tuple[list[str], int]:
|
|
1061
|
+
"""Health checks for `hermes lithermes doctor`. Returns (lines, exit_code)."""
|
|
1062
|
+
lines: list[str] = []
|
|
1063
|
+
ok = True
|
|
1064
|
+
ver = plugin_version()
|
|
1065
|
+
if ver != "unknown":
|
|
1066
|
+
lines.append(f"[OK] plugin.yaml readable (version {ver})")
|
|
1067
|
+
else:
|
|
1068
|
+
lines.append("[WARN] plugin.yaml unreadable or missing a version field")
|
|
1069
|
+
ok = False
|
|
1070
|
+
skills = _skill_names()
|
|
1071
|
+
if skills:
|
|
1072
|
+
lines.append(f"[OK] skills bundled: {len(skills)}")
|
|
1073
|
+
else:
|
|
1074
|
+
lines.append("[WARN] no skills found under skills/")
|
|
1075
|
+
ok = False
|
|
1076
|
+
try:
|
|
1077
|
+
from .litgoal import runtime as _rt # noqa: F401
|
|
1078
|
+
lines.append("[OK] litgoal durable runtime importable")
|
|
1079
|
+
except Exception as exc:
|
|
1080
|
+
lines.append(f"[WARN] litgoal runtime import failed: {exc}")
|
|
1081
|
+
ok = False
|
|
1082
|
+
hv = hermes_host_version()
|
|
1083
|
+
if hv != "unknown":
|
|
1084
|
+
lines.append(f"[OK] Hermes host detected (v{hv})")
|
|
1085
|
+
else:
|
|
1086
|
+
lines.append("[NOTE] Hermes host version unknown (running outside Hermes?)")
|
|
1087
|
+
return lines, (0 if ok else 1)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"syncedAt": "2026-06-
|
|
2
|
+
"syncedAt": "2026-06-15T16:35:55.443Z",
|
|
3
3
|
"source": "source-reference",
|
|
4
|
-
"sourceHash": "
|
|
4
|
+
"sourceHash": "c93c37881e1f6f5730a1adc6c0e62e4dfab1ca44146eed900b8468448438fe8a",
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
7
7
|
"path": "NOTICE.md",
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "README.md",
|
|
12
|
-
"sha256": "
|
|
12
|
+
"sha256": "29f9157e4aa5a667c0d4c2df30d803c4eaa8cc4b30937c84ac1a08b8257e1eca"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "__init__.py",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "96b816aee730ea9a5e1fedbc283829240baffddecc37872e4f60bb05f420366c"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "core.py",
|
|
20
|
-
"sha256": "
|
|
20
|
+
"sha256": "70ddccfb4cc2fe1a923a5a61244e5cb36ef8ac0f94d34a76703fa6d82dbabf3f"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"path": "litgoal/__init__.py",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"path": "plugin.yaml",
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "7761c417acfcd614e8d434b3ca11c498f48422a72f5b70f817a59326aca51b60"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "skills/ai-slop-remover/SKILL.md",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"path": "skills/debugging/SKILL.md",
|
|
64
|
-
"sha256": "
|
|
64
|
+
"sha256": "48bdb0df0f41633aca17d6193aa98aabac4c49cc25c36e50f26b020f89f77d43"
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"path": "skills/debugging/references/methodology/00-setup.md",
|
|
@@ -163,10 +163,114 @@
|
|
|
163
163
|
"path": "skills/litgoal/SKILL.md",
|
|
164
164
|
"sha256": "7a1fc23afe57f957a063a70b1bf810dc9c66fd44bcfd93b1ec739d59167e5ad9"
|
|
165
165
|
},
|
|
166
|
+
{
|
|
167
|
+
"path": "skills/litresearch/SKILL.md",
|
|
168
|
+
"sha256": "3ff390e7a5847aebfa8943fe593fa386f9aeab2716fb30f7b20feaa3990f311f"
|
|
169
|
+
},
|
|
166
170
|
{
|
|
167
171
|
"path": "skills/litwork/SKILL.md",
|
|
168
172
|
"sha256": "625e8ed44365d5ebcab9b8a3a2e1db4ccd5d4b6a7cbff6710fabfa51fd8727ad"
|
|
169
173
|
},
|
|
174
|
+
{
|
|
175
|
+
"path": "skills/lsp-setup/SKILL.md",
|
|
176
|
+
"sha256": "52e473a5727ab80e90d1bfd6c3a91d8a2ba9579c30bf65af1dd895eb3918900a"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"path": "skills/lsp-setup/references/bash/README.md",
|
|
180
|
+
"sha256": "7d32640c2f50ad18e4ccf1ab2f7b4b1ea989ce2228054c8bc2f05b97d484f8ad"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"path": "skills/lsp-setup/references/c-cpp/README.md",
|
|
184
|
+
"sha256": "0334f275754d4231a30700b9f1518c06ae9fd04f8809e3c89b197763cbdfdbb3"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"path": "skills/lsp-setup/references/csharp/README.md",
|
|
188
|
+
"sha256": "1717ca8bf762832f7209ef1d10f8896958e1a5a9c0445b8b9ce7bbce18423fb8"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"path": "skills/lsp-setup/references/dart/README.md",
|
|
192
|
+
"sha256": "eaa9b13bdbcd162b43220fdefb6292a86d53b053c32d60b3d067f9785a26c9df"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"path": "skills/lsp-setup/references/elixir/README.md",
|
|
196
|
+
"sha256": "385b3d4c3d0d531afb07e33570c502e754174b52125ae6572a35edd24d0da1e5"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"path": "skills/lsp-setup/references/go/README.md",
|
|
200
|
+
"sha256": "e0f2ced60994adfe22a76e37d69deb3308fe7f4885a9579e28b864a1948e7c22"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"path": "skills/lsp-setup/references/haskell/README.md",
|
|
204
|
+
"sha256": "df6dc810662b52de10d358edae6742cfab9cd66fc1636c68096ffe7f241fe102"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"path": "skills/lsp-setup/references/java/README.md",
|
|
208
|
+
"sha256": "a33e64405e090ffc4ec028d2aead42ec3c52b8c38f72ec0f92e4f0324bbbf4f3"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"path": "skills/lsp-setup/references/julia/README.md",
|
|
212
|
+
"sha256": "779799ec0ce809b10136167f768c65a756438e5a478ef338249619cc76511e78"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"path": "skills/lsp-setup/references/kotlin/README.md",
|
|
216
|
+
"sha256": "f4472bb7c34328aaeb1461d0c729efbf738a2e89fc94a1eb729f2a868ca88a76"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"path": "skills/lsp-setup/references/lua/README.md",
|
|
220
|
+
"sha256": "892613acb00e9cdb50ba5e69f147e33788a9b3db6500371f2ae6e20a07db3220"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"path": "skills/lsp-setup/references/php/README.md",
|
|
224
|
+
"sha256": "3719c12c64bd823ff9cf7af4073e14eaa4799726dee5b20a593b8a528527472f"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"path": "skills/lsp-setup/references/python/README.md",
|
|
228
|
+
"sha256": "b64b0add1c8eb5472cf03bfe4aad7ee4eab20c8f12874be20739071cdd58be7d"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"path": "skills/lsp-setup/references/ruby/README.md",
|
|
232
|
+
"sha256": "6c7a146dc58ef38c3670ba4c16690e419c96099ac6e62f0f059d4f16a5792e48"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"path": "skills/lsp-setup/references/rust/README.md",
|
|
236
|
+
"sha256": "2797c7c27d1041924600192cb649d81bbb94a53ddbb894f82748e977eac64d3a"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"path": "skills/lsp-setup/references/swift/README.md",
|
|
240
|
+
"sha256": "d7589fe85fae9937bfcfb951e41171577e743f6e4b7cea9dbef575b811d041ed"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"path": "skills/lsp-setup/references/terraform/README.md",
|
|
244
|
+
"sha256": "fe86c8bcb4966efd400e083bd3e22863ee4fae56c3fba1eb3abdaa666fe9c24e"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"path": "skills/lsp-setup/references/typescript/README.md",
|
|
248
|
+
"sha256": "fbdc8348d5d0b3978e73d7bd3701d34d8df692d031437e87c19b8708a5946108"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"path": "skills/lsp-setup/references/yaml/README.md",
|
|
252
|
+
"sha256": "c9456d750ba91716e30538d262e83f70ae51b44697e3bdee87d68dbf861f4b63"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"path": "skills/lsp-setup/references/zig/README.md",
|
|
256
|
+
"sha256": "87b955a8bd792561e291fe2922b467714aefdf59bede752938b20ce3da2a402c"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"path": "skills/lsp-setup/scripts/detect-lsp.ts",
|
|
260
|
+
"sha256": "32d9dba93c1e604e49e6049603c0ee8da67927540a7c53c87fc46c9a059b5178"
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"path": "skills/lsp-setup/scripts/lsp-server-table.ts",
|
|
264
|
+
"sha256": "fc281d78ff2f50657d4c9bcc253f2ff8c0f9e6be1dcea0b9963f52d874ef801e"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"path": "skills/lsp-setup/scripts/tsconfig.json",
|
|
268
|
+
"sha256": "8eecbbef0296b909dbe17af651126cf2c00a825ae65fa5be2836b212267c6f83"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"path": "skills/lsp-setup/scripts/verify-lsp.ts",
|
|
272
|
+
"sha256": "33c6c22236234ed5f4db7b0deae560b9b5e0c8c018be4ded1a6c1179792655fe"
|
|
273
|
+
},
|
|
170
274
|
{
|
|
171
275
|
"path": "skills/lsp/SKILL.md",
|
|
172
276
|
"sha256": "3e793aaa158156dd60ec11add7375050bbeeb7b3eb77497f1c432d0842abff5c"
|
|
@@ -478,6 +582,46 @@
|
|
|
478
582
|
{
|
|
479
583
|
"path": "skills/start-work/SKILL.md",
|
|
480
584
|
"sha256": "194a1d719c00564959da99715c86424a5ecd76196a4db9ca60e64be062dc70b5"
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
"path": "skills/visual-qa/SKILL.md",
|
|
588
|
+
"sha256": "fd1ed0841afc08ca838069969284afa04b16c81016a63a16d2f9187a3bde3327"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
"path": "skills/visual-qa/scripts/ansi.ts",
|
|
592
|
+
"sha256": "8d6e2f3881093538a96040ec8fea28285754e28ceac1b1f1da1e6d5024eeacfd"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
"path": "skills/visual-qa/scripts/cli.ts",
|
|
596
|
+
"sha256": "0dc05cf89afbd8df5371722229ada00751ba58eda633405457964ccd8bc6ac23"
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"path": "skills/visual-qa/scripts/east-asian-width.ts",
|
|
600
|
+
"sha256": "8cd4ac48a57bad794639be581f7dd2b52105ad258d090b403a74a46b10a83952"
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"path": "skills/visual-qa/scripts/image-diff.ts",
|
|
604
|
+
"sha256": "3b4e68afa5ad3e2bbd2866ba9b5a39b7e371b773c6d6b1d3a080a2f381cc00e4"
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
"path": "skills/visual-qa/scripts/png-crc.ts",
|
|
608
|
+
"sha256": "881027d0bb58b1633fd46b58e3034fefb61cba2e173af666c24a5ea4f95429d0"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"path": "skills/visual-qa/scripts/png-decode.ts",
|
|
612
|
+
"sha256": "9c190b960e276a81b3f962e509a45b72fe8bcc6a93d704fbee3a383fcde4bb64"
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
"path": "skills/visual-qa/scripts/png-synth.ts",
|
|
616
|
+
"sha256": "acc348340f1efd1cc6d312753912ef294640d5585a05a6839c72784fb64fcb84"
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
"path": "skills/visual-qa/scripts/tui-grid.ts",
|
|
620
|
+
"sha256": "63a0db7624eda98cfd37434552f9e56a48195bbeab8a9bbdd017c97b369bf58c"
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
"path": "skills/visual-qa/scripts/types.ts",
|
|
624
|
+
"sha256": "ef5ee3c9adfeb2d92138b2ce543232a8323247d5b9dbdde13b26f3197ee13c62"
|
|
481
625
|
}
|
|
482
626
|
]
|
|
483
627
|
}
|
|
@@ -89,6 +89,48 @@ These are not phases — read them when the situation calls for them:
|
|
|
89
89
|
|
|
90
90
|
---
|
|
91
91
|
|
|
92
|
+
## Reproduction standards
|
|
93
|
+
|
|
94
|
+
A good reproduction is:
|
|
95
|
+
|
|
96
|
+
- runnable from the project root
|
|
97
|
+
- deterministic, or carries a bounded flake note
|
|
98
|
+
- small enough for the next agent to rerun
|
|
99
|
+
- tied to one expected observable
|
|
100
|
+
|
|
101
|
+
For LitHermes examples:
|
|
102
|
+
|
|
103
|
+
- `cd ~/.hermes/hermes-agent && venv/bin/python -c "import sys; sys.path.insert(0,'$HOME/.hermes/plugins'); import lithermes.core as c; print(bool(c.pre_llm_call(user_message='lit go', session_id='x')))"`
|
|
104
|
+
- `hermes -z "Reply READY then stop. lit"` → expect `READY`, exit 0
|
|
105
|
+
- `npm test` from `packages/lithermes-installer/`
|
|
106
|
+
- `node test/scripts/scan-forbidden-tokens.js --tracked`
|
|
107
|
+
|
|
108
|
+
## Root cause discipline
|
|
109
|
+
|
|
110
|
+
Explain the mechanism, not just the symptom. "The command didn't bind the goal"
|
|
111
|
+
is not a root cause. "The slash-command handler is dispatched as `handler(user_args)`
|
|
112
|
+
with no `session_id`, so it cannot call `GoalManager.set()` — binding has to happen
|
|
113
|
+
in `pre_llm_call`, which does receive the session id" is a root cause.
|
|
114
|
+
|
|
115
|
+
## Common LitHermes failure classes
|
|
116
|
+
|
|
117
|
+
- Plugin manifest (`plugin.yaml`) version drifts from `package.json` — a guard test asserts they match.
|
|
118
|
+
- `npx <pkg>` fails with `command not found` when the bin name ≠ the package name (needs a matching bin alias).
|
|
119
|
+
- `npm publish` requires the user's OTP and fails with `EOTP` — it cannot be run unattended.
|
|
120
|
+
- Hook JSON parsing must fail with a controlled error, never a raw stack trace.
|
|
121
|
+
- Package `files` / `payload-version.json` omit a newly added skill or command.
|
|
122
|
+
- A per-turn flag left in module state leaks into the next turn when a hook does not fire (e.g. an interrupted turn).
|
|
123
|
+
|
|
124
|
+
## Patch rules
|
|
125
|
+
|
|
126
|
+
- Patch the failing boundary, not an unrelated symptom.
|
|
127
|
+
- Keep compatibility aliases unless a breaking change is intentional.
|
|
128
|
+
- Add the failing test before changing production behavior.
|
|
129
|
+
- Do not broaden `except`/`catch` blocks without asserting the new error path.
|
|
130
|
+
- Never call the network, publish, or mutate shared user state inside tests.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
92
134
|
## Non-Negotiable Safety Invariants
|
|
93
135
|
|
|
94
136
|
<safety>
|