shipwright-kit 0.11.0__tar.gz → 0.12.0__tar.gz
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.
- {shipwright_kit-0.11.0/shipwright_kit.egg-info → shipwright_kit-0.12.0}/PKG-INFO +1 -1
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/pyproject.toml +1 -1
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/__init__.py +1 -1
- shipwright_kit-0.12.0/shipwright_kit/security/render.py +62 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0/shipwright_kit.egg-info}/PKG-INFO +1 -1
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit.egg-info/SOURCES.txt +1 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/LICENSE +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/README.md +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/setup.cfg +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/cli.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/config.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/__init__.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/banner.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/console.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/glyphs.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/output.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/palette.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/design/tiers.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/eval/__init__.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/eval/corpus.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/eval/harness.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/eval/metrics.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/llm.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/py.typed +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/security/__init__.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/security/eval.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/security/injection.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/security/ssrf.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit/security/theme.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit.egg-info/dependency_links.txt +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit.egg-info/entry_points.txt +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit.egg-info/requires.txt +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit.egg-info/top_level.txt +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_cli.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_config.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_llm.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_packaging.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_packs_entrypoint.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_release_config.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_template_wiring.py +0 -0
- {shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/tests/test_tooling.py +0 -0
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
|
7
7
|
# PyPI distribution name. The bare `shipwright` is taken on PyPI (unrelated 6si
|
|
8
8
|
# tool), so the dist is `shipwright-kit`; the IMPORT name is `shipwright_kit`.
|
|
9
9
|
name = "shipwright-kit"
|
|
10
|
-
version = "0.
|
|
10
|
+
version = "0.12.0"
|
|
11
11
|
description = "Shipwright — AI-agent dev framework + import-light design/eval/security library"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.11"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Terminal-safe rendering of untrusted (LLM-sourced) text.
|
|
2
|
+
|
|
3
|
+
Neutralizes the two ways attacker-influenced text — chiefly an LLM summary or
|
|
4
|
+
explanation a model can be steered to emit — manipulates a Rich-rendered
|
|
5
|
+
terminal when a consumer (vex, sift, barb) prints it:
|
|
6
|
+
|
|
7
|
+
* Rich console markup (``[red]``, ``[link=...]``) — escaped so it renders as
|
|
8
|
+
literal text, following Rich's own ``\\[`` escape convention.
|
|
9
|
+
* ANSI / OSC escape sequences and other C0/C1 control characters — stripped, so
|
|
10
|
+
a model cannot move the cursor, recolor, set the window title, or emit OSC-8
|
|
11
|
+
hyperlinks. TAB (``\\t``) and newline (``\\n``) are preserved.
|
|
12
|
+
|
|
13
|
+
Render-sink half of the fleet's LLM-output hardening (OWASP LLM05, Improper
|
|
14
|
+
Output Handling); the prompt-input half lives in
|
|
15
|
+
:mod:`shipwright_kit.security.injection`. Apply ``safe_render`` to the
|
|
16
|
+
LLM-sourced field ONLY — trusted app-generated markup (e.g. a severity-color
|
|
17
|
+
span) must never be routed through it.
|
|
18
|
+
|
|
19
|
+
Import-light: stdlib only (``re``), no Rich import — mirrors the import-light
|
|
20
|
+
invariant of :mod:`shipwright_kit.security.injection`.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import re
|
|
26
|
+
|
|
27
|
+
__all__ = ["SAFE_RENDER_VERSION", "safe_render"]
|
|
28
|
+
|
|
29
|
+
# Bump when the neutralization rule set changes (added/removed/retuned rule).
|
|
30
|
+
SAFE_RENDER_VERSION = 1
|
|
31
|
+
|
|
32
|
+
# CSI (ESC [ ... final byte), OSC (ESC ] ... BEL | ESC \), and other two-char
|
|
33
|
+
# ESC sequences.
|
|
34
|
+
_ANSI_RE = re.compile(
|
|
35
|
+
r"\x1b\[[0-?]*[ -/]*[@-~]" # CSI
|
|
36
|
+
r"|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)" # OSC (terminated by BEL or ST)
|
|
37
|
+
r"|\x1b[@-Z\\-_]" # other two-char ESC sequences
|
|
38
|
+
)
|
|
39
|
+
# C0/C1 control chars except TAB (\x09) and LF (\x0a).
|
|
40
|
+
_CTRL_RE = re.compile(r"[\x00-\x08\x0b-\x1f\x7f-\x9f]")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def safe_render(text: str, *, escape_markup: bool = True) -> str:
|
|
44
|
+
"""Return ``text`` safe to print at a terminal render sink.
|
|
45
|
+
|
|
46
|
+
Always removes ANSI/OSC escape sequences and other control characters (TAB
|
|
47
|
+
and newline kept). When ``escape_markup`` is True (default), ALSO escapes
|
|
48
|
+
Rich console markup so ``[red]`` shows literally — for text printed into a
|
|
49
|
+
Rich-markup-enabled sink (``console.print`` / ``Panel``). Set
|
|
50
|
+
``escape_markup=False`` for a plain builtin-``print`` sink, where there is no
|
|
51
|
+
Rich to interpret markup and escaping ``[`` would only add spurious
|
|
52
|
+
backslashes (the control/ANSI strip still applies). Use on LLM-sourced /
|
|
53
|
+
attacker-influenceable text at the render site.
|
|
54
|
+
"""
|
|
55
|
+
text = _ANSI_RE.sub("", text)
|
|
56
|
+
text = _CTRL_RE.sub("", text)
|
|
57
|
+
if escape_markup:
|
|
58
|
+
# Escape Rich markup. Double backslashes first so an attacker-supplied
|
|
59
|
+
# backslash cannot combine with the one we insert (Rich collapses \\ ->
|
|
60
|
+
# \ and only parses the opening '['), then escape '['.
|
|
61
|
+
text = text.replace("\\", "\\\\").replace("[", "\\[")
|
|
62
|
+
return text
|
|
@@ -26,6 +26,7 @@ shipwright_kit/eval/metrics.py
|
|
|
26
26
|
shipwright_kit/security/__init__.py
|
|
27
27
|
shipwright_kit/security/eval.py
|
|
28
28
|
shipwright_kit/security/injection.py
|
|
29
|
+
shipwright_kit/security/render.py
|
|
29
30
|
shipwright_kit/security/ssrf.py
|
|
30
31
|
shipwright_kit/security/theme.py
|
|
31
32
|
tests/test_cli.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shipwright_kit-0.11.0 → shipwright_kit-0.12.0}/shipwright_kit.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|