@litfamily/lithermes 1.0.7 → 1.0.9
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 +299 -13
- package/README_Ko-KR.md +300 -14
- package/assets/lithermes-plugin/README.md +17 -6
- package/assets/lithermes-plugin/__init__.py +96 -21
- package/assets/lithermes-plugin/core.py +15 -6
- package/assets/lithermes-plugin/core_commands.py +140 -28
- package/assets/lithermes-plugin/core_contexts.py +88 -15
- package/assets/lithermes-plugin/core_contract.py +118 -9
- package/assets/lithermes-plugin/core_routing.py +197 -8
- package/assets/lithermes-plugin/deliverable_hedge_guard.py +378 -357
- package/assets/lithermes-plugin/diagnostics.py +76 -8
- package/assets/lithermes-plugin/humanizer_detector.py +348 -0
- package/assets/lithermes-plugin/humanizer_ko_metrics.py +108 -0
- package/assets/lithermes-plugin/humanizer_office.py +18 -0
- package/assets/lithermes-plugin/lit_mark.py +1 -1
- package/assets/lithermes-plugin/motion_receipts.py +80 -0
- package/assets/lithermes-plugin/payload-version.json +2240 -64
- package/assets/lithermes-plugin/plugin.yaml +1 -1
- package/assets/lithermes-plugin/rules/bundled-rules/lit-humanizer.md +14 -0
- package/assets/lithermes-plugin/skills/autoconference/assets/report_template.md +2 -1
- package/assets/lithermes-plugin/skills/autoconference/modes/ship/SKILL.md +11 -8
- package/assets/lithermes-plugin/skills/autoresearch/modes/ship/type-checklists.md +2 -2
- package/assets/lithermes-plugin/skills/browser-drive/ORIGIN.json +17 -0
- package/assets/lithermes-plugin/skills/browser-drive/SKILL.md +41 -16
- package/assets/lithermes-plugin/skills/browser-drive/scripts/capability_probe.py +122 -10
- package/assets/lithermes-plugin/skills/frontend-ui-ux/SKILL.md +45 -13
- package/assets/lithermes-plugin/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +51 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/README.md +44 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/adaptive-layout.md +34 -62
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/brand-and-imagery.md +22 -70
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/complete-contract.md +18 -4
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/composition.md +27 -78
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/craft-floor.md +74 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/creative-directions.md +25 -69
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/evidence-review.md +18 -97
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/implementation-platforms.md +23 -83
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/inclusive-interface.md +22 -70
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/interaction-motion.md +34 -68
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/motion-guide.md +62 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/operating-lanes.md +14 -78
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/performance-delivery.md +22 -71
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/product-direction.md +17 -70
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/production.md +19 -7
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/redesign-playbook.md +23 -76
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/slop-register.md +69 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/system-foundations.md +22 -67
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-language.md +16 -72
- package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-reconstruction.md +16 -81
- package/assets/lithermes-plugin/skills/frontend-ui-ux/resources/THIRD-PARTY-NOTICE.txt +15 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-page.js +311 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-rules.json +46 -0
- package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe.mjs +231 -0
- package/assets/lithermes-plugin/skills/lit-comprehend/SKILL.md +36 -25
- package/assets/lithermes-plugin/skills/lit-comprehend/references/artifact-template.md +45 -87
- package/assets/lithermes-plugin/skills/lit-comprehend/scripts/verify-explainer.py +3 -27
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/NOTICE +33 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/SKILL.md +308 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/provenance.json +22 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/icons.html +231 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/index.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/accessibility.md +37 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/export.md +29 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-drawio.md +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-excalidraw.md +14 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-mermaid.md +18 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-schema.md +28 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/motion.md +29 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/office-pptx-docx.md +40 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/output-spec.md +48 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/profiles.md +24 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/style-guide.md +67 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bar.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bump.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-er.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-journey.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-layers.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-line.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-nested.md +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-polar.md +67 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-process.md +58 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-radar.md +57 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state.md +59 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-venn.md +51 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/verifier-guide.md +31 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/browser-version.mjs +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/check-visible-text.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_brief.py +192 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_catalog.py +135 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_checks.py +123 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_cli.py +94 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_geometry.py +130 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_metrics.py +166 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality.py +293 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality_geometry.py +200 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_records.py +205 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_sequence.py +55 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/doctor.mjs +24 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_extract.py +209 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_source.py +188 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_extract.py +233 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_support.py +64 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/export.mjs +125 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_extract.py +240 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_source.py +39 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/office-safety.mjs +54 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-all.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-brief.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-diagram.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-motion.py +12 -0
- package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-type.py +12 -0
- package/assets/lithermes-plugin/skills/lit-docx/NOTICE +1 -0
- package/assets/lithermes-plugin/skills/lit-docx/SKILL.md +97 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/frontmatter_schema.md +42 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/journal_style_spec.md +17 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
- package/assets/lithermes-plugin/skills/lit-docx/references/slop_rules.md +35 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/clean_markdown.py +95 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_docx.py +1041 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_pdf.py +281 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_pdf.py +130 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/edit_docx.py +297 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/embed_images.py +78 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/generate_docx_templates.py +491 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/slop_lint.py +536 -0
- package/assets/lithermes-plugin/skills/lit-docx/scripts/visual_audit.py +41 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/acs.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/elsevier.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/ieee.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/docx/nature.docx +0 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/README.md +5 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/template.tex +37 -0
- package/assets/lithermes-plugin/skills/lit-docx/templates/registry.yaml +1366 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/NOTICE +170 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/SKILL.md +125 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/assets/report-skeleton.md +26 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/assets/slide-text-skeleton.md +30 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/before.md +15 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/before.md +12 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/after.md +10 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/before.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/before.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/ko-metrics-golden.json +49 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/pos-real.txt +26 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/rule-cases.json +306 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/before.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/before.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/before.md +13 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/after.md +15 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/before.md +17 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/after.md +7 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/before.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/after.md +12 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/before.md +14 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/after.md +13 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/before.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/after.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/before.md +19 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/README.md +16 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/always-on-rule.md +9 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/code-patterns.md +468 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/deliverable-channels.md +111 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-content.md +243 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns.md +57 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-metrics.md +33 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns.md +31 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/references/taxonomy.md +153 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/rules.json +884 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/scripts/detect.py +17 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/scripts/extract_office_text.py +114 -0
- package/assets/lithermes-plugin/skills/lit-humanizer/scripts/ko_metrics.py +35 -0
- package/assets/lithermes-plugin/skills/lit-pptx/NOTICE +1 -0
- package/assets/lithermes-plugin/skills/lit-pptx/SKILL.md +109 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/analyst.md +49 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/antithesis.md +65 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/architect.md +44 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/critic.md +42 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/synthesizer.md +47 -0
- package/assets/lithermes-plugin/skills/lit-pptx/agents/thesis.md +33 -0
- package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-md.png +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/bin/office.mjs +77 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/PRETENDARD-OFL.txt +94 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Black.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Bold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraBold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraLight.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Light.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Medium.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Regular.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-SemiBold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Thin.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/OFL.txt +94 -0
- package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/SOURCE.md +29 -0
- package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Bold.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Regular.otf +0 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/anti-slop-checklist.md +71 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/authoring-guide.md +139 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/consensus-protocol.md +125 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/data-display-cookbook.md +45 -0
- package/assets/lithermes-plugin/skills/lit-pptx/references/design-system-azure.md +58 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/package-lock.json +750 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/package.json +15 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.in +7 -0
- package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.lock +391 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/compile-deck.js +447 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/craft_extras.py +215 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/embed_fonts.py +199 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/integrity.py +60 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/inventory.py +64 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/learn_template.py +433 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/font-map.js +79 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-bg.js +85 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +36 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/layout-resolver.js +736 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-html.js +357 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +1864 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/slide-ast.js +539 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/template-registry.js +355 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/qa_deck.py +791 -0
- package/assets/lithermes-plugin/skills/lit-pptx/scripts/validate_pptx.py +206 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v1.md +251 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v2.md +221 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v1.schema.json +229 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v2.schema.json +144 -0
- package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/template-enrollment-contract.md +228 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +384 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +405 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
- package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
- package/assets/lithermes-plugin/skills/lit-scientific-visualization/SKILL.md +2 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/SKILL.md +71 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/audio.py +45 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/motion.mjs +690 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/runtime.mjs +299 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/NOTICE +23 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +55 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/browser.mjs +169 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/completion.mjs +52 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/constants.mjs +162 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/director.mjs +33 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/encode.mjs +191 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/flash.mjs +163 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/frame.mjs +428 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/gate.mjs +483 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/look.mjs +223 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/page.js +622 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/presets.mjs +170 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/scenes.mjs +242 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/sound.mjs +382 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-gate.mjs +97 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-init.js +186 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-kit.js +389 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-qa.mjs +358 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-worker.mjs +33 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage.mjs +691 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stills.mjs +71 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stroke.mjs +231 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/timeline.mjs +177 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/treatment.mjs +244 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/type.mjs +183 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/util.mjs +152 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/craft-loop.md +175 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/engine-contract.md +166 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/runtime.md +122 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/stage.md +261 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/style-bibles.md +122 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/treatment.md +164 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/references/type-craft.md +92 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/fonts.json +154 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/CREDITS +20 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/EMS-OFL.txt +91 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package-lock.json +88 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package.json +12 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.in +1 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.lock +727 -0
- package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/word-timing.json +9 -0
- package/assets/lithermes-plugin/skills/litresearch/SKILL.md +19 -18
- package/assets/lithermes-plugin/skills/litwork/SKILL.md +28 -0
- package/assets/lithermes-plugin/skills/visual-qa/references/complete-contract.md +3 -3
- package/package.json +1 -1
- package/readme-assets/ab-simple/s11-ui-baseline-desktop.webp +0 -0
- package/readme-assets/ab-simple/s11-ui-lithermes-desktop.webp +0 -0
- package/readme-assets/ab-simple/s3-ui-baseline-desktop.webp +0 -0
- package/readme-assets/ab-simple/s3-ui-lithermes-desktop.webp +0 -0
- package/readme-assets/ab-simple/s4-ui-baseline-desktop.webp +0 -0
- package/readme-assets/ab-simple/s4-ui-lithermes-desktop.webp +0 -0
- package/readme-assets/ab-simple/s5-office-baseline-slides.webp +0 -0
- package/readme-assets/ab-simple/s5-office-lithermes-slides.webp +0 -0
- package/readme-assets/ab-simple/s7-lithermes-diagram.webp +0 -0
- package/readme-assets/ab-simple/s8-office-baseline-slides.webp +0 -0
- package/readme-assets/ab-simple/s8-office-lithermes-slides.webp +0 -0
- package/readme-assets/ab-simple/s9-office-lithermes-pages.webp +0 -0
- package/readme-assets/badge-version.svg +1 -1
- package/readme-assets/cover-motion-still.webp +0 -0
- package/readme-assets/cover-motion.webp +0 -0
- package/readme-assets/skills/autoconference.webp +0 -0
- package/readme-assets/skills/autoresearch.webp +0 -0
- package/readme-assets/skills/browser-drive.webp +0 -0
- package/readme-assets/skills/comment-checker.webp +0 -0
- package/readme-assets/skills/debugging.webp +0 -0
- package/readme-assets/skills/deep-interview.webp +0 -0
- package/readme-assets/skills/frontend-ui-ux.webp +0 -0
- package/readme-assets/skills/lit-burnoff-file.webp +0 -0
- package/readme-assets/skills/lit-burnoff.webp +0 -0
- package/readme-assets/skills/lit-code.webp +0 -0
- package/readme-assets/skills/lit-commit.webp +0 -0
- package/readme-assets/skills/lit-comprehend.webp +0 -0
- package/readme-assets/skills/lit-crucible.webp +0 -0
- package/readme-assets/skills/lit-diagram-drawer.webp +0 -0
- package/readme-assets/skills/lit-docx.webp +0 -0
- package/readme-assets/skills/lit-handoff.webp +0 -0
- package/readme-assets/skills/lit-humanizer.webp +0 -0
- package/readme-assets/skills/lit-init.webp +0 -0
- package/readme-assets/skills/lit-plan.webp +0 -0
- package/readme-assets/skills/lit-pptx.webp +0 -0
- package/readme-assets/skills/lit-recap.webp +0 -0
- package/readme-assets/skills/lit-scientific-visualization.webp +0 -0
- package/readme-assets/skills/lit-typographic-motion.webp +0 -0
- package/readme-assets/skills/litgoal.webp +0 -0
- package/readme-assets/skills/litresearch.webp +0 -0
- package/readme-assets/skills/litwork.webp +0 -0
- package/readme-assets/skills/lsp-setup.webp +0 -0
- package/readme-assets/skills/lsp.webp +0 -0
- package/readme-assets/skills/readme-studio.webp +0 -0
- package/readme-assets/skills/refactor.webp +0 -0
- package/readme-assets/skills/review-work.webp +0 -0
- package/readme-assets/skills/rules.webp +0 -0
- package/readme-assets/skills/start-work.webp +0 -0
- package/readme-assets/skills/structural-search.webp +0 -0
- package/readme-assets/skills/visual-qa.webp +0 -0
- package/readme-assets/skills/wikify.webp +0 -0
- package/src/cli.js +40 -1
- package/src/lib/check.js +21 -0
- package/src/lib/install.js +262 -7
- package/src/lib/skillPayload.js +3 -3
- package/assets/lithermes-plugin/skills/lit-korean/SKILL.md +0 -237
- package/assets/lithermes-plugin/skills/lit-korean/references/quick-rules.md +0 -24
- package/assets/lithermes-plugin/skills/lit-korean/references/safety-checklist.md +0 -23
- package/readme-assets/cover.webp +0 -0
|
@@ -1,140 +1,52 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Changed-text LitHumanizer enforcement at Hermes' supported file hooks.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
``pre_tool_call`` can deny ``write_file`` and ``patch`` before persistence. The
|
|
4
|
+
``post_tool_call`` observer cannot undo a completed Office/PDF export, so those
|
|
5
|
+
checks are advisory and ask for a source edit and rebuild.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import difflib
|
|
11
|
+
import json
|
|
10
12
|
import os
|
|
11
13
|
import re
|
|
12
14
|
import stat
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
13
17
|
from dataclasses import dataclass
|
|
14
18
|
from pathlib import Path
|
|
15
19
|
from typing import Iterable
|
|
16
20
|
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
PLUGIN_ROOT = Path(__file__).resolve().parent
|
|
23
|
+
DETECTOR = PLUGIN_ROOT / "skills" / "lit-humanizer" / "scripts" / "detect.py"
|
|
19
24
|
MAX_SESSIONS = 64
|
|
20
25
|
MAX_FILE_BYTES = 2 * 1024 * 1024
|
|
26
|
+
MAX_DETECT_BYTES = 512 * 1024
|
|
27
|
+
MAX_DETECT_OUTPUT = 2 * 1024 * 1024
|
|
21
28
|
MAX_ARTIFACT_PATHS = 32
|
|
22
29
|
MAX_AGGREGATE_FILE_BYTES = 4 * 1024 * 1024
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
MAX_CONTEXT_LINES = 6
|
|
31
|
+
DETECT_TIMEOUT_SECONDS = 3
|
|
32
|
+
TEXT_SUFFIXES = frozenset({".adoc", ".csv", ".htm", ".html", ".md", ".mdx", ".rst", ".svg", ".tex", ".txt"})
|
|
33
|
+
OFFICE_SUFFIXES = frozenset({".docx", ".pptx", ".pdf"})
|
|
34
|
+
READER_FACING_SUFFIXES = TEXT_SUFFIXES | OFFICE_SUFFIXES
|
|
35
|
+
|
|
36
|
+
_QUOTED_SPAN = re.compile(
|
|
37
|
+
r'"([^"\n]{1,2000})"|“([^”\n]{1,2000})”|'
|
|
38
|
+
r"‘([^’\n]{1,2000})’|«([^»\n]{1,2000})»|"
|
|
39
|
+
r"(?<!\w)'([^'\n]{8,1000})'(?!\w)"
|
|
26
40
|
)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"working_note": "inline",
|
|
32
|
-
"no_artifact": "reply",
|
|
33
|
-
}
|
|
34
|
-
ROUTE_SKILL_ALIASES = {
|
|
35
|
-
"korean-prose-cleanup": "lit-korean",
|
|
36
|
-
}
|
|
37
|
-
REFERENCE_CONTRACT_SKILLS = frozenset({"frontend-ui-ux", "visual-qa"})
|
|
38
|
-
|
|
39
|
-
_OUTPUT_BLOCK = re.compile(
|
|
40
|
-
r"(?ms)^## #contract\.output_channels\s*$\s*^```yaml\s*$\n(?P<body>.*?)^```\s*$"
|
|
41
|
-
)
|
|
42
|
-
_SCALAR = re.compile(
|
|
43
|
-
r"^\s*(artifact_genre|limitations_channel)\s*:\s*([a-z_]+)\s*$",
|
|
44
|
-
re.MULTILINE,
|
|
45
|
-
)
|
|
46
|
-
_FENCE = re.compile(r"^\s*(`{3,}|~{3,})")
|
|
47
|
-
_YAML_OR_JSON_SCALAR = re.compile(
|
|
48
|
-
r'^\s*(?:[A-Za-z_][A-Za-z0-9_.-]*|"[^"]+"|\'[^\']+\')\s*:\s*.+?\s*,?\s*$'
|
|
49
|
-
)
|
|
50
|
-
_QUOTED = re.compile(r'(["\'`])([^"\'`]+)\1')
|
|
51
|
-
_STATUS_VALUE = re.compile(
|
|
52
|
-
r"^(?:pending|blocked|in[_ -]?progress|done|complete|pass|fail|보류\s*중|진행\s*중|완료|차단)$",
|
|
53
|
-
re.IGNORECASE,
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
_EVIDENCE_NOUN_KO = (
|
|
57
|
-
r"(?:근거|자료|데이터|측정(?:값|치|자료)|관찰\s*기록|사용자\s*관찰|실험\s*결과|"
|
|
58
|
-
r"검증\s*결과|평가\s*자료|출처|문헌|증거|수치)"
|
|
59
|
-
)
|
|
60
|
-
_ABSENCE_KO = (
|
|
61
|
-
r"(?:없(?:다|습니다|음|어|어서|으므로|기\s*때문)?|부재|제공되지\s*않|주어지지\s*않|"
|
|
62
|
-
r"확인되지\s*않|검증되지\s*않)"
|
|
63
|
-
)
|
|
64
|
-
_ABILITY_KO = r"(?:(?:평가|판단|산정)할\s*수\s*없|알\s*수\s*없)"
|
|
65
|
-
_ABSENT_EVIDENCE_KO = re.compile(
|
|
66
|
-
rf"(?:{_EVIDENCE_NOUN_KO}.{{0,48}}{_ABSENCE_KO}|{_ABSENCE_KO}.{{0,24}}{_EVIDENCE_NOUN_KO}|"
|
|
67
|
-
rf"{_EVIDENCE_NOUN_KO}.{{0,64}}{_ABILITY_KO})",
|
|
68
|
-
re.IGNORECASE,
|
|
69
|
-
)
|
|
70
|
-
_ABSENT_EVIDENCE_EN = re.compile(
|
|
71
|
-
r"(?:no\s+(?:supporting\s+)?evidence\s+yet|not\s+yet\s+substantiated|"
|
|
72
|
-
r"(?:evidence|data|measurements?|observations?|records?|sources?|citations?|test\s+results?)"
|
|
73
|
-
r".{0,48}(?:is|are|was|were)?\s*(?:absent|missing|unavailable|not\s+provided|not\s+verified)|"
|
|
74
|
-
r"(?:cannot|could\s+not)\s+(?:assess|determine|calculate).{0,48}"
|
|
75
|
-
r"(?:evidence|data|measurements?|observations?|records?|sources?|citations?))",
|
|
76
|
-
re.IGNORECASE,
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
_PATTERNS = (
|
|
80
|
-
(
|
|
81
|
-
"deferred",
|
|
82
|
-
re.compile(
|
|
83
|
-
r"보류\s*중|별도로\s*진행|추후\s*진행|to be determined separately",
|
|
84
|
-
re.IGNORECASE,
|
|
85
|
-
),
|
|
86
|
-
),
|
|
87
|
-
("absent-evidence", _ABSENT_EVIDENCE_KO),
|
|
88
|
-
("absent-evidence", _ABSENT_EVIDENCE_EN),
|
|
89
|
-
(
|
|
90
|
-
"scope-limit",
|
|
91
|
-
re.compile(
|
|
92
|
-
r"한정됩니다|국한됩니다|범위\s*내에서만|limited to the provided evidence",
|
|
93
|
-
re.IGNORECASE,
|
|
94
|
-
),
|
|
95
|
-
),
|
|
96
|
-
(
|
|
97
|
-
"negated-action",
|
|
98
|
-
re.compile(
|
|
99
|
-
r"하지\s*않았습니다|포함되지\s*않습니다|다루지\s*않습니다|was not performed|is not included",
|
|
100
|
-
re.IGNORECASE,
|
|
101
|
-
),
|
|
102
|
-
),
|
|
103
|
-
(
|
|
104
|
-
"self-protection",
|
|
105
|
-
re.compile(
|
|
106
|
-
r"참고용|추가\s*검증이\s*필요|완전하지\s*않을\s*수\s*있|for reference only|may be incomplete",
|
|
107
|
-
re.IGNORECASE,
|
|
108
|
-
),
|
|
109
|
-
),
|
|
110
|
-
("process-meta", re.compile(r"as an AI|이\s*작업에서는|프롬프트가", re.IGNORECASE)),
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
@dataclass(frozen=True)
|
|
115
|
-
class OutputChannel:
|
|
116
|
-
artifact_genre: str
|
|
117
|
-
limitations_channel: str
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
@dataclass(frozen=True)
|
|
121
|
-
class Finding:
|
|
122
|
-
pattern_class: str
|
|
123
|
-
line_number: int
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
@dataclass(frozen=True)
|
|
127
|
-
class PendingReceipt:
|
|
128
|
-
skill_id: str
|
|
129
|
-
contract: OutputChannel
|
|
130
|
-
finding_count: int
|
|
131
|
-
line_numbers: tuple[int, ...]
|
|
132
|
-
file_count: int
|
|
41
|
+
_INTERNAL_FILE = re.compile(r"(?:^|/)(?:plans|evidence|ledgers?|\.hermes|\.lit[^/]*)(?:/|$)|(?:^|/)HANDOFF[^/]*$", re.I)
|
|
42
|
+
_V4A_FILE = re.compile(r"^\*\*\* (Add|Update|Delete) File: (.+)$")
|
|
43
|
+
_V4A_MOVE = re.compile(r"^\*\*\* Move to: (.+)$")
|
|
44
|
+
_RULE_ID = re.compile(r"^[a-z0-9][a-z0-9-]{0,79}$")
|
|
133
45
|
|
|
134
46
|
|
|
135
47
|
@dataclass(frozen=True)
|
|
136
|
-
class
|
|
137
|
-
|
|
48
|
+
class _StableFile:
|
|
49
|
+
data: bytes
|
|
138
50
|
byte_count: int
|
|
139
51
|
|
|
140
52
|
|
|
@@ -143,27 +55,23 @@ class _ReadBudgetExceeded:
|
|
|
143
55
|
|
|
144
56
|
|
|
145
57
|
_READ_BUDGET_EXCEEDED = _ReadBudgetExceeded()
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
_ACTIVE_SKILLS: dict[str, str] = {}
|
|
149
58
|
_ROOT_TURNS: dict[str, str] = {}
|
|
150
|
-
|
|
59
|
+
_USER_QUOTES: dict[str, tuple[str, ...]] = {}
|
|
60
|
+
_PENDING_ADVISORIES: dict[str, list[str]] = {}
|
|
151
61
|
|
|
152
62
|
|
|
153
63
|
def reset_state() -> None:
|
|
154
|
-
"""Clear in-memory hook state; used by host lifecycle and isolated drivers."""
|
|
155
|
-
_ACTIVE_SKILLS.clear()
|
|
156
64
|
_ROOT_TURNS.clear()
|
|
157
|
-
|
|
65
|
+
_USER_QUOTES.clear()
|
|
66
|
+
_PENDING_ADVISORIES.clear()
|
|
158
67
|
|
|
159
68
|
|
|
160
69
|
def release_session(session_id: object) -> None:
|
|
161
70
|
key = str(session_id or "")
|
|
162
|
-
if
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
_PENDING_RECEIPTS.pop(key, None)
|
|
71
|
+
if key:
|
|
72
|
+
_ROOT_TURNS.pop(key, None)
|
|
73
|
+
_USER_QUOTES.pop(key, None)
|
|
74
|
+
_PENDING_ADVISORIES.pop(key, None)
|
|
167
75
|
|
|
168
76
|
|
|
169
77
|
def _bounded_set(mapping: dict[str, object], key: str, value: object) -> None:
|
|
@@ -173,165 +81,60 @@ def _bounded_set(mapping: dict[str, object], key: str, value: object) -> None:
|
|
|
173
81
|
mapping.pop(next(iter(mapping)), None)
|
|
174
82
|
|
|
175
83
|
|
|
176
|
-
def _contract_path(skill_id: str) -> Path:
|
|
177
|
-
skill_root = SKILLS_ROOT / skill_id
|
|
178
|
-
entrypoint = skill_root / "SKILL.md"
|
|
179
|
-
if skill_id not in REFERENCE_CONTRACT_SKILLS:
|
|
180
|
-
return entrypoint
|
|
181
|
-
if entrypoint.is_file() and "## #contract.output_channels" in entrypoint.read_text(encoding="utf-8"):
|
|
182
|
-
raise ValueError(f"lazy-reference skill declares output channel in entrypoint: {skill_id}")
|
|
183
|
-
return skill_root / "references" / "complete-contract.md"
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def load_output_channel(skill_id: str) -> OutputChannel:
|
|
187
|
-
if not re.fullmatch(r"[a-z0-9-]+", str(skill_id or "")):
|
|
188
|
-
raise ValueError("invalid skill id")
|
|
189
|
-
path = _contract_path(skill_id)
|
|
190
|
-
text = path.read_text(encoding="utf-8")
|
|
191
|
-
match = _OUTPUT_BLOCK.search(text)
|
|
192
|
-
if match is None:
|
|
193
|
-
raise ValueError(f"output channel declaration missing for {skill_id}")
|
|
194
|
-
values = dict(_SCALAR.findall(match.group("body")))
|
|
195
|
-
genre = values.get("artifact_genre", "")
|
|
196
|
-
channel = values.get("limitations_channel", "")
|
|
197
|
-
if genre not in CHANNEL_BY_GENRE or CHANNEL_BY_GENRE[genre] != channel:
|
|
198
|
-
raise ValueError(f"invalid output channel declaration for {skill_id}")
|
|
199
|
-
return OutputChannel(genre, channel)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def activate_skill(session_id: object, route_or_skill: object) -> bool:
|
|
203
|
-
key = str(session_id or "")
|
|
204
|
-
candidate = ROUTE_SKILL_ALIASES.get(str(route_or_skill or ""), str(route_or_skill or ""))
|
|
205
|
-
if not key:
|
|
206
|
-
return False
|
|
207
|
-
try:
|
|
208
|
-
load_output_channel(candidate)
|
|
209
|
-
except (OSError, UnicodeError, ValueError):
|
|
210
|
-
_ACTIVE_SKILLS.pop(key, None)
|
|
211
|
-
return False
|
|
212
|
-
_bounded_set(_ACTIVE_SKILLS, key, candidate)
|
|
213
|
-
return True
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
def clear_active_skill(session_id: object) -> None:
|
|
217
|
-
"""End the previous root turn without discarding a pending finding receipt."""
|
|
218
|
-
_ACTIVE_SKILLS.pop(str(session_id or ""), None)
|
|
219
|
-
|
|
220
|
-
|
|
221
84
|
def begin_root_turn(session_id: object, turn_id: object) -> None:
|
|
222
|
-
"""Rebind guard state only at a host-authored root-turn boundary.
|
|
223
|
-
|
|
224
|
-
Current Hermes passes a fresh ``turn_id`` into ``pre_llm_call`` once per
|
|
225
|
-
root turn. Repeated callbacks carrying that same identity belong to the
|
|
226
|
-
assistant/tool loop and must keep the active skill after an advisory is
|
|
227
|
-
consumed. Missing identities are not promoted into boundaries from raw user
|
|
228
|
-
text; session lifecycle hooks remain the fallback reset surface.
|
|
229
|
-
"""
|
|
230
85
|
key = str(session_id or "")
|
|
231
86
|
identity = turn_id if isinstance(turn_id, str) else ""
|
|
232
87
|
if not key or not identity or len(identity.encode("utf-8")) > 512:
|
|
233
88
|
return
|
|
234
89
|
if _ROOT_TURNS.get(key) != identity:
|
|
235
|
-
|
|
90
|
+
_USER_QUOTES.pop(key, None)
|
|
236
91
|
_bounded_set(_ROOT_TURNS, key, identity)
|
|
237
92
|
|
|
238
93
|
|
|
239
|
-
def
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
def _designated_section_lines(lines: list[str]) -> set[int]:
|
|
284
|
-
heading = re.compile(r"^\s*(#{1,6})\s+.*(?:limitations?|한계|제한)", re.IGNORECASE)
|
|
285
|
-
allowed: set[int] = set()
|
|
286
|
-
active_level: int | None = None
|
|
287
|
-
for index, line in enumerate(lines):
|
|
288
|
-
matched = heading.match(line)
|
|
289
|
-
if matched:
|
|
290
|
-
active_level = len(matched.group(1))
|
|
291
|
-
allowed.add(index)
|
|
292
|
-
continue
|
|
293
|
-
next_heading = re.match(r"^\s*(#{1,6})\s+", line)
|
|
294
|
-
if active_level is not None and next_heading and len(next_heading.group(1)) <= active_level:
|
|
295
|
-
active_level = None
|
|
296
|
-
if active_level is not None:
|
|
297
|
-
allowed.add(index)
|
|
298
|
-
return allowed
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
def scan_text(text: str, contract: OutputChannel) -> list[Finding]:
|
|
302
|
-
if contract.artifact_genre in {"working_note", "no_artifact"}:
|
|
303
|
-
return []
|
|
304
|
-
lines = str(text or "").splitlines()
|
|
305
|
-
allowed = (
|
|
306
|
-
_methodology_lines(lines)
|
|
307
|
-
if contract.artifact_genre == "audit_report"
|
|
308
|
-
else _designated_section_lines(lines)
|
|
309
|
-
if contract.artifact_genre == "internal_analysis"
|
|
310
|
-
else set()
|
|
311
|
-
)
|
|
312
|
-
findings: list[Finding] = []
|
|
313
|
-
fence: str | None = None
|
|
314
|
-
for index, line in enumerate(lines):
|
|
315
|
-
fence_match = _FENCE.match(line)
|
|
316
|
-
if fence_match:
|
|
317
|
-
marker = fence_match.group(1)[0]
|
|
318
|
-
fence = None if fence == marker else marker if fence is None else fence
|
|
319
|
-
continue
|
|
320
|
-
if fence is not None or index in allowed:
|
|
321
|
-
continue
|
|
322
|
-
scalar = bool(_YAML_OR_JSON_SCALAR.fullmatch(line))
|
|
323
|
-
table = _status_table_line(line)
|
|
324
|
-
for pattern_class, pattern in _PATTERNS:
|
|
325
|
-
match = pattern.search(line)
|
|
326
|
-
if match is None:
|
|
327
|
-
continue
|
|
328
|
-
if pattern_class == "deferred" and (
|
|
329
|
-
scalar or table or _quoted_status_contains(line, match.start(), match.end())
|
|
330
|
-
):
|
|
331
|
-
continue
|
|
332
|
-
findings.append(Finding(pattern_class, index + 1))
|
|
333
|
-
break
|
|
334
|
-
return findings
|
|
94
|
+
def capture_user_text(session_id: object, user_message: object, turn_id: object = None) -> None:
|
|
95
|
+
"""Keep only bounded exact quote spans, never the full user message."""
|
|
96
|
+
key = str(session_id or "")
|
|
97
|
+
message = user_message if isinstance(user_message, str) else ""
|
|
98
|
+
if not key or not message:
|
|
99
|
+
return
|
|
100
|
+
identity = turn_id if isinstance(turn_id, str) else _ROOT_TURNS.get(key, "")
|
|
101
|
+
if identity and _ROOT_TURNS.get(key) not in (None, identity):
|
|
102
|
+
_USER_QUOTES.pop(key, None)
|
|
103
|
+
quotes: list[str] = []
|
|
104
|
+
used = 0
|
|
105
|
+
for line in message.splitlines():
|
|
106
|
+
stripped = line.lstrip()
|
|
107
|
+
if stripped.startswith("> ") and len(stripped) > 2:
|
|
108
|
+
quote = stripped[2:].strip()
|
|
109
|
+
if quote:
|
|
110
|
+
quotes.append(quote[:2000])
|
|
111
|
+
for match in _QUOTED_SPAN.finditer(message[:16_384]):
|
|
112
|
+
quote = next((group for group in match.groups() if group), "")
|
|
113
|
+
if quote:
|
|
114
|
+
quotes.append(quote[:2000])
|
|
115
|
+
bounded: list[str] = []
|
|
116
|
+
for quote in quotes:
|
|
117
|
+
quote = quote.strip()
|
|
118
|
+
if quote and quote not in bounded and len(bounded) < 16 and used + len(quote) <= 8000:
|
|
119
|
+
bounded.append(quote)
|
|
120
|
+
used += len(quote)
|
|
121
|
+
_bounded_set(_USER_QUOTES, key, tuple(bounded))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _mask_exact_user_quotes(text: str, session_id: str) -> str:
|
|
125
|
+
masked = text
|
|
126
|
+
for quote in _USER_QUOTES.get(session_id, ()):
|
|
127
|
+
masked = masked.replace(quote, "".join("\n" if char == "\n" else " " for char in quote))
|
|
128
|
+
return masked
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def activate_skill(session_id: object, route_or_skill: object) -> bool:
|
|
132
|
+
"""Compatibility no-op: reader-facing checks do not depend on skill genre."""
|
|
133
|
+
return bool(str(session_id or ""))
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def clear_active_skill(session_id: object) -> None:
|
|
137
|
+
"""Compatibility no-op; guards are always active for supported paths."""
|
|
335
138
|
|
|
336
139
|
|
|
337
140
|
def _directory_flags() -> int | None:
|
|
@@ -354,16 +157,17 @@ def _relative_artifact_path(path_text: str, workspace: Path) -> Path | None:
|
|
|
354
157
|
not relative.parts
|
|
355
158
|
or any(part in {"", ".", ".."} for part in relative.parts)
|
|
356
159
|
or relative.suffix.lower() not in READER_FACING_SUFFIXES
|
|
160
|
+
or _INTERNAL_FILE.search(relative.as_posix())
|
|
357
161
|
):
|
|
358
162
|
return None
|
|
359
163
|
return relative
|
|
360
164
|
|
|
361
165
|
|
|
362
|
-
def
|
|
166
|
+
def _read_stable_file_result(
|
|
363
167
|
path_text: str,
|
|
364
168
|
workspace: Path,
|
|
365
169
|
byte_limit: int,
|
|
366
|
-
) ->
|
|
170
|
+
) -> _StableFile | _ReadBudgetExceeded | None:
|
|
367
171
|
relative = _relative_artifact_path(path_text, workspace)
|
|
368
172
|
directory_flags = _directory_flags()
|
|
369
173
|
if relative is None or directory_flags is None or byte_limit < 0:
|
|
@@ -411,10 +215,7 @@ def _read_stable_text_file_result(
|
|
|
411
215
|
return None
|
|
412
216
|
if initial.st_size > read_limit:
|
|
413
217
|
return _READ_BUDGET_EXCEEDED
|
|
414
|
-
edges.append(
|
|
415
|
-
(parent_fd, relative.parts[-1], (initial.st_dev, initial.st_ino), False)
|
|
416
|
-
)
|
|
417
|
-
|
|
218
|
+
edges.append((parent_fd, relative.parts[-1], (initial.st_dev, initial.st_ino), False))
|
|
418
219
|
chunks: list[bytes] = []
|
|
419
220
|
total = 0
|
|
420
221
|
while total <= read_limit:
|
|
@@ -423,10 +224,9 @@ def _read_stable_text_file_result(
|
|
|
423
224
|
break
|
|
424
225
|
chunks.append(chunk)
|
|
425
226
|
total += len(chunk)
|
|
426
|
-
|
|
427
|
-
if len(
|
|
227
|
+
data = b"".join(chunks)
|
|
228
|
+
if len(data) > read_limit:
|
|
428
229
|
return _READ_BUDGET_EXCEEDED
|
|
429
|
-
|
|
430
230
|
final = os.fstat(artifact_fd)
|
|
431
231
|
if (
|
|
432
232
|
not stat.S_ISREG(final.st_mode)
|
|
@@ -434,20 +234,16 @@ def _read_stable_text_file_result(
|
|
|
434
234
|
or final.st_size != initial.st_size
|
|
435
235
|
or final.st_mtime_ns != initial.st_mtime_ns
|
|
436
236
|
or final.st_ctime_ns != initial.st_ctime_ns
|
|
437
|
-
or len(
|
|
237
|
+
or len(data) != initial.st_size
|
|
438
238
|
):
|
|
439
239
|
return None
|
|
440
240
|
for parent_fd, name, identity, is_directory in edges:
|
|
441
241
|
current = os.stat(name, dir_fd=parent_fd, follow_symlinks=False)
|
|
442
|
-
correct_type = (
|
|
443
|
-
stat.S_ISDIR(current.st_mode)
|
|
444
|
-
if is_directory
|
|
445
|
-
else stat.S_ISREG(current.st_mode)
|
|
446
|
-
)
|
|
242
|
+
correct_type = stat.S_ISDIR(current.st_mode) if is_directory else stat.S_ISREG(current.st_mode)
|
|
447
243
|
if (current.st_dev, current.st_ino) != identity or not correct_type:
|
|
448
244
|
return None
|
|
449
|
-
return
|
|
450
|
-
except (OSError,
|
|
245
|
+
return _StableFile(data, len(data))
|
|
246
|
+
except (OSError, ValueError):
|
|
451
247
|
return None
|
|
452
248
|
finally:
|
|
453
249
|
if artifact_fd >= 0:
|
|
@@ -462,9 +258,25 @@ def _read_stable_text_file_result(
|
|
|
462
258
|
pass
|
|
463
259
|
|
|
464
260
|
|
|
261
|
+
def _read_stable_text_file_result(
|
|
262
|
+
path_text: str,
|
|
263
|
+
workspace: Path,
|
|
264
|
+
byte_limit: int,
|
|
265
|
+
) -> _StableFile | _ReadBudgetExceeded | None:
|
|
266
|
+
result = _read_stable_file_result(path_text, workspace, byte_limit)
|
|
267
|
+
if isinstance(result, _StableFile) and Path(path_text).suffix.lower() not in TEXT_SUFFIXES:
|
|
268
|
+
return None
|
|
269
|
+
return result
|
|
270
|
+
|
|
271
|
+
|
|
465
272
|
def _read_stable_text_file(path_text: str, workspace: Path) -> str | None:
|
|
466
273
|
result = _read_stable_text_file_result(path_text, workspace, MAX_FILE_BYTES)
|
|
467
|
-
|
|
274
|
+
if not isinstance(result, _StableFile):
|
|
275
|
+
return None
|
|
276
|
+
try:
|
|
277
|
+
return result.data.decode("utf-8")
|
|
278
|
+
except UnicodeError:
|
|
279
|
+
return None
|
|
468
280
|
|
|
469
281
|
|
|
470
282
|
def _bounded_artifact_paths(paths: Iterable[object]) -> list[object] | None:
|
|
@@ -482,81 +294,290 @@ def _bounded_artifact_paths(paths: Iterable[object]) -> list[object] | None:
|
|
|
482
294
|
return bounded
|
|
483
295
|
|
|
484
296
|
|
|
297
|
+
def _queue_advisory(session_id: str, message: str) -> None:
|
|
298
|
+
if not session_id:
|
|
299
|
+
return
|
|
300
|
+
pending = list(_PENDING_ADVISORIES.get(session_id, ()))
|
|
301
|
+
if message not in pending:
|
|
302
|
+
pending.append(message)
|
|
303
|
+
_bounded_set(_PENDING_ADVISORIES, session_id, pending[-8:])
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def consume_context(session_id: object) -> str:
|
|
307
|
+
key = str(session_id or "")
|
|
308
|
+
messages = _PENDING_ADVISORIES.pop(key, ())
|
|
309
|
+
return "\n".join(messages)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def _path_is_reader_copy(path_text: str, workspace: Path) -> bool:
|
|
313
|
+
return _relative_artifact_path(path_text, workspace) is not None
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _changed_lines(previous: str, proposed: str) -> set[int]:
|
|
317
|
+
old_lines = previous.splitlines(keepends=True)
|
|
318
|
+
new_lines = proposed.splitlines(keepends=True)
|
|
319
|
+
changed: set[int] = set()
|
|
320
|
+
for tag, _old_start, _old_end, new_start, new_end in difflib.SequenceMatcher(
|
|
321
|
+
None, old_lines, new_lines, autojunk=True
|
|
322
|
+
).get_opcodes():
|
|
323
|
+
if tag in {"replace", "insert"}:
|
|
324
|
+
changed.update(range(new_start + 1, new_end + 1))
|
|
325
|
+
return changed
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def _run_detector(text: str, path_text: str) -> list[dict] | None:
|
|
329
|
+
encoded = text.encode("utf-8")
|
|
330
|
+
if len(encoded) > MAX_DETECT_BYTES:
|
|
331
|
+
return None
|
|
332
|
+
payload = json.dumps({"text": text, "file": path_text}, ensure_ascii=False).encode("utf-8")
|
|
333
|
+
if len(payload) > MAX_DETECT_BYTES + 16_384:
|
|
334
|
+
return None
|
|
335
|
+
try:
|
|
336
|
+
result = subprocess.run(
|
|
337
|
+
[sys.executable, "-B", "-I", str(DETECTOR), "--stdin-json"],
|
|
338
|
+
input=payload,
|
|
339
|
+
capture_output=True,
|
|
340
|
+
timeout=DETECT_TIMEOUT_SECONDS,
|
|
341
|
+
check=False,
|
|
342
|
+
)
|
|
343
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
344
|
+
return None
|
|
345
|
+
if result.returncode != 0 or len(result.stdout) > MAX_DETECT_OUTPUT:
|
|
346
|
+
return None
|
|
347
|
+
try:
|
|
348
|
+
findings = json.loads(result.stdout.decode("utf-8"))
|
|
349
|
+
except (UnicodeError, json.JSONDecodeError):
|
|
350
|
+
return None
|
|
351
|
+
if not isinstance(findings, list) or len(findings) > 4096:
|
|
352
|
+
return None
|
|
353
|
+
for finding in findings:
|
|
354
|
+
if (
|
|
355
|
+
not isinstance(finding, dict)
|
|
356
|
+
or not _RULE_ID.fullmatch(str(finding.get("rule") or ""))
|
|
357
|
+
or finding.get("severity") not in {"block", "warn"}
|
|
358
|
+
or not isinstance(finding.get("line"), int)
|
|
359
|
+
or not isinstance(finding.get("line_end"), int)
|
|
360
|
+
or finding["line"] < 1
|
|
361
|
+
or finding["line_end"] < finding["line"]
|
|
362
|
+
or not isinstance(finding.get("match"), str)
|
|
363
|
+
):
|
|
364
|
+
return None
|
|
365
|
+
return findings
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def _changed_findings(text: str, path_text: str, changed: set[int], session_id: str) -> list[dict] | None:
|
|
369
|
+
findings = _run_detector(_mask_exact_user_quotes(text, session_id), path_text)
|
|
370
|
+
if findings is None:
|
|
371
|
+
return None
|
|
372
|
+
return [
|
|
373
|
+
finding
|
|
374
|
+
for finding in findings
|
|
375
|
+
if any(finding["line"] <= line <= finding["line_end"] for line in changed)
|
|
376
|
+
]
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def _block_message(findings: list[dict]) -> dict[str, str] | None:
|
|
380
|
+
blocks = [finding for finding in findings if finding["severity"] == "block"]
|
|
381
|
+
if not blocks:
|
|
382
|
+
return None
|
|
383
|
+
refs = ", ".join(f"{item['rule']}:{item['line']}" for item in blocks[:5])
|
|
384
|
+
extra = f" (+{len(blocks) - 5})" if len(blocks) > 5 else ""
|
|
385
|
+
return {
|
|
386
|
+
"action": "block",
|
|
387
|
+
"message": f"LitHumanizer blocked {len(blocks)} block-tier finding(s) in added prose ({refs}{extra}). Revise the added wording; warnings remain contextual review signals.",
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def _warn_if_needed(session_id: str, findings: list[dict]) -> None:
|
|
392
|
+
warnings = [finding for finding in findings if finding["severity"] == "warn"]
|
|
393
|
+
if warnings:
|
|
394
|
+
refs = ", ".join(f"{item['rule']}:{item['line']}" for item in warnings[:5])
|
|
395
|
+
_queue_advisory(session_id, f"LitHumanizer warning-tier review signal(s) in added prose: {refs}. Consider them in context; they are not a ban or authorship judgment.")
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def _fail_open(session_id: str) -> None:
|
|
399
|
+
_queue_advisory(session_id, "LitHumanizer check unavailable; the write was allowed. Run the detector manually before delivery.")
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def _read_previous(path_text: str, workspace: Path) -> str | None:
|
|
403
|
+
result = _read_stable_text_file_result(path_text, workspace, MAX_FILE_BYTES)
|
|
404
|
+
if isinstance(result, _StableFile):
|
|
405
|
+
try:
|
|
406
|
+
return result.data.decode("utf-8")
|
|
407
|
+
except UnicodeError:
|
|
408
|
+
return None
|
|
409
|
+
target = Path(path_text).expanduser()
|
|
410
|
+
target = target if target.is_absolute() else workspace / target
|
|
411
|
+
if result is None and not target.exists() and not target.is_symlink():
|
|
412
|
+
return ""
|
|
413
|
+
return None
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def _check_text_change(session_id: str, path_text: str, proposed: str, workspace: Path) -> dict[str, str] | None:
|
|
417
|
+
if not _path_is_reader_copy(path_text, workspace):
|
|
418
|
+
return None
|
|
419
|
+
if len(proposed.encode("utf-8")) > MAX_DETECT_BYTES:
|
|
420
|
+
_fail_open(session_id)
|
|
421
|
+
return None
|
|
422
|
+
previous = _read_previous(path_text, workspace)
|
|
423
|
+
if previous is None:
|
|
424
|
+
_fail_open(session_id)
|
|
425
|
+
return None
|
|
426
|
+
if len(previous.encode("utf-8")) > MAX_DETECT_BYTES:
|
|
427
|
+
_fail_open(session_id)
|
|
428
|
+
return None
|
|
429
|
+
changed = _changed_lines(previous, proposed)
|
|
430
|
+
if not changed:
|
|
431
|
+
return None
|
|
432
|
+
findings = _changed_findings(proposed, path_text, changed, session_id)
|
|
433
|
+
if findings is None:
|
|
434
|
+
_fail_open(session_id)
|
|
435
|
+
return None
|
|
436
|
+
_warn_if_needed(session_id, findings)
|
|
437
|
+
return _block_message(findings)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def _patch_added_chunks(patch_text: str) -> list[tuple[str, str]]:
|
|
441
|
+
chunks: list[tuple[str, str]] = []
|
|
442
|
+
path = ""
|
|
443
|
+
kind = ""
|
|
444
|
+
added: list[str] = []
|
|
445
|
+
|
|
446
|
+
def flush() -> None:
|
|
447
|
+
nonlocal added
|
|
448
|
+
if path and kind in {"Add", "Update"} and added:
|
|
449
|
+
chunks.append((path, "\n".join(added)))
|
|
450
|
+
added = []
|
|
451
|
+
|
|
452
|
+
for line in patch_text.splitlines():
|
|
453
|
+
header = _V4A_FILE.match(line)
|
|
454
|
+
if header:
|
|
455
|
+
flush()
|
|
456
|
+
kind, path = header.group(1), header.group(2).strip()
|
|
457
|
+
elif _V4A_MOVE.match(line):
|
|
458
|
+
flush()
|
|
459
|
+
elif line.startswith("+++") or line.startswith("---"):
|
|
460
|
+
flush()
|
|
461
|
+
elif line.startswith("+"):
|
|
462
|
+
added.append(line[1:])
|
|
463
|
+
else:
|
|
464
|
+
flush()
|
|
465
|
+
flush()
|
|
466
|
+
return chunks
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def pre_tool_call(
|
|
470
|
+
tool_name: object,
|
|
471
|
+
args: object,
|
|
472
|
+
session_id: object,
|
|
473
|
+
*,
|
|
474
|
+
workspace: object = None,
|
|
475
|
+
) -> dict[str, str] | None:
|
|
476
|
+
"""Block block-tier findings before Hermes persists a supported text edit."""
|
|
477
|
+
name = str(tool_name or "")
|
|
478
|
+
payload = args if isinstance(args, dict) else {}
|
|
479
|
+
key = str(session_id or "")
|
|
480
|
+
if not key or name not in {"write_file", "patch"}:
|
|
481
|
+
return None
|
|
482
|
+
try:
|
|
483
|
+
root = Path(workspace or Path.cwd()).expanduser().resolve(strict=True)
|
|
484
|
+
except (OSError, RuntimeError):
|
|
485
|
+
_fail_open(key)
|
|
486
|
+
return None
|
|
487
|
+
if name == "write_file":
|
|
488
|
+
path_text = str(payload.get("path") or "")
|
|
489
|
+
content = payload.get("content")
|
|
490
|
+
if isinstance(content, str):
|
|
491
|
+
return _check_text_change(key, path_text, content, root)
|
|
492
|
+
return None
|
|
493
|
+
mode = str(payload.get("mode") or "replace").lower()
|
|
494
|
+
if mode == "replace":
|
|
495
|
+
path_text = str(payload.get("path") or "")
|
|
496
|
+
old_string = payload.get("old_string")
|
|
497
|
+
new_string = payload.get("new_string")
|
|
498
|
+
if not isinstance(old_string, str) or not isinstance(new_string, str):
|
|
499
|
+
return None
|
|
500
|
+
previous = _read_previous(path_text, root)
|
|
501
|
+
if previous is None or old_string not in previous:
|
|
502
|
+
_fail_open(key)
|
|
503
|
+
return None
|
|
504
|
+
proposed = previous.replace(old_string, new_string) if payload.get("replace_all") else previous.replace(old_string, new_string, 1)
|
|
505
|
+
return _check_text_change(key, path_text, proposed, root)
|
|
506
|
+
if mode == "patch" and isinstance(payload.get("patch"), str):
|
|
507
|
+
for path_text, added_text in _patch_added_chunks(payload["patch"]):
|
|
508
|
+
if not _path_is_reader_copy(path_text, root):
|
|
509
|
+
continue
|
|
510
|
+
findings = _changed_findings(added_text, path_text, set(range(1, len(added_text.splitlines()) + 1)), key)
|
|
511
|
+
if findings is None:
|
|
512
|
+
_fail_open(key)
|
|
513
|
+
continue
|
|
514
|
+
_warn_if_needed(key, findings)
|
|
515
|
+
denial = _block_message(findings)
|
|
516
|
+
if denial:
|
|
517
|
+
return denial
|
|
518
|
+
return None
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def _extract_office(data: bytes, suffix: str) -> str:
|
|
522
|
+
try:
|
|
523
|
+
import humanizer_office
|
|
524
|
+
except ImportError:
|
|
525
|
+
from . import humanizer_office
|
|
526
|
+
if suffix == ".pdf":
|
|
527
|
+
return humanizer_office.extract_pdf_bytes(data)
|
|
528
|
+
return humanizer_office.extract_office_bytes(data, suffix)
|
|
529
|
+
|
|
530
|
+
|
|
485
531
|
def observe_completed_paths(
|
|
486
532
|
session_id: object,
|
|
487
533
|
paths: Iterable[object],
|
|
488
534
|
*,
|
|
489
535
|
workspace: object = None,
|
|
490
536
|
) -> None:
|
|
537
|
+
"""Advise after supported Office/PDF exports; this observer cannot deny."""
|
|
491
538
|
key = str(session_id or "")
|
|
492
|
-
|
|
493
|
-
if not key or not skill_id:
|
|
494
|
-
return
|
|
495
|
-
try:
|
|
496
|
-
contract = load_output_channel(skill_id)
|
|
497
|
-
except (OSError, UnicodeError, ValueError):
|
|
498
|
-
return
|
|
499
|
-
if contract.artifact_genre in {"working_note", "no_artifact"}:
|
|
539
|
+
if not key:
|
|
500
540
|
return
|
|
501
|
-
|
|
502
|
-
if
|
|
541
|
+
bounded = _bounded_artifact_paths(paths)
|
|
542
|
+
if bounded is None:
|
|
543
|
+
_fail_open(key)
|
|
503
544
|
return
|
|
504
545
|
try:
|
|
505
546
|
root = Path(workspace or Path.cwd()).expanduser().resolve(strict=True)
|
|
506
547
|
except (OSError, RuntimeError):
|
|
548
|
+
_fail_open(key)
|
|
507
549
|
return
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
for raw_path in
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
)
|
|
550
|
+
candidates: list[tuple[str, bytes]] = []
|
|
551
|
+
remaining = MAX_AGGREGATE_FILE_BYTES
|
|
552
|
+
for raw_path in bounded:
|
|
553
|
+
path_text = str(raw_path or "")
|
|
554
|
+
relative = _relative_artifact_path(path_text, root)
|
|
555
|
+
if relative is None or relative.suffix.lower() not in OFFICE_SUFFIXES:
|
|
556
|
+
continue
|
|
557
|
+
result = _read_stable_file_result(path_text, root, remaining)
|
|
516
558
|
if result is _READ_BUDGET_EXCEEDED:
|
|
559
|
+
_fail_open(key)
|
|
517
560
|
return
|
|
518
|
-
if not isinstance(result,
|
|
561
|
+
if not isinstance(result, _StableFile):
|
|
562
|
+
_fail_open(key)
|
|
563
|
+
continue
|
|
564
|
+
candidates.append((relative.suffix.lower(), result.data))
|
|
565
|
+
remaining -= result.byte_count
|
|
566
|
+
for suffix, data in candidates:
|
|
567
|
+
try:
|
|
568
|
+
text = _extract_office(data, suffix)
|
|
569
|
+
except (OSError, RuntimeError, ValueError, subprocess.TimeoutExpired, ImportError):
|
|
570
|
+
_fail_open(key)
|
|
571
|
+
continue
|
|
572
|
+
findings = _run_detector(text, "post-write" + suffix)
|
|
573
|
+
if findings is None:
|
|
574
|
+
_fail_open(key)
|
|
519
575
|
continue
|
|
520
|
-
buffered_text.append(result.text)
|
|
521
|
-
remaining_bytes -= result.byte_count
|
|
522
|
-
|
|
523
|
-
all_findings: list[Finding] = []
|
|
524
|
-
file_count = 0
|
|
525
|
-
for text in buffered_text:
|
|
526
|
-
findings = scan_text(text, contract)
|
|
527
576
|
if findings:
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
finding_count=min(len(all_findings), MAX_CONTEXT_FINDINGS),
|
|
536
|
-
line_numbers=tuple(sorted({finding.line_number for finding in all_findings}))[
|
|
537
|
-
:MAX_CONTEXT_FINDINGS
|
|
538
|
-
],
|
|
539
|
-
file_count=file_count,
|
|
540
|
-
)
|
|
541
|
-
pending = list(_PENDING_RECEIPTS.get(key, ()))
|
|
542
|
-
pending.append(receipt)
|
|
543
|
-
_bounded_set(_PENDING_RECEIPTS, key, pending[-8:])
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
def consume_context(session_id: object) -> str:
|
|
547
|
-
key = str(session_id or "")
|
|
548
|
-
receipts = _PENDING_RECEIPTS.pop(key, None)
|
|
549
|
-
if not receipts:
|
|
550
|
-
return ""
|
|
551
|
-
lines = ['<lithermes-deliverable-hedge-guard event="completed-write">']
|
|
552
|
-
for receipt in receipts:
|
|
553
|
-
line_numbers = ",".join(str(number) for number in receipt.line_numbers)
|
|
554
|
-
lines.append(
|
|
555
|
-
"DELIVERABLE_HEDGE_VIOLATION "
|
|
556
|
-
f"skill={receipt.skill_id} genre={receipt.contract.artifact_genre} "
|
|
557
|
-
f"findings={receipt.finding_count} lines={line_numbers} files={receipt.file_count}. "
|
|
558
|
-
f"Revise the artifact and place limitations in {receipt.contract.limitations_channel}."
|
|
559
|
-
)
|
|
560
|
-
lines.append("Artifact text and paths were omitted because they are untrusted data.")
|
|
561
|
-
lines.append("</lithermes-deliverable-hedge-guard>")
|
|
562
|
-
return "\n".join(lines)
|
|
577
|
+
blocks = sum(item["severity"] == "block" for item in findings)
|
|
578
|
+
warnings = sum(item["severity"] == "warn" for item in findings)
|
|
579
|
+
_queue_advisory(
|
|
580
|
+
key,
|
|
581
|
+
"LIT_HUMANIZER_POSTWRITE_ADVISORY: the completed Office/PDF export has "
|
|
582
|
+
f"{blocks} block-tier and {warnings} warning-tier finding(s). Edit the source and rebuild; Hermes cannot undo a completed export.",
|
|
583
|
+
)
|