@litfamily/lithermes 1.0.28 → 1.0.30
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 +12 -9
- package/README_Ko-KR.md +12 -9
- package/assets/lithermes-plugin/README.md +15 -2
- package/assets/lithermes-plugin/__init__.py +49 -10
- package/assets/lithermes-plugin/adhd_stack.py +228 -0
- package/assets/lithermes-plugin/core.py +30 -4
- package/assets/lithermes-plugin/core_commands.py +99 -0
- package/assets/lithermes-plugin/core_contexts.py +54 -4
- package/assets/lithermes-plugin/core_contract.py +2 -2
- package/assets/lithermes-plugin/core_routing.py +126 -0
- package/assets/lithermes-plugin/diagnostics.py +3 -2
- package/assets/lithermes-plugin/lit_mark.py +75 -0
- package/assets/lithermes-plugin/payload-version.json +472 -60
- package/assets/lithermes-plugin/plugin.yaml +1 -1
- package/assets/lithermes-plugin/scientific_visualization.py +23 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/SKILL.md +7 -7
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/components.css +414 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/fonts.json +42 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/layouts/landing.html +164 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/layouts/settings.html +114 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/layouts/workspace.html +115 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/styles/computational-brutalism.json +227 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/styles/field-notes.json +205 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/styles/graphite.json +200 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/styles/meadow.json +199 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/styles/neo-brutalism.json +222 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/kit/ui.js +226 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/README.md +2 -4
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/complete-contract.md +4 -4
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/craft-floor.md +10 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/design-lock.mjs +400 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-rules.json +6 -1
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe.mjs +76 -4
- package/assets/lithermes-plugin/skills/lit-adhd/SKILL.md +194 -0
- package/assets/lithermes-plugin/skills/lit-adhd/references/brief-contract.md +55 -0
- package/assets/lithermes-plugin/skills/lit-adhd/references/card-examples.md +86 -0
- package/assets/lithermes-plugin/skills/lit-adhd/references/status-taxonomy.md +40 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/adhd.mjs +11 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/collect.mjs +554 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/gauge.mjs +89 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/hermes-sessions.mjs +219 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/next-step.mjs +101 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/plan-task-rows.mjs +32 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/redact.mjs +42 -0
- package/assets/lithermes-plugin/skills/lit-adhd/scripts/lib/secret-shapes.mjs +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/SKILL.md +7 -4
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/style-guide.md +20 -11
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-architecture.md +3 -3
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dependency.md +1 -1
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree.md +3 -3
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-wardley.md +1 -1
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/verifier-guide.md +5 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality.py +4 -4
- package/assets/lithermes-plugin/skills/lit-docx/SKILL.md +1 -1
- package/assets/lithermes-plugin/skills/lit-hijack/SKILL.md +239 -0
- package/assets/lithermes-plugin/skills/lit-hijack/references/capture-and-provenance.md +123 -0
- package/assets/lithermes-plugin/skills/lit-hijack/references/clean-room-build.md +128 -0
- package/assets/lithermes-plugin/skills/lit-hijack/references/distil-and-licence.md +128 -0
- package/assets/lithermes-plugin/skills/lit-hijack/references/gap-and-port-design.md +152 -0
- package/assets/lithermes-plugin/skills/lit-hijack/references/parity-and-report.md +131 -0
- package/assets/lithermes-plugin/skills/lit-hijack/scripts/hijack.mjs +995 -0
- package/assets/lithermes-plugin/skills/lit-plan/SKILL.md +1 -0
- package/assets/lithermes-plugin/skills/lit-pptx/SKILL.md +11 -6
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Bold.ttf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Regular.ttf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/jetbrains-mono/OFL.txt +93 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/provenance.json +1 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/anti-slop-checklist.md +3 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/authoring-guide.md +1 -1
- package/assets/lithermes-plugin/skills/lit-pptx/references/consensus-protocol.md +1 -1
- package/assets/lithermes-plugin/skills/lit-pptx/references/direction-step.md +8 -2
- package/assets/lithermes-plugin/skills/lit-pptx/references/examples/13-engineering-review-computational-brutalism-ko.md +175 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/examples/14-launch-pitch-neo-brutalism-ko.md +156 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/examples/15-design-lecture-bauhaus-ko.md +141 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/examples/16-community-programme-riso-ko.md +160 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/examples/17-public-data-briefing-newsroom-ko.md +183 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/layout-families.md +1 -1
- package/assets/lithermes-plugin/skills/lit-pptx/references/tonalities/bauhaus.md +105 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/tonalities/computational-brutalism.md +111 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/tonalities/neo-brutalism.md +114 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/tonalities/newsroom.md +106 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/tonalities/riso.md +101 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/craft_extras.py +49 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/deck_output.py +4 -2
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-pack.js +96 -10
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/template-registry.js +50 -6
- package/assets/lithermes-plugin/skills/lit-pptx/templates/tonalities/bauhaus/pack.yaml +103 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/tonalities/computational-brutalism/pack.yaml +99 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/tonalities/neo-brutalism/pack.yaml +107 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/tonalities/newsroom/pack.yaml +99 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/tonalities/riso/pack.yaml +99 -0
- package/assets/lithermes-plugin/skills/lit-recap/SKILL.md +1 -1
- package/assets/lithermes-plugin/skills/lit-schematic/SKILL.md +144 -0
- package/assets/lithermes-plugin/skills/lit-schematic/examples/iso-heat-exchanger/build.mjs +38 -0
- package/assets/lithermes-plugin/skills/lit-schematic/examples/iso-heat-exchanger/scene.mjs +133 -0
- package/assets/lithermes-plugin/skills/lit-schematic/examples/journal-adsorption-rig/build.mjs +87 -0
- package/assets/lithermes-plugin/skills/lit-schematic/examples/pid-dosing-skid/build.mjs +85 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/cutaway-outputs.md +70 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/isometric-craft.md +101 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/journal-figures.md +72 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/kit-api.md +134 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/pfd-and-layout.md +53 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/pid-drafting.md +103 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/pid-symbols.md +163 -0
- package/assets/lithermes-plugin/skills/lit-schematic/references/verification.md +100 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/doctor.mjs +57 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/figure.mjs +81 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/fonts.mjs +27 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/geom.mjs +113 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/interactive.mjs +292 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/isa.mjs +115 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/iso.mjs +719 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/legend-sheet.mjs +162 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/pid.mjs +937 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/png.mjs +132 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/qa-core.mjs +658 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/route.mjs +218 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/sheet.mjs +890 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/svg.mjs +82 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/lib/theme.mjs +115 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/motion.mjs +129 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/qa.mjs +92 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/render.mjs +233 -0
- package/assets/lithermes-plugin/skills/lit-schematic/scripts/scaffold.mjs +60 -0
- package/assets/lithermes-plugin/skills/lit-scientific-visualization/SKILL.md +19 -1
- package/assets/lithermes-plugin/skills/lit-typographic-motion/SKILL.md +12 -11
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/motion.mjs +56 -2
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/runtime.mjs +129 -4
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +9 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/blender/runner.py +218 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/blender.mjs +154 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/board.mjs +132 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/completion.mjs +48 -5
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/gate.mjs +13 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/house.mjs +44 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/scaffold.mjs +238 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/score.mjs +643 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/sound-dsp.mjs +21 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/sound.mjs +171 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-qa.mjs +23 -3
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage.mjs +124 -17
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/styles.mjs +240 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/treatment.mjs +152 -10
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/vendor/three/LICENSE +21 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/vendor/three/addons/environments/RoomEnvironment.js +144 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/vendor/three/addons/geometries/RoundedBoxGeometry.js +155 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/vendor/three/three.module.js +54571 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/recipes/hero-3d/expected.json +67 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/recipes/hero-3d/index.html +139 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/depth.md +74 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/studio.md +87 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/style-bibles.md +9 -2
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/treatment.md +24 -8
- package/assets/lithermes-plugin/skills/lit-typographic-motion/styles/paper.json +41 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/styles/swiss-signal.json +41 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/styles/terminalcore.json +42 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/styles/tidal.json +41 -0
- package/assets/lithermes-plugin/skills/litresearch/SKILL.md +4 -0
- package/assets/lithermes-plugin/skills/readme-studio/SKILL.md +1 -1
- package/assets/lithermes-plugin/skills/readme-studio/templates/hyperframes/package-lock.json +3 -3
- package/assets/lithermes-plugin/skills/readme-studio/templates/remotion/package-lock.json +3 -3
- package/assets/lithermes-plugin/skills/review-work/SKILL.md +2 -0
- package/assets/lithermes-plugin/skills/start-work/SKILL.md +2 -1
- package/assets/lithermes-plugin/skills/visual-qa/references/complete-contract.md +3 -3
- package/package.json +1 -1
- package/readme-assets/badge-version.svg +1 -1
- package/src/lib/skillPayload.js +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
1
|
+
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/cover-motion.webp" width="100%" alt="LitFamily motion cover: seven armored robots power on one by one, the LitHermes robot wakes with glowing eyes and a lit frame, then LITFAMILY and KEEP THE WORK LIT. light up." /></picture></p>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<a href="#install"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
5
|
-
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
4
|
+
<a href="#install"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/badge-version.svg" alt="1.0.30" /></a>
|
|
5
|
+
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/badge-license.svg" alt="MIT license" /></a>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/docs/guide.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
10
|
-
<a href="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
11
|
-
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
9
|
+
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/docs/guide.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/lucide-book-open.svg" width="16" alt="" /> Guide</a>
|
|
10
|
+
<a href="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/lucide-play.svg" width="16" alt="" /> Ignition film</a>
|
|
11
|
+
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
# LitHermes
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
A plugin for **Hermes Agent**. Put `lit` in front of a request, and Hermes plans the task, does it, checks the result and writes down where things stand, so the next session can pick up where this one stopped.
|
|
19
19
|
|
|
20
|
-
**[README and docs on GitHub](https://github.com/wjgoarxiv/lithermes#readme)** · [한국어](https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
20
|
+
**[README and docs on GitHub](https://github.com/wjgoarxiv/lithermes#readme)** · [한국어](https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/README_Ko-KR.md)
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
|
@@ -51,11 +51,14 @@ The reply opens with a `🔥 **LIT IGNITED · <discipline>** 🔥` line once the
|
|
|
51
51
|
| `lit research <question>` | `litresearch` | Research with source notes |
|
|
52
52
|
| `/lit-humanizer` | `lit-humanizer` | Revising Korean or English prose, meaning kept |
|
|
53
53
|
| `/lit-diagram-drawer <brief>` | `lit-diagram-drawer` | A checked, editable diagram |
|
|
54
|
-
| `/lit-
|
|
54
|
+
| `/lit-schematic <brief>` | `lit-schematic` | A QA-gated P&ID, apparatus figure or isometric cutaway |
|
|
55
|
+
| `/lit-pptx <brief>` | `lit-pptx` | A PowerPoint deck in one of thirteen named looks, with its Markdown source |
|
|
55
56
|
| `/lit-docx <brief>` | `lit-docx` | A restrained Word document in one of six named shapes, with its Markdown source |
|
|
57
|
+
| `/lit-hijack <brief>` | `lit-hijack` | A clean-room port of published know-how, licence-gated with parity proof |
|
|
58
|
+
| `/lit-adhd [--here] [--since 7d] [--max 12]` | `lit-adhd` | A cross-session brief with gauges and one next step, read-only |
|
|
56
59
|
| `/lit-typographic-motion <brief>` | `lit-typographic-motion` | A short film, treatment first |
|
|
57
60
|
|
|
58
|
-
On a Telegram gateway, use `/lit_loop` and `/lit_plan`. Every skill also loads by name as `lithermes:<name>`, for example `lithermes:lit-pptx` or `lithermes:lit-docx`. [Skills and commands](https://github.com/wjgoarxiv/lithermes/blob/main/docs/skills.md) shows all
|
|
61
|
+
On a Telegram gateway, use `/lit_loop` and `/lit_plan`. Every skill also loads by name as `lithermes:<name>`, for example `lithermes:lit-pptx` or `lithermes:lit-docx`. [Skills and commands](https://github.com/wjgoarxiv/lithermes/blob/main/docs/skills.md) shows all 39 with pictures.
|
|
59
62
|
|
|
60
63
|
## Check, update, remove
|
|
61
64
|
|
package/README_Ko-KR.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
1
|
+
<p align="center"><picture><source media="(prefers-reduced-motion: reduce)" srcset="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/cover-motion-still.webp" /><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/cover-motion.webp" width="100%" alt="LitFamily 모션 커버: 일곱 로봇 패널이 차례로 켜지고, LitHermes 로봇의 눈과 테두리가 빛난 뒤 LITFAMILY와 KEEP THE WORK LIT. 문구가 밝아지는 영상" /></picture></p>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<a href="#설치"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
5
|
-
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
4
|
+
<a href="#설치"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/badge-version.svg" alt="1.0.30" /></a>
|
|
5
|
+
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/badge-license.svg" alt="MIT license" /></a>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/docs/guide.ko.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
10
|
-
<a href="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
11
|
-
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
9
|
+
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/docs/guide.ko.md"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/lucide-book-open.svg" width="16" alt="" /> 안내</a>
|
|
10
|
+
<a href="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/ignition-film.mp4"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/lucide-play.svg" width="16" alt="" /> Ignition 영상</a>
|
|
11
|
+
<a href="https://github.com/wjgoarxiv/lithermes/blob/main/LICENSE"><img src="https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/readme-assets/lucide-shield-check.svg" width="16" alt="" /> MIT</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
# LitHermes
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
**Hermes Agent**용 플러그인입니다. 요청 앞에 `lit`을 붙이면 Hermes가 작업을 계획하고, 해내고, 결과를 확인한 뒤 어디까지 왔는지 적어 둡니다. 그래서 다음 세션이 그 기록을 읽고 멈춘 자리에서 이어 갈 수 있습니다.
|
|
19
19
|
|
|
20
|
-
**[GitHub의 README와 문서](https://github.com/wjgoarxiv/lithermes/blob/main/README_Ko-KR.md)** · [English](https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.
|
|
20
|
+
**[GitHub의 README와 문서](https://github.com/wjgoarxiv/lithermes/blob/main/README_Ko-KR.md)** · [English](https://cdn.jsdelivr.net/npm/@litfamily/lithermes@1.0.30/README.md)
|
|
21
21
|
|
|
22
22
|
## 설치
|
|
23
23
|
|
|
@@ -51,11 +51,14 @@ lit 외부 의존성 없이 HTML 파일 하나로 할 일 목록을 만들어줘
|
|
|
51
51
|
| `lit research <질문>` | `litresearch` | 출처 메모가 있는 조사 |
|
|
52
52
|
| `/lit-humanizer` | `lit-humanizer` | 의미를 지키며 한국어·영어 문장 다듬기 |
|
|
53
53
|
| `/lit-diagram-drawer <brief>` | `lit-diagram-drawer` | 검사를 거친, 편집 가능한 다이어그램 |
|
|
54
|
-
| `/lit-
|
|
54
|
+
| `/lit-schematic <brief>` | `lit-schematic` | QA 게이트를 거친 P&ID·장치도·아이소메트릭 단면도 |
|
|
55
|
+
| `/lit-hijack <brief>` | `lit-hijack` | 라이선스 게이트와 parity 검증을 거친 공개 노하우의 클린룸 포팅 |
|
|
56
|
+
| `/lit-adhd [--here] [--since 7d] [--max 12]` | `lit-adhd` | 게이지와 다음 한 단계로 최근 세션을 브리핑합니다. 읽기 전용입니다. |
|
|
57
|
+
| `/lit-pptx <brief>` | `lit-pptx` | 열세 가지 디자인 방향 가운데 하나로 만든 PowerPoint 발표자료와 Markdown 원본 |
|
|
55
58
|
| `/lit-docx <brief>` | `lit-docx` | 여섯 가지 문서 형식 가운데 하나로 짠 절제된 Word 문서와 Markdown 원본 |
|
|
56
59
|
| `/lit-typographic-motion <brief>` | `lit-typographic-motion` | 트리트먼트부터 쓰는 짧은 영상 |
|
|
57
60
|
|
|
58
|
-
Telegram gateway에서는 `/lit_loop`와 `/lit_plan`을 쓰세요. 모든 스킬은 `lithermes:<이름>`으로도 불러올 수 있습니다. 예를 들어 `lithermes:lit-pptx`, `lithermes:lit-docx`처럼 씁니다. 스킬
|
|
61
|
+
Telegram gateway에서는 `/lit_loop`와 `/lit_plan`을 쓰세요. 모든 스킬은 `lithermes:<이름>`으로도 불러올 수 있습니다. 예를 들어 `lithermes:lit-pptx`, `lithermes:lit-docx`처럼 씁니다. 스킬 39개 전체는 [스킬과 명령](https://github.com/wjgoarxiv/lithermes/blob/main/docs/skills.ko.md)에서 그림과 함께 볼 수 있습니다.
|
|
59
62
|
|
|
60
63
|
## 확인, 업데이트, 삭제
|
|
61
64
|
|
|
@@ -86,6 +86,18 @@ CLI/plugin name, not the npm package name.
|
|
|
86
86
|
installed diagram skill. Its Python checks cover source geometry, accessibility,
|
|
87
87
|
content requirements, motion source rules, and visible-text findings; actual
|
|
88
88
|
rendering remains a separate local capability.
|
|
89
|
+
- `/lit-schematic <brief>` and the exact `lit-schematic` route load the
|
|
90
|
+
installed schematic skill. Drawings of real equipment (P&IDs, PFDs, apparatus
|
|
91
|
+
figures, isometric cutaways) belong here; abstract boxes-and-arrows stay with
|
|
92
|
+
`lithermes:lit-diagram-drawer`.
|
|
93
|
+
- `/lit-hijack <brief>` and the exact `lit-hijack` route (also `lit hijack`,
|
|
94
|
+
`lit hijacking`, `lit 하이재킹`, `lit 하이잭`) load the installed hijack skill.
|
|
95
|
+
Published know-how enters only through capture with provenance, a licence gate,
|
|
96
|
+
a source-free spec and a parity proof.
|
|
97
|
+
- `/lit-adhd [--here] [--since 7d] [--max 12]` and the exact `lit-adhd` route
|
|
98
|
+
(also `lit adhd`, `lit rewind`, `lit-rewind`) load the installed adhd skill.
|
|
99
|
+
One collector run reads the session store read-only and prints the
|
|
100
|
+
cross-session brief; a bare `go` continues the offered step within 30 minutes.
|
|
89
101
|
- The `pre_llm_call` hook injects an Litwork directive when the user says
|
|
90
102
|
a standalone `lit` or `litwork`. It also routes `lit plan`, `lit review`,
|
|
91
103
|
`lit research`, `lit goal`, and durable `lit workflow` / `lit kanban` / `lit team`
|
|
@@ -179,7 +191,8 @@ CLI/plugin name, not the npm package name.
|
|
|
179
191
|
`lithermes:frontend-ui-ux`, `lithermes:readme-studio`, `lithermes:lit-commit`,
|
|
180
192
|
`lithermes:lit-crucible`, `lithermes:lit-init`, `lithermes:lit-recap`,
|
|
181
193
|
`lithermes:lit-handoff`, `lithermes:lit-scientific-visualization`,
|
|
182
|
-
`lithermes:lit-diagram-drawer`,
|
|
194
|
+
`lithermes:lit-diagram-drawer`, `lithermes:lit-schematic`, `lithermes:lit-hijack`,
|
|
195
|
+
`lithermes:lit-adhd`,
|
|
183
196
|
`lithermes:lsp`, `lithermes:lsp-setup`,
|
|
184
197
|
`lithermes:litresearch`, `lithermes:lit-code`, `lithermes:refactor`,
|
|
185
198
|
`lithermes:lit-burnoff`, `lithermes:review-work`,
|
|
@@ -379,7 +392,7 @@ npm --prefix packages/lithermes-installer run sync-plugin -- --in-place
|
|
|
379
392
|
uses A/B checks, and keeps a claim/source/confidence/uncertainty graph. The
|
|
380
393
|
acquisition procedure loads from `lithermes:litresearch` through `skill_view`.
|
|
381
394
|
- `lit-crucible`, `lit-init`, `lit-recap`, `lit-handoff`,
|
|
382
|
-
`lit-scientific-visualization`,
|
|
395
|
+
`lit-scientific-visualization`, `lit-diagram-drawer`, `lit-schematic`, `lit-hijack`, and `lit-adhd`: bounded bare or exact natural routes load the bundled
|
|
383
396
|
skill body for the matching explicit skill; they do not fall back to generic
|
|
384
397
|
Litwork.
|
|
385
398
|
- `lit goal`: litgoal sets and keeps the finish line; lit-loop and start-work run toward it.
|
|
@@ -39,8 +39,11 @@ _NATIVE_COMMANDS = frozenset(
|
|
|
39
39
|
"lit-handoff",
|
|
40
40
|
"lit-scientific-visualization",
|
|
41
41
|
"lit-diagram-drawer",
|
|
42
|
+
"lit-schematic",
|
|
42
43
|
"lit-pptx",
|
|
43
44
|
"lit-docx",
|
|
45
|
+
"lit-hijack",
|
|
46
|
+
"lit-adhd",
|
|
44
47
|
"lit-typographic-motion",
|
|
45
48
|
*core.KOREAN_PROSE_COMMANDS,
|
|
46
49
|
*core.KOREAN_PROSE_ALIASES,
|
|
@@ -81,11 +84,11 @@ PORTED_SKILLS = [
|
|
|
81
84
|
),
|
|
82
85
|
(
|
|
83
86
|
"debugging",
|
|
84
|
-
"Use when something fails, hangs or returns a wrong result
|
|
87
|
+
"Use when something fails, hangs or returns a wrong result; the cause must be reproduced, fixed and rechecked.",
|
|
85
88
|
),
|
|
86
89
|
(
|
|
87
90
|
"deep-interview",
|
|
88
|
-
"Run the
|
|
91
|
+
"Run the Socratic deep-interview clarity gate before planning.",
|
|
89
92
|
),
|
|
90
93
|
(
|
|
91
94
|
"frontend-ui-ux",
|
|
@@ -95,16 +98,28 @@ PORTED_SKILLS = [
|
|
|
95
98
|
"lit-diagram-drawer",
|
|
96
99
|
"Create clear, accessible, Korean-ready diagrams with product-local Python verification and optional export.",
|
|
97
100
|
),
|
|
101
|
+
(
|
|
102
|
+
"lit-schematic",
|
|
103
|
+
"Draw P&IDs, PFDs, apparatus figures and isometric cutaways; QA-gated SVG with PDF and 600 dpi PNG in full material colour.",
|
|
104
|
+
),
|
|
98
105
|
("lit-pptx", "Create and inspect PowerPoint decks with the installed Office engine and QA gate."),
|
|
99
106
|
("lit-docx", "Create, edit, convert, and audit styled Word documents."),
|
|
100
|
-
(
|
|
107
|
+
(
|
|
108
|
+
"lit-hijack",
|
|
109
|
+
"Port published know-how into your skill.",
|
|
110
|
+
),
|
|
111
|
+
(
|
|
112
|
+
"lit-adhd",
|
|
113
|
+
"Cross-session brief with gauges and one next step.",
|
|
114
|
+
),
|
|
115
|
+
("lit-typographic-motion", "Direct an original film or a README cover loop, gated before delivery."),
|
|
101
116
|
(
|
|
102
117
|
"readme-studio",
|
|
103
118
|
"Write factual READMEs and compose local covers with outlined type, honest image capability and verified motion.",
|
|
104
119
|
),
|
|
105
120
|
(
|
|
106
121
|
"lit-commit",
|
|
107
|
-
"Run the
|
|
122
|
+
"Run the git-history specialist for commits, rebases, blame and bisect.",
|
|
108
123
|
),
|
|
109
124
|
(
|
|
110
125
|
"lit-brainstorm",
|
|
@@ -112,7 +127,7 @@ PORTED_SKILLS = [
|
|
|
112
127
|
),
|
|
113
128
|
(
|
|
114
129
|
"lit-crucible",
|
|
115
|
-
"Stress-test a plan with
|
|
130
|
+
"Stress-test a plan with delegate_task lanes before handing off to /lit-plan.",
|
|
116
131
|
),
|
|
117
132
|
(
|
|
118
133
|
"lit-init",
|
|
@@ -120,11 +135,11 @@ PORTED_SKILLS = [
|
|
|
120
135
|
),
|
|
121
136
|
(
|
|
122
137
|
"lsp",
|
|
123
|
-
"Use Hermes' native LSP diagnostics with
|
|
138
|
+
"Use Hermes' native LSP diagnostics with LSP guidance.",
|
|
124
139
|
),
|
|
125
140
|
(
|
|
126
141
|
"lit-code",
|
|
127
|
-
"Use
|
|
142
|
+
"Use programming references for Python, TypeScript, Go and Rust.",
|
|
128
143
|
),
|
|
129
144
|
(
|
|
130
145
|
"refactor",
|
|
@@ -156,7 +171,7 @@ PORTED_SKILLS = [
|
|
|
156
171
|
),
|
|
157
172
|
(
|
|
158
173
|
"litwork",
|
|
159
|
-
"Use when a defined code change must be carried to done: build, test, verify the real surface, report
|
|
174
|
+
"Use when a defined code change must be carried to done: build, test, verify the real surface, report; not for documents or decks.",
|
|
160
175
|
),
|
|
161
176
|
(
|
|
162
177
|
"visual-qa",
|
|
@@ -172,7 +187,7 @@ PORTED_SKILLS = [
|
|
|
172
187
|
),
|
|
173
188
|
(
|
|
174
189
|
"litresearch",
|
|
175
|
-
"Use when a question needs broad cited research into prior work or how others solve it
|
|
190
|
+
"Use when a question needs broad cited research into prior work or how others solve it; disputed claims checked at the source.",
|
|
176
191
|
),
|
|
177
192
|
(
|
|
178
193
|
"lit-recap",
|
|
@@ -458,7 +473,7 @@ def _setup_lithermes_cli(parser) -> None:
|
|
|
458
473
|
"slash commands: /lit /lit-loop /lit-plan /litgoal /review-work /start-work /deep-interview "
|
|
459
474
|
"/lit-humanizer (legacy aliases: /lit-korean /text-naturalization /text-neutralization "
|
|
460
475
|
"/korean-ai-slop-remover) /lit-recap "
|
|
461
|
-
"/lit-handoff /lit-scientific-visualization /lit-diagram-drawer /lit-pptx /lit-docx /lit-typographic-motion\n"
|
|
476
|
+
"/lit-handoff /lit-scientific-visualization /lit-diagram-drawer /lit-schematic /lit-pptx /lit-docx /lit-hijack /lit-adhd /lit-typographic-motion\n"
|
|
462
477
|
f"skills: {len(PORTED_SKILLS)} lithermes:* skills — `hermes lithermes status` lists them\n"
|
|
463
478
|
"contract schema: lithermes_llm_contract/v1 headings include #contract.activation, "
|
|
464
479
|
"#contract.inputs, #contract.outputs, #contract.evidence, and #contract.hard_stops\n"
|
|
@@ -774,6 +789,12 @@ def register(ctx) -> None:
|
|
|
774
789
|
description="Create and verify an accessible diagram from a supplied brief",
|
|
775
790
|
args_hint="<diagram brief>",
|
|
776
791
|
)
|
|
792
|
+
ctx.register_command(
|
|
793
|
+
"lit-schematic",
|
|
794
|
+
_command_handler(ctx, core.command_lit_schematic, "lit-schematic"),
|
|
795
|
+
description="Draw and QA-check a P&ID, PFD, apparatus figure or isometric cutaway from a supplied brief",
|
|
796
|
+
args_hint="<schematic brief>",
|
|
797
|
+
)
|
|
777
798
|
for name in ("lit-pptx", "lit-docx"):
|
|
778
799
|
ctx.register_command(
|
|
779
800
|
name,
|
|
@@ -781,6 +802,24 @@ def register(ctx) -> None:
|
|
|
781
802
|
description="Create and verify a PowerPoint deck" if name == "lit-pptx" else "Create and audit a Word document",
|
|
782
803
|
args_hint="<document brief>",
|
|
783
804
|
)
|
|
805
|
+
ctx.register_command(
|
|
806
|
+
"lit-hijack",
|
|
807
|
+
_command_handler(ctx, core.command_lit_hijack, "lit-hijack"),
|
|
808
|
+
description="Port published know-how into your own skill, clean-room",
|
|
809
|
+
args_hint="<urls or files> [into <target>]",
|
|
810
|
+
)
|
|
811
|
+
ctx.register_command(
|
|
812
|
+
"lit-adhd",
|
|
813
|
+
_command_handler(ctx, core.command_lit_adhd, "lit-adhd"),
|
|
814
|
+
description="Cross-session brief with gauges and one next step",
|
|
815
|
+
args_hint="[--here] [--since 7d] [--max 12]",
|
|
816
|
+
)
|
|
817
|
+
ctx.register_command(
|
|
818
|
+
"lit-rewind",
|
|
819
|
+
_command_handler(ctx, lambda raw: core.command_lit_adhd(raw, route="/lit-rewind"), "lit-adhd"),
|
|
820
|
+
description="Cross-session brief with gauges and one next step (alias of lit-adhd)",
|
|
821
|
+
args_hint="[--here] [--since 7d] [--max 12]",
|
|
822
|
+
)
|
|
784
823
|
ctx.register_command(
|
|
785
824
|
"lit-typographic-motion",
|
|
786
825
|
_command_handler(ctx, core.command_motion_skill, "lit-typographic-motion"),
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""Per-session discipline stack and `go` continuation for lit-adhd.
|
|
2
|
+
|
|
3
|
+
The prompt hook records each lit route activation as a frame in one guarded JSON file per
|
|
4
|
+
workspace (``.hermes/lithermes/adhd/stack.json``) so a later brief in another session can see
|
|
5
|
+
which disciplines are active. Hermes has a single chat lane per session and nothing can pause
|
|
6
|
+
a discipline, so a session holds at most one active frame: pushing a new skill finishes the
|
|
7
|
+
previous active frame, and there are no pause/resume transitions. lit-adhd and lit-recap are
|
|
8
|
+
read-only disciplines and never push a frame, so a brief in the middle of a lit-loop leaves
|
|
9
|
+
the loop exactly where it was.
|
|
10
|
+
|
|
11
|
+
A bare ``go`` (also ``lit go``, ``ㄱㄱ``, ``고``, ``진행``, as the whole prompt) continues the
|
|
12
|
+
step the last brief offered: the hook reads the next-step record the collector wrote for this
|
|
13
|
+
session (``.hermes/lithermes/adhd/next-<session>.json``) and returns a short context note for
|
|
14
|
+
the model. A record older than 30 minutes, or no record at all, reads as no next step on
|
|
15
|
+
record. Hermes has no typed ``go`` command; ``go`` is a word the hook consumes.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
import os
|
|
21
|
+
import re
|
|
22
|
+
import tempfile
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
STACK_VERSION = 1
|
|
27
|
+
STACK_DIRNAME = "adhd"
|
|
28
|
+
STACK_FILENAME = "stack.json"
|
|
29
|
+
MAX_SESSIONS = 64
|
|
30
|
+
MAX_FRAMES_PER_SESSION = 20
|
|
31
|
+
MAX_STATE_BYTES = 2 * 1024 * 1024
|
|
32
|
+
GO_TTL_SECONDS = 30 * 60
|
|
33
|
+
|
|
34
|
+
# Read-only disciplines never push a stack frame.
|
|
35
|
+
READ_ONLY_DISCIPLINES = frozenset({"lit-adhd", "lit-recap"})
|
|
36
|
+
|
|
37
|
+
_GO_WORD = re.compile(r"^(?:go|lit go|ㄱㄱ|고|진행)$", re.IGNORECASE)
|
|
38
|
+
_SESSION_SAFE = re.compile(r"[^A-Za-z0-9_-]")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def match_go_word(text: str) -> bool:
|
|
42
|
+
"""True when the whole prompt is a go word the hook should consume."""
|
|
43
|
+
return _GO_WORD.match(str(text or "").strip()) is not None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def adhd_dir(workspace: Path | str) -> Path:
|
|
47
|
+
return Path(workspace) / ".hermes" / "lithermes" / STACK_DIRNAME
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def stack_path(workspace: Path | str) -> Path:
|
|
51
|
+
return adhd_dir(workspace) / STACK_FILENAME
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def next_step_path(workspace: Path | str, session_id: Any) -> Path:
|
|
55
|
+
safe = _SESSION_SAFE.sub("_", str(session_id or "session"))[:128] or "session"
|
|
56
|
+
return adhd_dir(workspace) / f"next-{safe}.json"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def read_stack(workspace: Path | str) -> dict[str, Any]:
|
|
60
|
+
"""The stack file, or {} when it is missing, oversized or malformed. Never raises."""
|
|
61
|
+
try:
|
|
62
|
+
path = stack_path(workspace)
|
|
63
|
+
if not path.is_file() or path.stat().st_size > MAX_STATE_BYTES:
|
|
64
|
+
return {}
|
|
65
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
66
|
+
except (OSError, ValueError):
|
|
67
|
+
return {}
|
|
68
|
+
return data if isinstance(data, dict) else {}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _write_stack(workspace: Path | str, data: dict[str, Any]) -> bool:
|
|
72
|
+
"""Whole-file write through a temporary file. False when the write failed."""
|
|
73
|
+
try:
|
|
74
|
+
directory = adhd_dir(workspace)
|
|
75
|
+
# Refuse to write through a planted link: neither the adhd directory
|
|
76
|
+
# nor its `.hermes` parent may be a symlink. Missing paths are fine.
|
|
77
|
+
workspace_path = Path(workspace)
|
|
78
|
+
for probe in (directory, workspace_path / ".hermes"):
|
|
79
|
+
try:
|
|
80
|
+
if probe.is_symlink():
|
|
81
|
+
return False
|
|
82
|
+
except OSError:
|
|
83
|
+
return False
|
|
84
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
85
|
+
fd, staging = tempfile.mkstemp(dir=str(directory), prefix="stack-", suffix=".tmp")
|
|
86
|
+
try:
|
|
87
|
+
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
|
88
|
+
json.dump({"version": STACK_VERSION, "sessions": data.get("sessions", {})}, handle)
|
|
89
|
+
handle.write("\n")
|
|
90
|
+
os.replace(staging, stack_path(workspace))
|
|
91
|
+
finally:
|
|
92
|
+
try:
|
|
93
|
+
os.unlink(staging)
|
|
94
|
+
except OSError:
|
|
95
|
+
pass
|
|
96
|
+
return True
|
|
97
|
+
except (OSError, ValueError):
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _frames(data: dict[str, Any], session_id: str) -> list[dict[str, Any]]:
|
|
102
|
+
sessions = data.get("sessions")
|
|
103
|
+
if not isinstance(sessions, dict):
|
|
104
|
+
return []
|
|
105
|
+
record = sessions.get(session_id)
|
|
106
|
+
if not isinstance(record, dict):
|
|
107
|
+
return []
|
|
108
|
+
frames = record.get("frames")
|
|
109
|
+
return [frame for frame in frames if isinstance(frame, dict)] if isinstance(frames, list) else []
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def push(workspace: Path | str, session_id: Any, skill: str, *, stage: str = "", at: str = "") -> bool:
|
|
113
|
+
"""Record an activation: the previous active frame of this session finishes. Never raises."""
|
|
114
|
+
key = str(session_id or "")
|
|
115
|
+
skill = str(skill or "")
|
|
116
|
+
if not key or not skill or skill in READ_ONLY_DISCIPLINES:
|
|
117
|
+
return False
|
|
118
|
+
try:
|
|
119
|
+
data = read_stack(workspace)
|
|
120
|
+
sessions = data.get("sessions")
|
|
121
|
+
if not isinstance(sessions, dict):
|
|
122
|
+
sessions = {}
|
|
123
|
+
data["sessions"] = sessions
|
|
124
|
+
frames = _frames(data, key)
|
|
125
|
+
for frame in frames:
|
|
126
|
+
if frame.get("status") == "active":
|
|
127
|
+
frame["status"] = "finished"
|
|
128
|
+
frames.append({"skill": skill, "stage": stage, "status": "active", "at": at})
|
|
129
|
+
sessions[key] = {"frames": frames[-MAX_FRAMES_PER_SESSION:]}
|
|
130
|
+
while len(sessions) > MAX_SESSIONS:
|
|
131
|
+
oldest = next(iter(sessions))
|
|
132
|
+
if oldest == key:
|
|
133
|
+
break
|
|
134
|
+
del sessions[oldest]
|
|
135
|
+
return _write_stack(workspace, data)
|
|
136
|
+
except (OSError, ValueError):
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def finish(workspace: Path | str, session_id: Any, skill: str = "") -> bool:
|
|
141
|
+
"""Mark this session's latest active frame finished. Never raises."""
|
|
142
|
+
key = str(session_id or "")
|
|
143
|
+
if not key:
|
|
144
|
+
return False
|
|
145
|
+
try:
|
|
146
|
+
data = read_stack(workspace)
|
|
147
|
+
sessions = data.get("sessions")
|
|
148
|
+
if not isinstance(sessions, dict) or key not in sessions:
|
|
149
|
+
return False
|
|
150
|
+
frames = _frames(data, key)
|
|
151
|
+
for frame in reversed(frames):
|
|
152
|
+
if frame.get("status") == "active" and (not skill or frame.get("skill") == skill):
|
|
153
|
+
frame["status"] = "finished"
|
|
154
|
+
break
|
|
155
|
+
sessions[key] = {"frames": frames[-MAX_FRAMES_PER_SESSION:]}
|
|
156
|
+
return _write_stack(workspace, data)
|
|
157
|
+
except (OSError, ValueError):
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def read_next_step(workspace: Path | str, session_id: Any) -> dict[str, Any] | None:
|
|
162
|
+
"""This session's next-step record, or None when it is missing or malformed. Never raises."""
|
|
163
|
+
try:
|
|
164
|
+
path = next_step_path(workspace, session_id)
|
|
165
|
+
if not path.is_file() or path.stat().st_size > MAX_STATE_BYTES:
|
|
166
|
+
return None
|
|
167
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
168
|
+
except (OSError, ValueError):
|
|
169
|
+
return None
|
|
170
|
+
return data if isinstance(data, dict) and isinstance(data.get("kind"), str) else None
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def go_note(workspace: Path | str, session_id: Any, *, now: float | None = None) -> str:
|
|
174
|
+
"""The context note a consumed `go` injects: what to do next, or that nothing is on record."""
|
|
175
|
+
import time as _time
|
|
176
|
+
from datetime import datetime, timezone
|
|
177
|
+
|
|
178
|
+
def _stamp(raw: str) -> float:
|
|
179
|
+
parsed = datetime.fromisoformat(raw.replace("Z", "+00:00"))
|
|
180
|
+
if parsed.tzinfo is None:
|
|
181
|
+
parsed = parsed.replace(tzinfo=timezone.utc)
|
|
182
|
+
return parsed.timestamp()
|
|
183
|
+
|
|
184
|
+
record = read_next_step(workspace, session_id)
|
|
185
|
+
if record is None:
|
|
186
|
+
return (
|
|
187
|
+
"The user typed `go` with no brief on record: no next-step record exists for this "
|
|
188
|
+
"session. Offer `lit adhd` for a cross-session brief instead of inventing a step."
|
|
189
|
+
)
|
|
190
|
+
try:
|
|
191
|
+
at = _stamp(str(record.get("at", "")))
|
|
192
|
+
now_s = now if now is not None else _time.time()
|
|
193
|
+
if now_s - at > GO_TTL_SECONDS:
|
|
194
|
+
raise ValueError("expired")
|
|
195
|
+
except (ValueError, OverflowError, TypeError):
|
|
196
|
+
return (
|
|
197
|
+
"The user typed `go` but the brief's next-step record is older than 30 minutes: it "
|
|
198
|
+
"has expired. Offer `lit adhd` for a fresh brief instead of continuing the old step."
|
|
199
|
+
)
|
|
200
|
+
kind = str(record.get("kind", "none")).replace("-", " ")
|
|
201
|
+
target = record.get("target") or {}
|
|
202
|
+
if not isinstance(target, dict):
|
|
203
|
+
# A hand-edited or foreign record may store a bare string here; treat
|
|
204
|
+
# it as an empty detail rather than raising on `.get`.
|
|
205
|
+
target = {}
|
|
206
|
+
detail = target.get("plan") or target.get("workId") or target.get("skill") or ""
|
|
207
|
+
if record.get("kind") == "start-plan" and detail:
|
|
208
|
+
return (
|
|
209
|
+
f"The user typed `go` after a brief whose next step is: start plan {detail} with "
|
|
210
|
+
f"`/start-work {detail}`. Present that command for the user to run; do not run it, "
|
|
211
|
+
"and do not start anything else."
|
|
212
|
+
)
|
|
213
|
+
if record.get("kind") == "approve-boundary":
|
|
214
|
+
return (
|
|
215
|
+
"YOUR TURN\n"
|
|
216
|
+
"The user typed `go` after a brief whose next step is a bounded-work boundary "
|
|
217
|
+
f"({detail}): show what it wants and ask the user to approve or deny it in chat. "
|
|
218
|
+
"Never approve it yourself."
|
|
219
|
+
)
|
|
220
|
+
if kind != "none":
|
|
221
|
+
return (
|
|
222
|
+
f"The user typed `go` after a brief whose next step is: {kind}"
|
|
223
|
+
f"{f' ({detail})' if detail else ''}. Continue that step in chat; start nothing else."
|
|
224
|
+
)
|
|
225
|
+
return (
|
|
226
|
+
"The user typed `go` but the brief recorded no next step: say there is none instead "
|
|
227
|
+
"of inventing one."
|
|
228
|
+
)
|
|
@@ -111,6 +111,11 @@ try:
|
|
|
111
111
|
except (ImportError, ModuleNotFoundError):
|
|
112
112
|
import lit_reentry as _lit_reentry
|
|
113
113
|
|
|
114
|
+
try:
|
|
115
|
+
from . import adhd_stack as _adhd_stack
|
|
116
|
+
except (ImportError, ModuleNotFoundError):
|
|
117
|
+
import adhd_stack as _adhd_stack
|
|
118
|
+
|
|
114
119
|
# Current-turn state stays in the compatibility facade because tests and the
|
|
115
120
|
# plugin register surface intentionally inspect it directly.
|
|
116
121
|
_PENDING_IGNITE: set[str] = set()
|
|
@@ -272,13 +277,18 @@ def release_rules_session(session_id: Any) -> None:
|
|
|
272
277
|
def ignite(result: str | dict[str, str], route: str = "litwork") -> str | dict[str, str]:
|
|
273
278
|
"""Draw a command acknowledgement and require a separate model probe."""
|
|
274
279
|
mark = acknowledgement(route, color=True)
|
|
280
|
+
# Skill looks ride only on disciplines that keep one, never on unstyled
|
|
281
|
+
# routes, to protect the per-route byte budgets the budget tests pin. The
|
|
282
|
+
# discipline block folds in the session-state rules (YOUR TURN, ✦ done).
|
|
283
|
+
discipline_looks = route_look_block(route)
|
|
284
|
+
looks_suffix = f"\n\n{discipline_looks}" if discipline_looks else ""
|
|
275
285
|
if isinstance(result, dict):
|
|
276
286
|
updated = dict(result)
|
|
277
287
|
display = result.get("display")
|
|
278
288
|
if display and not str(display).startswith(mark):
|
|
279
289
|
updated["display"] = f"{mark}\n{display}"
|
|
280
290
|
if result.get("agent_message"):
|
|
281
|
-
updated["agent_message"] = f"{probe_contract(route)}\n\n{result['agent_message']}"
|
|
291
|
+
updated["agent_message"] = f"{probe_contract(route)}\n\n{result['agent_message']}{looks_suffix}"
|
|
282
292
|
return updated
|
|
283
293
|
if isinstance(result, str) and result.strip() and not result.startswith(mark):
|
|
284
294
|
return f"{mark}\n{result}"
|
|
@@ -1685,6 +1695,18 @@ def pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
|
1685
1695
|
bind_obj = _extract_bind_goal(user_message)
|
|
1686
1696
|
if bind_obj:
|
|
1687
1697
|
return None
|
|
1698
|
+
# A bare `go` continues the step the last brief offered. The hook consumes
|
|
1699
|
+
# the word and injects the next-step record; it never runs a command.
|
|
1700
|
+
# Hermes has no typed `go`, so nothing else can collide with this match.
|
|
1701
|
+
if _adhd_stack.match_go_word(user_message):
|
|
1702
|
+
try:
|
|
1703
|
+
note = _adhd_stack.go_note(Path.cwd().resolve(), session_id)
|
|
1704
|
+
except Exception:
|
|
1705
|
+
note = (
|
|
1706
|
+
"The user typed `go` but the next-step record could not be read. "
|
|
1707
|
+
"Offer `lit adhd` for a fresh brief instead of inventing a step."
|
|
1708
|
+
)
|
|
1709
|
+
return {"context": note}
|
|
1688
1710
|
# /lit and /lit-loop inject a run-context message. Durable run state already
|
|
1689
1711
|
# exists, so skip re-injecting context without touching native /goal state.
|
|
1690
1712
|
if "<lithermes-run-context>" in user_message:
|
|
@@ -1729,7 +1751,7 @@ def pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
|
1729
1751
|
if session_id:
|
|
1730
1752
|
_PENDING_BLOCK[session_id] = route.block_message
|
|
1731
1753
|
_evict_pending_browser_state()
|
|
1732
|
-
return with_reader_contract(build_natural_mode_context(route), compact=True)
|
|
1754
|
+
return with_reader_contract(build_natural_mode_context(route, session_id=session_id), compact=True)
|
|
1733
1755
|
|
|
1734
1756
|
active = discipline(route.mode) if session_id else ""
|
|
1735
1757
|
compacted = _rules.compaction_stamp(kwargs.get("conversation_history"))
|
|
@@ -1762,13 +1784,15 @@ def pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
|
1762
1784
|
if route.mode == "lit-plan" and route.objective:
|
|
1763
1785
|
planned = command_lit_plan(shlex.quote(route.objective))
|
|
1764
1786
|
_lit_reentry.remember(session_id, active, plan=planned["plan"], compacted=compacted)
|
|
1787
|
+
_adhd_stack.push(Path.cwd().resolve(), session_id, active)
|
|
1765
1788
|
return with_reader_contract(
|
|
1766
|
-
f"{build_natural_mode_context(route)}\n\n"
|
|
1789
|
+
f"{build_natural_mode_context(route, session_id=session_id)}\n\n"
|
|
1767
1790
|
f"Durable plan: {planned['plan']}",
|
|
1768
1791
|
compact=True,
|
|
1769
1792
|
)
|
|
1770
1793
|
if route.mode != "litwork":
|
|
1771
1794
|
_lit_reentry.remember(session_id, active, compacted=compacted)
|
|
1795
|
+
_adhd_stack.push(Path.cwd().resolve(), session_id, active)
|
|
1772
1796
|
if route.mode in _SKILL_ROUTE_CONTRACTS:
|
|
1773
1797
|
compact_contract = reader_facing_contract_block(
|
|
1774
1798
|
requested_reader_mode,
|
|
@@ -1782,10 +1806,11 @@ def pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
|
1782
1806
|
route,
|
|
1783
1807
|
browser_report=browser_report,
|
|
1784
1808
|
reader_contract=compact_contract,
|
|
1809
|
+
session_id=session_id,
|
|
1785
1810
|
)
|
|
1786
1811
|
}
|
|
1787
1812
|
return with_reader_contract(
|
|
1788
|
-
build_natural_mode_context(route, browser_report=browser_report),
|
|
1813
|
+
build_natural_mode_context(route, browser_report=browser_report, session_id=session_id),
|
|
1789
1814
|
compact=True,
|
|
1790
1815
|
)
|
|
1791
1816
|
|
|
@@ -1802,6 +1827,7 @@ def pre_llm_call(**kwargs: Any) -> dict[str, str] | None:
|
|
|
1802
1827
|
)
|
|
1803
1828
|
run_binding = build_run_binding(load_run_state(run_dir))
|
|
1804
1829
|
_lit_reentry.remember(session_id, active, run=str(run_dir), compacted=compacted)
|
|
1830
|
+
_adhd_stack.push(workspace, session_id, active)
|
|
1805
1831
|
ui_handoff = litwork_ui_handoff(route.objective)
|
|
1806
1832
|
# A bare `lit` with nothing active asks what to start; every other activation is unchanged.
|
|
1807
1833
|
idle_note = f"\n\n{_lit_reentry.IDLE_NOTE}" if not run_binding and step.idle else ""
|