lithermes-ai 0.6.0 → 0.8.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/README.md +2 -1
- package/README_Ko-KR.md +2 -1
- package/assets/lithermes-plugin/README.md +2 -1
- package/assets/lithermes-plugin/__init__.py +28 -9
- package/assets/lithermes-plugin/core.py +58 -0
- package/assets/lithermes-plugin/payload-version.json +14 -6
- package/assets/lithermes-plugin/plugin.yaml +1 -1
- package/assets/lithermes-plugin/skills/git-master/SKILL.md +130 -0
- package/assets/lithermes-plugin/skills/init-deep/SKILL.md +198 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,7 +57,8 @@ Restart any running Hermes CLI or Hermes gateway process. Then open Hermes and t
|
|
|
57
57
|
- Interactive install spinner keeps terminal installs lively while redirected or scripted installs stay plain; use `npx lithermes-ai install --yes --no-spinner` for quiet terminal installs.
|
|
58
58
|
- `start-work`: open or dry-run a LitHermes plan inside Hermes.
|
|
59
59
|
- LitHermes workflow skill set: `ai-slop-remover`, `comment-checker`,
|
|
60
|
-
`debugging`, `deep-interview`, `frontend-ui-ux`, `
|
|
60
|
+
`debugging`, `deep-interview`, `frontend-ui-ux`, `git-master`, `init-deep`,
|
|
61
|
+
`lsp`, `programming`, `refactor`,
|
|
61
62
|
`remove-ai-slops`, `review-work`, `rules`, `start-work`, `lit-plan`,
|
|
62
63
|
`litgoal`, and `litwork` are installed as `lithermes:*` skills.
|
|
63
64
|
- The full plugin payload — the `pre_llm_call` / `subagent_stop` hooks, every
|
package/README_Ko-KR.md
CHANGED
|
@@ -57,7 +57,8 @@ npx lithermes-ai install --yes
|
|
|
57
57
|
- interactive install spinner가 terminal 설치는 더 생동감 있게 보여주고, redirect/script 설치는 기존처럼 plain output을 유지합니다. 조용한 terminal 설치가 필요하면 `npx lithermes-ai install --yes --no-spinner`를 사용합니다.
|
|
58
58
|
- `start-work`: LitHermes plan을 Hermes 작업으로 엽니다.
|
|
59
59
|
- LitHermes workflow skill set: `ai-slop-remover`, `comment-checker`,
|
|
60
|
-
`debugging`, `deep-interview`, `frontend-ui-ux`, `
|
|
60
|
+
`debugging`, `deep-interview`, `frontend-ui-ux`, `git-master`, `init-deep`,
|
|
61
|
+
`lsp`, `programming`, `refactor`,
|
|
61
62
|
`remove-ai-slops`, `review-work`, `rules`, `start-work`, `lit-plan`,
|
|
62
63
|
`litgoal`, `litwork`가 `lithermes:*` skill로 함께 설치됩니다.
|
|
63
64
|
- 전체 plugin payload — `pre_llm_call` / `subagent_stop`
|
|
@@ -15,7 +15,8 @@ first-class Hermes skills:
|
|
|
15
15
|
- Explicit skills are available as:
|
|
16
16
|
`lithermes:ai-slop-remover`, `lithermes:comment-checker`,
|
|
17
17
|
`lithermes:debugging`, `lithermes:deep-interview`,
|
|
18
|
-
`lithermes:frontend-ui-ux`, `lithermes:
|
|
18
|
+
`lithermes:frontend-ui-ux`, `lithermes:git-master`,
|
|
19
|
+
`lithermes:init-deep`, `lithermes:lsp`,
|
|
19
20
|
`lithermes:programming`, `lithermes:refactor`,
|
|
20
21
|
`lithermes:remove-ai-slops`, `lithermes:review-work`,
|
|
21
22
|
`lithermes:rules`, `lithermes:start-work`, `lithermes:lit-plan`,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import functools
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Any
|
|
5
6
|
|
|
@@ -30,6 +31,14 @@ PORTED_SKILLS = [
|
|
|
30
31
|
"frontend-ui-ux",
|
|
31
32
|
"Apply the LitHermes frontend UI/UX review discipline.",
|
|
32
33
|
),
|
|
34
|
+
(
|
|
35
|
+
"git-master",
|
|
36
|
+
"Run the LitHermes git-history specialist for commits, rebases, blame, and bisect.",
|
|
37
|
+
),
|
|
38
|
+
(
|
|
39
|
+
"init-deep",
|
|
40
|
+
"Generate a hierarchical AGENTS.md knowledge base with the LitHermes onboarding workflow.",
|
|
41
|
+
),
|
|
33
42
|
(
|
|
34
43
|
"lsp",
|
|
35
44
|
"Use Hermes' native LSP diagnostics with LitHermes LSP guidance.",
|
|
@@ -107,6 +116,16 @@ def _handle_lithermes_cli(args) -> int:
|
|
|
107
116
|
return 1
|
|
108
117
|
|
|
109
118
|
|
|
119
|
+
def _ignited(handler):
|
|
120
|
+
"""Wrap a slash-command handler so its display prints the LITBURN banner."""
|
|
121
|
+
|
|
122
|
+
@functools.wraps(handler)
|
|
123
|
+
def wrapped(user_args):
|
|
124
|
+
return core.ignite(handler(user_args))
|
|
125
|
+
|
|
126
|
+
return wrapped
|
|
127
|
+
|
|
128
|
+
|
|
110
129
|
def register(ctx) -> None:
|
|
111
130
|
base = Path(__file__).resolve().parent
|
|
112
131
|
|
|
@@ -128,55 +147,55 @@ def register(ctx) -> None:
|
|
|
128
147
|
|
|
129
148
|
ctx.register_command(
|
|
130
149
|
"lit-plan",
|
|
131
|
-
core.command_lit_plan,
|
|
150
|
+
_ignited(core.command_lit_plan),
|
|
132
151
|
description="Create a durable Litwork implementation plan",
|
|
133
152
|
args_hint='"what to build"',
|
|
134
153
|
)
|
|
135
154
|
ctx.register_command(
|
|
136
155
|
"litwork-plan",
|
|
137
|
-
core.command_lit_plan,
|
|
156
|
+
_ignited(core.command_lit_plan),
|
|
138
157
|
description="Alias for /lit-plan",
|
|
139
158
|
args_hint='"what to build"',
|
|
140
159
|
)
|
|
141
160
|
ctx.register_command(
|
|
142
161
|
"lit",
|
|
143
|
-
core.command_lit,
|
|
162
|
+
_ignited(core.command_lit),
|
|
144
163
|
description="Start an Litwork run and execute the task immediately",
|
|
145
164
|
args_hint='"task" [--completion-promise TEXT] [--strategy reset|continue]',
|
|
146
165
|
)
|
|
147
166
|
ctx.register_command(
|
|
148
167
|
"lit-loop",
|
|
149
|
-
core.command_lit_loop,
|
|
168
|
+
_ignited(core.command_lit_loop),
|
|
150
169
|
description="Start an Litwork run and execute the task immediately",
|
|
151
170
|
args_hint='"task" [--completion-promise TEXT] [--strategy reset|continue]',
|
|
152
171
|
)
|
|
153
172
|
ctx.register_command(
|
|
154
173
|
"litwork-loop",
|
|
155
|
-
core.command_lit_loop,
|
|
174
|
+
_ignited(core.command_lit_loop),
|
|
156
175
|
description="Alias for /lit-loop",
|
|
157
176
|
args_hint='"task" [--completion-promise TEXT] [--strategy reset|continue]',
|
|
158
177
|
)
|
|
159
178
|
ctx.register_command(
|
|
160
179
|
"litgoal",
|
|
161
|
-
core.command_litgoal,
|
|
180
|
+
_ignited(core.command_litgoal),
|
|
162
181
|
description="Open or inspect the LitHermes litgoal durable runtime",
|
|
163
182
|
args_hint='["objective"] [--worktree PATH]',
|
|
164
183
|
)
|
|
165
184
|
ctx.register_command(
|
|
166
185
|
"review-work",
|
|
167
|
-
core.command_review_work,
|
|
186
|
+
_ignited(core.command_review_work),
|
|
168
187
|
description="Run the LitHermes 5-lane review orchestrator on the current diff",
|
|
169
188
|
args_hint="[--base REF]",
|
|
170
189
|
)
|
|
171
190
|
ctx.register_command(
|
|
172
191
|
"start-work",
|
|
173
|
-
core.command_start_work,
|
|
192
|
+
_ignited(core.command_start_work),
|
|
174
193
|
description="Open or dry-run a LitHermes plan against a workspace",
|
|
175
194
|
args_hint="[plan-name] [--worktree PATH] [--dry-run]",
|
|
176
195
|
)
|
|
177
196
|
ctx.register_command(
|
|
178
197
|
"deep-interview",
|
|
179
|
-
core.command_deep_interview,
|
|
198
|
+
_ignited(core.command_deep_interview),
|
|
180
199
|
description="Run the LitHermes Socratic clarity gate before planning/execution",
|
|
181
200
|
args_hint="[--quick|--standard|--deep] <idea>",
|
|
182
201
|
)
|
|
@@ -33,9 +33,16 @@ DIRECT_LIT_PATTERN = re.compile(r"^\s*(?:lit|litwork)\b\s+(?P<task>.+?)\s*$", re
|
|
|
33
33
|
MAX_TASK_LEN = 4000
|
|
34
34
|
_SLUG_PATTERN = re.compile(r"[^a-z0-9]+")
|
|
35
35
|
|
|
36
|
+
# Deterministic ignite banner. Printed verbatim on every LitHermes slash-command
|
|
37
|
+
# display (the only user-visible plugin channel); also instructed into LIT_CONTEXT
|
|
38
|
+
# for the bare-`lit` keyword path (best-effort — that path only reaches the model).
|
|
39
|
+
LITBURN_BANNER = "🔥 LITBURN IGNITED 🔥"
|
|
40
|
+
|
|
41
|
+
|
|
36
42
|
LIT_CONTEXT = "\n".join(
|
|
37
43
|
[
|
|
38
44
|
"<lithermes-litwork>",
|
|
45
|
+
f"FIRST, open your reply with this exact line so the user sees Litwork engage: {LITBURN_BANNER}",
|
|
39
46
|
"The user invoked Litwork/LitHermes. Operate in a durable, evidence-first loop:",
|
|
40
47
|
"- restate the concrete completion promise before changing files;",
|
|
41
48
|
"- keep the implementation scoped to the current repository and existing Hermes patterns;",
|
|
@@ -210,9 +217,53 @@ def _extract_run_context_task(message: str) -> str:
|
|
|
210
217
|
return _clamp_task(m.group("task")) if m else ""
|
|
211
218
|
|
|
212
219
|
|
|
220
|
+
# Slash-command handlers are dispatched as handler(user_args) with NO session_id,
|
|
221
|
+
# so they cannot bind the native /goal themselves. They instead embed this marker
|
|
222
|
+
# in their agent_message; pre_llm_call (which DOES receive session_id) reads it and
|
|
223
|
+
# performs the bind. /lit & /lit-loop bind via the run-context block; /litgoal &
|
|
224
|
+
# /lit-plan declare an objective and bind via this marker.
|
|
225
|
+
_BIND_GOAL_PATTERN = re.compile(
|
|
226
|
+
r"<lithermes-bind-goal>(?P<obj>.+?)</lithermes-bind-goal>", re.DOTALL
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _extract_bind_goal(message: str) -> str:
|
|
231
|
+
m = _BIND_GOAL_PATTERN.search(message)
|
|
232
|
+
return _clamp_task(m.group("obj")) if m else ""
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def bind_goal_marker(objective: str) -> str:
|
|
236
|
+
"""Render the bind-goal marker a command embeds so pre_llm_call binds /goal."""
|
|
237
|
+
objective = (objective or "").strip()
|
|
238
|
+
return f"<lithermes-bind-goal>{objective}</lithermes-bind-goal>" if objective else ""
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def ignite(result: str | dict[str, str]) -> str | dict[str, str]:
|
|
242
|
+
"""Prepend the LITBURN banner to a command result's user-visible display.
|
|
243
|
+
|
|
244
|
+
``display`` is the one channel Hermes prints to the user verbatim
|
|
245
|
+
(cli.py _cprint), so the banner deterministically fires on every LitHermes
|
|
246
|
+
slash command. agent_message (model-facing) is left untouched.
|
|
247
|
+
"""
|
|
248
|
+
if isinstance(result, dict):
|
|
249
|
+
display = result.get("display")
|
|
250
|
+
if display and not str(display).startswith(LITBURN_BANNER):
|
|
251
|
+
return {**result, "display": f"{LITBURN_BANNER}\n{display}"}
|
|
252
|
+
return result
|
|
253
|
+
if isinstance(result, str) and result.strip() and not result.startswith(LITBURN_BANNER):
|
|
254
|
+
return f"{LITBURN_BANNER}\n{result}"
|
|
255
|
+
return result
|
|
256
|
+
|
|
257
|
+
|
|
213
258
|
def pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
214
259
|
user_message = str(kwargs.get("user_message") or "")
|
|
215
260
|
session_id = str(kwargs.get("session_id") or "")
|
|
261
|
+
# /litgoal & /lit-plan declare an objective via the bind-goal marker. Bind it
|
|
262
|
+
# (we have session_id here) and stop — those messages are self-contained.
|
|
263
|
+
bind_obj = _extract_bind_goal(user_message)
|
|
264
|
+
if bind_obj:
|
|
265
|
+
bind_native_goal(session_id, bind_obj)
|
|
266
|
+
return None
|
|
216
267
|
# The /lit command injects a run-context message. Bind the native goal from
|
|
217
268
|
# it (we have session_id here), then skip re-injecting context.
|
|
218
269
|
if "<lithermes-run-context>" in user_message:
|
|
@@ -629,6 +680,7 @@ def build_plan_agent_message(brief: str, plan: Path, workspace: Path) -> str:
|
|
|
629
680
|
"goal tools (goal_set / goal_add_criterion / goal_evidence / goal_complete) and inspect",
|
|
630
681
|
"with `hermes lithermes goal status`.",
|
|
631
682
|
"</lithermes-plan-context>",
|
|
683
|
+
bind_goal_marker(brief),
|
|
632
684
|
]
|
|
633
685
|
)
|
|
634
686
|
|
|
@@ -799,6 +851,12 @@ def command_litgoal(raw_args: str) -> dict[str, str]:
|
|
|
799
851
|
"Load the lithermes:litgoal skill for the full discipline.",
|
|
800
852
|
"</lithermes-litgoal-command>",
|
|
801
853
|
]
|
|
854
|
+
# When an objective is given, bind the native /goal too (pre_llm_call reads
|
|
855
|
+
# this marker — slash handlers have no session_id). Inspect-only /litgoal
|
|
856
|
+
# (no objective) leaves any active goal untouched.
|
|
857
|
+
marker = bind_goal_marker(objective)
|
|
858
|
+
if marker:
|
|
859
|
+
agent_lines.append(marker)
|
|
802
860
|
return {
|
|
803
861
|
"display": f"{intro}\nState dir: {lithermes_dir(workspace) / 'litgoal'}",
|
|
804
862
|
"agent_message": "\n".join(agent_lines),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"syncedAt": "2026-06-
|
|
2
|
+
"syncedAt": "2026-06-14T03:56:58.019Z",
|
|
3
3
|
"source": "source-reference",
|
|
4
|
-
"sourceHash": "
|
|
4
|
+
"sourceHash": "23886fd1b52dc30433f8886ba15ccedbc3d134ba8f0b99b7a90a83d07c0351fe",
|
|
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": "e0bc7d60f61a8d35df9f6287876e236e59e80e871261558701375a12cc4e4feb"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "__init__.py",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "14951813219a77f7074ff8ca36e26cc46b66b0987f28dbcf1827c9bcfa98d65c"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "core.py",
|
|
20
|
-
"sha256": "
|
|
20
|
+
"sha256": "da2888e70b560697eaf81fe29d0b92a36e8e0563ab3bcab95c34472533faa937"
|
|
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": "4b8a31a093d883cf1714250564955c3d8ca87889887780515a7df15ed317e732"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "skills/ai-slop-remover/SKILL.md",
|
|
@@ -143,6 +143,14 @@
|
|
|
143
143
|
"path": "skills/frontend-ui-ux/SKILL.md",
|
|
144
144
|
"sha256": "914667044f135563658ceac733a085a6bbdd71a00a5f4030f73d43444e0388f7"
|
|
145
145
|
},
|
|
146
|
+
{
|
|
147
|
+
"path": "skills/git-master/SKILL.md",
|
|
148
|
+
"sha256": "31d59a91767423094fd84ed668c8b8c7e14d515cd17e3845d91a0ce4aa0144c8"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"path": "skills/init-deep/SKILL.md",
|
|
152
|
+
"sha256": "f571334ad9150fd93ef57fcc9dd85d240812649975811e63045ff2a72e84260b"
|
|
153
|
+
},
|
|
146
154
|
{
|
|
147
155
|
"path": "skills/lit-plan/SKILL.md",
|
|
148
156
|
"sha256": "1f09901f9bb8f19b92add59c3613231228c8b5b7adbefae1cb3eb5cf7c3c61dc"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-master
|
|
3
|
+
description: "MUST USE whenever a task needs a commit or git-history investigation. Covers atomic commits, staging, commit-message style, rebase, squash, fixup/autosquash, blame, bisect, reflog, git log -S/-G, and questions like who wrote this or when was this added. Do not use for ordinary code edits unless the user asks for git work."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Git Master
|
|
7
|
+
|
|
8
|
+
The LitHermes git-history specialist for Hermes. Use this skill when the user
|
|
9
|
+
asks you to operate on Git history or answer a Git-history question. Be exact,
|
|
10
|
+
conservative, and evidence-led. Read the repository state before you infer anything.
|
|
11
|
+
|
|
12
|
+
## LitHermes publish boundary
|
|
13
|
+
|
|
14
|
+
Commit, push, force-push, and history rewrites are outward-facing or hard-to-reverse
|
|
15
|
+
operations. Per LitHermes discipline, do **not** commit, push, force-push, reset,
|
|
16
|
+
stash-pop, or rewrite history unless the user explicitly authorized that exact
|
|
17
|
+
operation. Investigative requests report findings and stop.
|
|
18
|
+
|
|
19
|
+
## Mode Gate
|
|
20
|
+
|
|
21
|
+
Classify the request first:
|
|
22
|
+
|
|
23
|
+
- `COMMIT`: stage and commit local changes.
|
|
24
|
+
- `REBASE`: rebase, squash, fixup, autosquash, reorder, split, or otherwise rewrite branch history.
|
|
25
|
+
- `HISTORY`: answer when, where, who, why, or which commit changed something.
|
|
26
|
+
- `STATUS`: inspect branch, diff, or working-tree state without changing it.
|
|
27
|
+
|
|
28
|
+
If the request is only investigative, report findings and stop.
|
|
29
|
+
|
|
30
|
+
## Ground Truth
|
|
31
|
+
|
|
32
|
+
Gather independent facts first (these are read-only and safe to run in parallel):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git status --short
|
|
36
|
+
git diff --stat
|
|
37
|
+
git diff --staged --stat
|
|
38
|
+
git branch --show-current
|
|
39
|
+
git log -30 --oneline
|
|
40
|
+
git rev-parse --abbrev-ref @{upstream}
|
|
41
|
+
git merge-base HEAD origin/main
|
|
42
|
+
git merge-base HEAD origin/master
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Missing upstream or missing `main`/`master` is normal. Fall back to the best
|
|
46
|
+
available branch or report the missing fact. Never treat a failed lookup as proof.
|
|
47
|
+
|
|
48
|
+
## Commit Mode
|
|
49
|
+
|
|
50
|
+
Commit only the user's requested changes. Preserve unrelated dirty work.
|
|
51
|
+
|
|
52
|
+
1. Detect message style from recent history (`git log -30 --pretty=format:%s`). Use the
|
|
53
|
+
dominant local pattern, language, and casing. Do not default to Conventional
|
|
54
|
+
Commits unless the repo already uses them.
|
|
55
|
+
2. Inspect the full diff, not only filenames. Separate unrelated user edits from the
|
|
56
|
+
requested commit.
|
|
57
|
+
3. Build atomic groups by behavior, module, and revertability. Keep implementation and
|
|
58
|
+
its direct tests together.
|
|
59
|
+
4. Prefer multiple commits for unrelated concerns. A single commit is acceptable only
|
|
60
|
+
when the changed files form one indivisible behavior or the user explicitly asks for one.
|
|
61
|
+
5. Stage by path or hunk so each commit contains only its atomic group.
|
|
62
|
+
6. Before each commit, verify `git diff --staged --stat` and enough staged diff to prove
|
|
63
|
+
the group is right.
|
|
64
|
+
7. Commit with the detected style. After each commit, verify `git log -1 --oneline`.
|
|
65
|
+
|
|
66
|
+
Grouping rules:
|
|
67
|
+
|
|
68
|
+
- Split different features, modules, generated artifacts, config, docs, and test-only
|
|
69
|
+
changes unless they are inseparable.
|
|
70
|
+
- Keep generated files with the source change that produced them when omitting them
|
|
71
|
+
would leave the repo inconsistent.
|
|
72
|
+
- Never hide failing or unrelated changes inside a broad commit.
|
|
73
|
+
- Follow the user's git conventions (e.g. no AI/co-author attribution when the repo or
|
|
74
|
+
the user's rules forbid it).
|
|
75
|
+
|
|
76
|
+
Final report: list commit hashes, messages, and any remaining uncommitted files.
|
|
77
|
+
|
|
78
|
+
## Rebase Mode
|
|
79
|
+
|
|
80
|
+
History rewriting is a shared-impact operation.
|
|
81
|
+
|
|
82
|
+
- Never rebase or rewrite `main`, `master`, `dev`, release branches, or a protected
|
|
83
|
+
branch unless the user explicitly named that exact operation.
|
|
84
|
+
- If commits may already be pushed, ask before force-pushing. Use `--force-with-lease`,
|
|
85
|
+
never plain `--force`.
|
|
86
|
+
- If the worktree is dirty, preserve it intentionally before rebasing. Do not stash-pop
|
|
87
|
+
over conflicts without checking what changed.
|
|
88
|
+
- For fixups, prefer `git commit --fixup=<hash>` then
|
|
89
|
+
`GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash <base>`.
|
|
90
|
+
- For conflicts, read the conflicting files and resolve by intent. Do not choose
|
|
91
|
+
ours/theirs blindly.
|
|
92
|
+
- If a rebase goes wrong, run `git rebase --abort` first. Use reflog only after
|
|
93
|
+
explaining the recovery path.
|
|
94
|
+
|
|
95
|
+
After rewriting, run the relevant tests or at least the project's cheapest smoke check,
|
|
96
|
+
then show the new branch log from base to HEAD.
|
|
97
|
+
|
|
98
|
+
## History Mode
|
|
99
|
+
|
|
100
|
+
Choose the Git tool by the question:
|
|
101
|
+
|
|
102
|
+
- `git log -S "text"`: when the count of an exact string changed.
|
|
103
|
+
- `git log -G "regex"`: when diffs touched lines matching a pattern.
|
|
104
|
+
- `git blame -L start,end -- file`: who last changed specific lines.
|
|
105
|
+
- `git log --follow -- file`: history across renames for one file.
|
|
106
|
+
- `git show <hash>`: inspect the commit that appears relevant.
|
|
107
|
+
- `git bisect`: find the first bad commit when there is a deterministic pass/fail
|
|
108
|
+
command and known good/bad bounds.
|
|
109
|
+
- `git reflog`: recover or explain recent local history movement.
|
|
110
|
+
|
|
111
|
+
Always cite the exact command evidence in the answer: commit hash, subject, file path,
|
|
112
|
+
and line or diff context when relevant. If the evidence is ambiguous, say what remains
|
|
113
|
+
unproven.
|
|
114
|
+
|
|
115
|
+
## Safety Checks
|
|
116
|
+
|
|
117
|
+
Before any write to Git history:
|
|
118
|
+
|
|
119
|
+
- Current branch is known.
|
|
120
|
+
- Dirty work is accounted for.
|
|
121
|
+
- Upstream/pushed status is known or explicitly unknown.
|
|
122
|
+
- The operation matches an explicit user request and authorization.
|
|
123
|
+
- Recovery path is known (`rebase --abort`, reflog hash, or untouched worktree).
|
|
124
|
+
|
|
125
|
+
Before finishing:
|
|
126
|
+
|
|
127
|
+
- Run the most relevant verification available for the changed behavior or history
|
|
128
|
+
operation (Manual QA evidence where a behavior changed).
|
|
129
|
+
- Report commands that passed and any command you could not run.
|
|
130
|
+
- Leave the worktree state explicit.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: init-deep
|
|
3
|
+
description: "Initialize a hierarchical AGENTS.md knowledge base for a repository — a root AGENTS.md plus complexity-scored subdirectory files. Use when the user wants to bootstrap or refresh project knowledge for Hermes, onboard a codebase, generate AGENTS.md guidance (reading any existing CLAUDE.md for context), or map an unfamiliar repo. Adapted for Hermes: discovery and parallel generation via delegate_task children + Hermes lsp tools."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Init-Deep — hierarchical AGENTS.md generator (Hermes)
|
|
7
|
+
|
|
8
|
+
Generate hierarchical `AGENTS.md` files: a root knowledge base plus complexity-scored subdirectory
|
|
9
|
+
files. This is the LitHermes onboarding/knowledge-base skill, re-authored for Hermes surfaces:
|
|
10
|
+
read-only `delegate_task` children for discovery, Hermes' `lsp` tools for the code map, and parallel
|
|
11
|
+
`delegate_task` fan-out for generation. (`AGENTS.md` is the file Hermes loads natively as project
|
|
12
|
+
context — see the `lithermes:rules` skill.)
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
init-deep # Update mode: modify existing AGENTS.md + create new where warranted
|
|
18
|
+
init-deep --create-new # Read existing → remove all → regenerate from scratch
|
|
19
|
+
init-deep --max-depth=2 # Limit directory depth (default: 3)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Workflow (high level)
|
|
23
|
+
|
|
24
|
+
1. **Discovery + analysis** (concurrent) — read-only `delegate_task` children + local bash structure +
|
|
25
|
+
`lsp` code map + read existing AGENTS.md.
|
|
26
|
+
2. **Score & decide** — determine AGENTS.md locations from merged findings.
|
|
27
|
+
3. **Generate** — root first, then subdirectories in parallel.
|
|
28
|
+
4. **Review** — deduplicate, trim, validate.
|
|
29
|
+
|
|
30
|
+
Track all four phases explicitly and report each one `pending → in_progress → completed` as you go
|
|
31
|
+
(Hermes has no TodoWrite tool; keep the running state in your reply or a working note).
|
|
32
|
+
|
|
33
|
+
## Phase 1 — Discovery + analysis (concurrent)
|
|
34
|
+
|
|
35
|
+
Mark "discovery" in_progress.
|
|
36
|
+
|
|
37
|
+
### Fan out read-only discovery children immediately
|
|
38
|
+
|
|
39
|
+
Dispatch the discovery lanes as read-only `delegate_task` children — pass a `tasks` array so they run
|
|
40
|
+
concurrently and the parent blocks until all return. Each child is self-contained (goal + scope +
|
|
41
|
+
"read-only, return findings only"). Suggested lanes (one child each):
|
|
42
|
+
|
|
43
|
+
- **Structure** — predict standard patterns for the detected language; report deviations only.
|
|
44
|
+
- **Entry points** — find main/entry files; report non-standard organization.
|
|
45
|
+
- **Conventions** — find config files (`.eslintrc`, `pyproject.toml`, `.editorconfig`, …); report
|
|
46
|
+
project-specific rules.
|
|
47
|
+
- **Anti-patterns** — find `DO NOT` / `NEVER` / `ALWAYS` / `DEPRECATED` markers; list forbidden patterns.
|
|
48
|
+
- **Build/CI** — find `.github/workflows`, `Makefile`, `Taskfile`; report non-standard patterns.
|
|
49
|
+
- **Tests** — find test configs and structure; report unique conventions.
|
|
50
|
+
|
|
51
|
+
**Dynamic scaling** — after the bash pass below, add MORE `delegate_task` children based on project
|
|
52
|
+
scale (never a static count):
|
|
53
|
+
|
|
54
|
+
| Factor | Threshold | Additional children |
|
|
55
|
+
|--------|-----------|---------------------|
|
|
56
|
+
| Total files | >100 | +1 per 100 files |
|
|
57
|
+
| Total lines | >10k | +1 per 10k lines |
|
|
58
|
+
| Directory depth | ≥4 | +2 for deep exploration |
|
|
59
|
+
| Large files (>500 lines) | >10 files | +1 for complexity hotspots |
|
|
60
|
+
| Monorepo | detected | +1 per package/workspace |
|
|
61
|
+
| Multiple languages | >1 | +1 per language |
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
total_files=$(find . -type f -not -path '*/node_modules/*' -not -path '*/.git/*' | wc -l)
|
|
65
|
+
total_lines=$(find . -type f \( -name "*.ts" -o -name "*.py" -o -name "*.go" \) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}')
|
|
66
|
+
large_files=$(find . -type f \( -name "*.ts" -o -name "*.py" \) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {c++} END {print c+0}')
|
|
67
|
+
max_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' | awk -F/ '{print NF}' | sort -rn | head -1)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For very broad repos, split the fan-out across several `delegate_task` batches rather than one giant
|
|
71
|
+
batch, but keep every child read-only.
|
|
72
|
+
|
|
73
|
+
### Main session: concurrent local analysis
|
|
74
|
+
|
|
75
|
+
While the discovery children run, the main session does:
|
|
76
|
+
|
|
77
|
+
**1. Bash structural analysis**
|
|
78
|
+
```bash
|
|
79
|
+
# Directory depth distribution
|
|
80
|
+
find . -type d -not -path '*/.*' -not -path '*/node_modules/*' -not -path '*/dist/*' -not -path '*/build/*' | awk -F/ '{print NF-1}' | sort -n | uniq -c
|
|
81
|
+
# Files per directory (top 30)
|
|
82
|
+
find . -type f -not -path '*/.*' -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -30
|
|
83
|
+
# Existing knowledge bases
|
|
84
|
+
find . -type f \( -name "AGENTS.md" -o -name "CLAUDE.md" \) -not -path '*/node_modules/*' 2>/dev/null
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**2. Read existing AGENTS.md** — for each file found, read it and extract key insights,
|
|
88
|
+
conventions, and anti-patterns into an EXISTING map. With `--create-new`, read ALL existing files
|
|
89
|
+
first (preserve context), THEN delete, THEN regenerate.
|
|
90
|
+
|
|
91
|
+
**3. LSP code map (if available)** — use Hermes' `lsp` tools: `lsp.status` to list configured servers,
|
|
92
|
+
then `lsp.symbols` for entry-point/workspace symbols (`class` / `interface` / `function`) and
|
|
93
|
+
`lsp.find_references` on the top exports to gauge centrality. If no server is configured, fall back to
|
|
94
|
+
the discovery children + plain search. (See the `lithermes:lsp` skill.)
|
|
95
|
+
|
|
96
|
+
Merge bash + LSP + existing + child findings. Mark "discovery" completed.
|
|
97
|
+
|
|
98
|
+
## Phase 2 — Scoring & location decision
|
|
99
|
+
|
|
100
|
+
Mark "scoring" in_progress.
|
|
101
|
+
|
|
102
|
+
### Scoring matrix
|
|
103
|
+
|
|
104
|
+
| Factor | Weight | High threshold | Source |
|
|
105
|
+
|--------|--------|----------------|--------|
|
|
106
|
+
| File count | 3× | >20 | bash |
|
|
107
|
+
| Subdir count | 2× | >5 | bash |
|
|
108
|
+
| Code ratio | 2× | >70% | bash |
|
|
109
|
+
| Unique patterns | 1× | has own config | child |
|
|
110
|
+
| Module boundary | 2× | has `index.ts`/`__init__.py` | bash |
|
|
111
|
+
| Symbol density | 2× | >30 symbols | LSP |
|
|
112
|
+
| Export count | 2× | >10 exports | LSP |
|
|
113
|
+
| Reference centrality | 3× | >20 refs | LSP |
|
|
114
|
+
|
|
115
|
+
### Decision rules
|
|
116
|
+
|
|
117
|
+
| Score | Action |
|
|
118
|
+
|-------|--------|
|
|
119
|
+
| Root (`.`) | ALWAYS create |
|
|
120
|
+
| >15 | Create AGENTS.md |
|
|
121
|
+
| 8–15 | Create if it is a distinct domain |
|
|
122
|
+
| <8 | Skip (parent covers it) |
|
|
123
|
+
|
|
124
|
+
Mark "scoring" completed.
|
|
125
|
+
|
|
126
|
+
## Phase 3 — Generate AGENTS.md
|
|
127
|
+
|
|
128
|
+
Mark "generate" in_progress.
|
|
129
|
+
|
|
130
|
+
**File-writing rule:** if `AGENTS.md` already exists at the target path, edit it in place; if not,
|
|
131
|
+
create it. NEVER overwrite an existing file — check existence first (via the discovery results or a
|
|
132
|
+
read).
|
|
133
|
+
|
|
134
|
+
### Root AGENTS.md (full treatment)
|
|
135
|
+
|
|
136
|
+
```markdown
|
|
137
|
+
# PROJECT KNOWLEDGE BASE
|
|
138
|
+
**Generated:** {TIMESTAMP} **Commit:** {SHORT_SHA} **Branch:** {BRANCH}
|
|
139
|
+
|
|
140
|
+
## OVERVIEW
|
|
141
|
+
{1–2 sentences: what + core stack}
|
|
142
|
+
|
|
143
|
+
## STRUCTURE
|
|
144
|
+
{tree with non-obvious purposes only}
|
|
145
|
+
|
|
146
|
+
## WHERE TO LOOK
|
|
147
|
+
| Task | Location | Notes |
|
|
148
|
+
|
|
149
|
+
## CODE MAP
|
|
150
|
+
{from LSP — skip if unavailable or project <10 files}
|
|
151
|
+
|
|
152
|
+
## CONVENTIONS
|
|
153
|
+
{ONLY deviations from standard}
|
|
154
|
+
|
|
155
|
+
## ANTI-PATTERNS (THIS PROJECT)
|
|
156
|
+
{explicitly forbidden here}
|
|
157
|
+
|
|
158
|
+
## COMMANDS
|
|
159
|
+
{dev / test / build}
|
|
160
|
+
|
|
161
|
+
## NOTES
|
|
162
|
+
{gotchas}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Quality gate: 50–150 lines, no generic advice, no obvious info.
|
|
166
|
+
|
|
167
|
+
### Subdirectory AGENTS.md (parallel)
|
|
168
|
+
|
|
169
|
+
Generate each non-root location in parallel — dispatch one writing `delegate_task` child per location
|
|
170
|
+
(batch them in one `delegate_task` call). Each child gets a `TASK:` line plus `DELIVERABLE` (the
|
|
171
|
+
AGENTS.md), `SCOPE` (this directory only), and `VERIFY` (30–80 lines, never repeats parent content;
|
|
172
|
+
sections: OVERVIEW 1 line, STRUCTURE if >5 subdirs, WHERE TO LOOK, CONVENTIONS if different,
|
|
173
|
+
ANTI-PATTERNS). Wait for all. Mark "generate" completed.
|
|
174
|
+
|
|
175
|
+
## Phase 4 — Review & deduplicate
|
|
176
|
+
|
|
177
|
+
Mark "review" in_progress. For each generated file: remove generic advice, remove parent duplicates,
|
|
178
|
+
trim to the size limits, verify telegraphic style. Mark "review" completed.
|
|
179
|
+
|
|
180
|
+
## Final report
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
=== init-deep complete ===
|
|
184
|
+
Mode: {update | create-new}
|
|
185
|
+
Files: [OK] ./AGENTS.md (root, {N} lines) · [OK] ./src/hooks/AGENTS.md ({N} lines)
|
|
186
|
+
Dirs analyzed: {N} · Created: {N} · Updated: {N}
|
|
187
|
+
Hierarchy: ./AGENTS.md └── src/hooks/AGENTS.md
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Anti-patterns
|
|
191
|
+
|
|
192
|
+
- **Static child count** — vary discovery `delegate_task` children by project size/depth (see the scaling table).
|
|
193
|
+
- **Sequential execution** — run discovery children + LSP concurrently; generate subdirectories in parallel.
|
|
194
|
+
- **Ignoring existing** — ALWAYS read existing AGENTS.md first, even with `--create-new`.
|
|
195
|
+
- **Over-documenting** — not every directory needs an AGENTS.md.
|
|
196
|
+
- **Redundancy** — a child file never repeats its parent.
|
|
197
|
+
- **Generic content** — remove anything that applies to all projects.
|
|
198
|
+
- **Verbose style** — telegraphic or die.
|