claude-dev-env 8.70.0 → 8.71.1
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/docs/rule-guides/question-presentation.md +11 -0
- package/docs/templates/html-plan/README.md +36 -0
- package/docs/templates/html-plan/house.css +26 -0
- package/hooks/features/session-context.md +2 -2
- package/hooks/hooks_constants/artifact_template_pointer_constants.py +9 -3
- package/hooks/hooks_constants/test_artifact_template_pointer_constants.py +9 -1
- package/hooks/session/artifact_template_pointer.py +10 -4
- package/hooks/session/test_artifact_template_pointer.py +8 -2
- package/package.json +1 -1
- package/rules/question-presentation.md +4 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Present questions clearly
|
|
2
|
+
|
|
3
|
+
Full text behind [`rules/question-presentation.md`](../../rules/question-presentation.md).
|
|
4
|
+
|
|
5
|
+
## Codex visual comparisons
|
|
6
|
+
|
|
7
|
+
For Codex visual comparisons, find Page creation, visualization upload, and Page opening tools. Create the comparison, upload its visualization, and open its Page here before asking. If tools are missing, steps fail, or opening queues, compare in chat before asking. Put inline Visualize references only in final replies. An async acknowledgement or saved visual is context only; wait for and use the submitted answer before dependent work.
|
|
8
|
+
|
|
9
|
+
## Option cards
|
|
10
|
+
|
|
11
|
+
When the user asks for option cards, build an Artifact page with the `html-plan:html-plan` skill and follow `~/.claude/docs/templates/html-plan/README.md`. Load the `artifact-capabilities` skill and declare the capability that saves the answer where you can read it. A tap selects a card, a second tap clears it, a picked card shows "Change it" with a notes field, and only Send delivers. After publishing, read the saved answer back before dependent work. If no capability can return the answer, use the native question tool with the same labels.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# html-plan page template
|
|
2
|
+
|
|
3
|
+
Build a new artifact page from the html-plan skill. Load `house.css` from this folder after the plugin's `htmlplan.css`. The older [artifact page template](../artifact-page/README.md) stays available; use it when the request names it.
|
|
4
|
+
|
|
5
|
+
## Get the skill
|
|
6
|
+
|
|
7
|
+
The html-plan plugin is the upstream source, and it stays read-only. Keep every local change in this folder.
|
|
8
|
+
|
|
9
|
+
1. When the plugin is installed, run `/html-plan` or load the `html-plan` skill.
|
|
10
|
+
2. When it is not installed, clone the source read-only and read the skill from it:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
git clone --depth 1 https://github.com/anthropics/claude-plugins-community <scratch folder>
|
|
14
|
+
git -C <scratch folder> checkout f60f0454df3045f724c43c6346ec80bdcc3472b2
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Read `html-plan/skills/html-plan/SKILL.md`, then `references/blocks.md` and `examples/scheduled-send.html` beside it. Link `runtime/htmlplan.css` and `runtime/htmlplan.js` from the page, and run `runtime/pack.mjs` to inline them.
|
|
18
|
+
3. To install the plugin, run `claude plugin install html-plan@claude-community`. The person who owns the environment approves this step.
|
|
19
|
+
|
|
20
|
+
Codex reads the same `SKILL.md` from the clone in step 2.
|
|
21
|
+
|
|
22
|
+
## House layer
|
|
23
|
+
|
|
24
|
+
`house.css` loads after `htmlplan.css`. It:
|
|
25
|
+
|
|
26
|
+
- sets the body text color and background from the theme tokens, so text keeps its contrast in dark mode,
|
|
27
|
+
- maps the gray text tokens to the full text color,
|
|
28
|
+
- sets accent and status colors that hold 7:1 contrast in light and dark,
|
|
29
|
+
- raises small text to 16px,
|
|
30
|
+
- removes opacity dimming on text.
|
|
31
|
+
|
|
32
|
+
Paste it into a `<style>` block after the plugin stylesheet, or link it beside the page.
|
|
33
|
+
|
|
34
|
+
## Check before publishing
|
|
35
|
+
|
|
36
|
+
Render the page at 390px in light and dark. Every text node is 16px or larger and holds 7:1 contrast against its painted background. The page has no console errors and no horizontal scroll.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
:root { color-scheme: light dark; --ink-2: var(--ink); --ink-3: var(--ink); --accent: #7a2e14; --green: #1c5426; --amber: #5f3f06; --red: #8f1d17; --on-accent: #ffffff; }
|
|
2
|
+
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --ink-2: var(--ink); --ink-3: var(--ink); --accent: #f6bba5; --green: #9fdcaa; --amber: #f2cc80; --red: #f7b3ab; --on-accent: #1f1e1d; } }
|
|
3
|
+
:root[data-theme="dark"] { --ink-2: var(--ink); --ink-3: var(--ink); --accent: #f6bba5; --green: #9fdcaa; --amber: #f2cc80; --red: #f7b3ab; --on-accent: #1f1e1d; }
|
|
4
|
+
body { background: var(--paper); color: var(--ink); font: 430 16px/1.6 var(--sans); }
|
|
5
|
+
small, code, bdi, .mk-cap, .mk-label, .mk-bar, .fig-cap, .c-lang, .c-lines, .c-body td,
|
|
6
|
+
.pl-num, .pl-chev, .pl-bdg, p.pl-claim, doc-claim > .pl-row > .pl-claim, .pl-body > p, .pl-body > ul, .pl-body > doc-note,
|
|
7
|
+
doc-ask::before, doc-ask label small, doc-ask label .sug, doc-ask label > span,
|
|
8
|
+
.nw-askrow .s, .nw-askrow .q small, .nw-btn, .nw-next, .nw-respond, .nw-cbtn, .fig-zoom, .tr-name, .tr-guide, .tr-note, .cl-note, .cl-loc, .mc-to, .mc-hint { font-size: 16px !important; }
|
|
9
|
+
.nw-cbtn, .cl-loc, .fig-zoom, .mc-ev[disabled], .nw-btn[disabled], svg.nw .msg.mc-past path, svg.nw .msg.mc-past text { opacity: 1 !important; }
|
|
10
|
+
.nw-next, .has-comment > .nw-cbtn, .nw-cbtn.on, .nw-askrow.todo .s, .nw-asks .ttl b.todo, .nw-pop.note .k { color: var(--on-accent) !important; }
|
|
11
|
+
.mk-frame.terminal .mk-bar { color: #e6e3dc; }
|
|
12
|
+
doc-note, doc-note > strong:first-child { font-size: 16px !important; }
|
|
13
|
+
:root { --blue: #1d4a85; --purple: #4f2f96; }
|
|
14
|
+
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --blue: #b9d3f5; --purple: #d3c3f5; } }
|
|
15
|
+
:root[data-theme="dark"] { --blue: #b9d3f5; --purple: #d3c3f5; }
|
|
16
|
+
doc-note, doc-note > strong:first-child, .pill, .kicker, .dek, .meta, h4, th, table, figcaption, .caption, details > summary, pre,
|
|
17
|
+
.nw-toc, .nw-toc a, .nw-toc a.h3, .nw-toc a.ask, .nw-toc .ttl, .nw-pop, .nw-pop .ref, .nw-pop textarea, .nw-sheet .hint, .nw-send-state,
|
|
18
|
+
.nw-sheet .body pre, .nw-asks .ttl, .nw-asks .ttl b, .nw-askrow, .nw-askrow .k, .nw-toast, .nw-pin-list, .nw-err, .nw-bar .nw-respond .n,
|
|
19
|
+
doc-claim[data-l="1"] > .pl-row > .pl-num, doc-claim[data-l="2"] > .pl-row > .pl-claim { font-size: 16px !important; }
|
|
20
|
+
.has-comment > .nw-cbtn, .nw-cbtn.on, .nw-bar .nw-respond .n, .nw-bar .nw-next { background: var(--accent); }
|
|
21
|
+
.nw-bar .nw-respond .n.ok { background: var(--green); color: var(--on-accent); }
|
|
22
|
+
.nw-bar .nw-respond .n { color: var(--on-accent); }
|
|
23
|
+
doc-changes, doc-changes b, .ch-tag, .ch-n, .q-head, .q-via, .q-from, .q-at, .q-body { font-size: 16px !important; }
|
|
24
|
+
.cl-head, .cl-kind, .cl-title, .cl-counts, .cl-counts b, .cl-nm, .cl-rail, .cl-tg, .c-cap, .c-pin b, .mc-now, .mc-now b, .mc-now i, .mc-now span, .nw-pin-dot, svg.nw text, svg.nw .node text.sub, svg.nw .node text.more, svg.nw .edge text, svg.nw .group text { font-size: 16px !important; }
|
|
25
|
+
.cl-tg, .tr-guide { color: var(--ink); }
|
|
26
|
+
.nw-pin-dot { color: var(--on-accent); }
|
|
@@ -10,7 +10,7 @@ This family injects reminders and task guidance when an agent starts, resumes, s
|
|
|
10
10
|
- `session/advisor_rules_prompt.py` injects advisor guidance when the built-in advisor is enabled.
|
|
11
11
|
- `session/orchestrator_auto_starter.py` injects an orchestrator directive when its environment flag is enabled.
|
|
12
12
|
- `session/issue_tracker_session_starter.py` injects issue tracker guidance when enabled for a registered repository.
|
|
13
|
-
- `session/artifact_template_pointer.py` points an agent that starts an artifact page at `docs/templates/artifact-page/README.md`, which names the tracker template and the diagram template and which ask each fits.
|
|
13
|
+
- `session/artifact_template_pointer.py` points an agent that starts an artifact page at `docs/templates/html-plan/README.md`. When the request names the older artifact page template, it points at `docs/templates/artifact-page/README.md`, which names the tracker template and the diagram template and which ask each fits.
|
|
14
14
|
- `advisory/auto_mode_denial_quick_fix.py` proposes one `autoMode.allow` entry and a PowerShell block that writes it after an auto mode denial. It never retries the denied call.
|
|
15
15
|
|
|
16
16
|
## When it fires
|
|
@@ -32,7 +32,7 @@ Preconditions:
|
|
|
32
32
|
- **Advisor guidance.** Input is SessionStart with `advisorModel` set. Run `python -m pytest packages/claude-dev-env/hooks/session/test_advisor_rules_prompt.py -q`. The adjacent test observes guidance only when the advisor setting is enabled.
|
|
33
33
|
- **Orchestrator start.** Input is SessionStart with its opt-in flag set. Run `python -m pytest packages/claude-dev-env/hooks/session/test_orchestrator_auto_starter.py -q`. The adjacent test observes an orchestrator directive.
|
|
34
34
|
- **Issue tracker start.** Input is SessionStart with its opt-in flag and a registered checkout. Run `python -m pytest packages/claude-dev-env/hooks/session/test_issue_tracker_session_starter.py -q`. The adjacent test observes issue tracker context.
|
|
35
|
-
- **Artifact template pointer.** Input is an `Artifact` quickstart call. Run `python -m pytest packages/claude-dev-env/hooks/session/test_artifact_template_pointer.py -q`. The adjacent test observes the template path in `additionalContext`, and silence on a publish call or another skill.
|
|
35
|
+
- **Artifact template pointer.** Input is an `Artifact` quickstart call. Run `python -m pytest packages/claude-dev-env/hooks/session/test_artifact_template_pointer.py -q`. The adjacent test observes the html-plan path ahead of the template path in `additionalContext`, and silence on a publish call or another skill.
|
|
36
36
|
- **Denial quick fix.** Input is a `PermissionDenied` event with a bracketed rule label and a classifier verdict. Run `python -m pytest packages/claude-dev-env/hooks/advisory/test_auto_mode_denial_quick_fix.py -q`. The adjacent test observes the named rule, the allow entry, and the PowerShell block; a denial with no verdict gets a note and no block.
|
|
37
37
|
|
|
38
38
|
## Gotchas
|
|
@@ -9,6 +9,8 @@ __all__ = [
|
|
|
9
9
|
"ARTIFACT_QUICKSTART_ACTION",
|
|
10
10
|
"ARTIFACT_TEMPLATE_PATH",
|
|
11
11
|
"ARTIFACT_TOOL_NAME",
|
|
12
|
+
"HTML_PLAN_TEMPLATE_README_PATH",
|
|
13
|
+
"POINTER_ALTERNATIVE_PREFIX",
|
|
12
14
|
"POINTER_TEXT_PREFIX",
|
|
13
15
|
"SKILL_NAME_INPUT_KEY",
|
|
14
16
|
"SKILL_TOOL_NAME",
|
|
@@ -21,7 +23,11 @@ ARTIFACT_QUICKSTART_ACTION = "quickstart"
|
|
|
21
23
|
SKILL_TOOL_NAME = "Skill"
|
|
22
24
|
SKILL_NAME_INPUT_KEY = "skill"
|
|
23
25
|
ALL_ARTIFACT_DESIGN_SKILL_NAMES = frozenset({"artifact-design"})
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
TEMPLATES_DIRECTORY = Path(__file__).resolve().parents[2] / "docs" / "templates"
|
|
27
|
+
ARTIFACT_TEMPLATE_PATH = TEMPLATES_DIRECTORY / "artifact-page" / "README.md"
|
|
28
|
+
HTML_PLAN_TEMPLATE_README_PATH = TEMPLATES_DIRECTORY / "html-plan" / "README.md"
|
|
29
|
+
POINTER_TEXT_PREFIX = "Build this artifact page from the html-plan skill, following "
|
|
30
|
+
POINTER_ALTERNATIVE_PREFIX = (
|
|
31
|
+
". When the request names the older artifact page template,"
|
|
32
|
+
" pick the one that fits the ask from "
|
|
26
33
|
)
|
|
27
|
-
POINTER_TEXT_PREFIX = "Pick the artifact page template that fits the ask from "
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"""Behavioral tests for the artifact template pointer's path."""
|
|
2
2
|
|
|
3
|
-
from hooks_constants.artifact_template_pointer_constants import
|
|
3
|
+
from hooks_constants.artifact_template_pointer_constants import (
|
|
4
|
+
ARTIFACT_TEMPLATE_PATH,
|
|
5
|
+
HTML_PLAN_TEMPLATE_README_PATH,
|
|
6
|
+
)
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
def test_template_path_names_the_packaged_template_file() -> None:
|
|
7
10
|
assert ARTIFACT_TEMPLATE_PATH.is_file()
|
|
8
11
|
assert ARTIFACT_TEMPLATE_PATH.parent.joinpath("README.md").is_file()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_html_plan_readme_path_names_the_packaged_readme_and_house_stylesheet() -> None:
|
|
15
|
+
assert HTML_PLAN_TEMPLATE_README_PATH.is_file()
|
|
16
|
+
assert HTML_PLAN_TEMPLATE_README_PATH.parent.joinpath("house.css").is_file()
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""PreToolUse hook: point an agent about to build an artifact page at
|
|
2
|
+
"""PreToolUse hook: point an agent about to build an artifact page at html-plan.
|
|
3
3
|
|
|
4
4
|
Registered on ``Artifact|Skill``. It adds one line of ``additionalContext``
|
|
5
|
-
naming ``docs/templates/
|
|
6
|
-
|
|
5
|
+
naming ``docs/templates/html-plan/README.md`` as the default and
|
|
6
|
+
``docs/templates/artifact-page/README.md`` as the alternative when a
|
|
7
|
+
session starts a new artifact page:
|
|
7
8
|
|
|
8
9
|
::
|
|
9
10
|
|
|
@@ -31,6 +32,8 @@ from hooks_constants.artifact_template_pointer_constants import (
|
|
|
31
32
|
ARTIFACT_QUICKSTART_ACTION,
|
|
32
33
|
ARTIFACT_TEMPLATE_PATH,
|
|
33
34
|
ARTIFACT_TOOL_NAME,
|
|
35
|
+
HTML_PLAN_TEMPLATE_README_PATH,
|
|
36
|
+
POINTER_ALTERNATIVE_PREFIX,
|
|
34
37
|
POINTER_TEXT_PREFIX,
|
|
35
38
|
SKILL_NAME_INPUT_KEY,
|
|
36
39
|
SKILL_TOOL_NAME,
|
|
@@ -77,7 +80,10 @@ def decide_hook_output(all_hook_fields: dict[str, object]) -> dict[str, object]
|
|
|
77
80
|
return {
|
|
78
81
|
HOOK_SPECIFIC_OUTPUT_KEY: {
|
|
79
82
|
HOOK_EVENT_NAME_KEY: PRE_TOOL_USE_EVENT_NAME,
|
|
80
|
-
ADDITIONAL_CONTEXT_KEY:
|
|
83
|
+
ADDITIONAL_CONTEXT_KEY: (
|
|
84
|
+
f"{POINTER_TEXT_PREFIX}{HTML_PLAN_TEMPLATE_README_PATH}"
|
|
85
|
+
f"{POINTER_ALTERNATIVE_PREFIX}{ARTIFACT_TEMPLATE_PATH}."
|
|
86
|
+
),
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
|
|
@@ -10,7 +10,10 @@ for each_sys_path_entry in (str(_SESSION_DIR), str(_HOOKS_ROOT)):
|
|
|
10
10
|
sys.path.insert(0, each_sys_path_entry)
|
|
11
11
|
|
|
12
12
|
import artifact_template_pointer
|
|
13
|
-
from hooks_constants.artifact_template_pointer_constants import
|
|
13
|
+
from hooks_constants.artifact_template_pointer_constants import (
|
|
14
|
+
ARTIFACT_TEMPLATE_PATH,
|
|
15
|
+
HTML_PLAN_TEMPLATE_README_PATH,
|
|
16
|
+
)
|
|
14
17
|
|
|
15
18
|
HOOK_SCRIPT = Path(__file__).resolve().parent / "artifact_template_pointer.py"
|
|
16
19
|
|
|
@@ -34,7 +37,10 @@ def test_artifact_quickstart_gets_the_template_pointer() -> None:
|
|
|
34
37
|
hook_output = json.loads(_run_hook(_payload("Artifact", {"action": "quickstart", "intent": "other"})))
|
|
35
38
|
specific_output = hook_output["hookSpecificOutput"]
|
|
36
39
|
assert specific_output["hookEventName"] == "PreToolUse"
|
|
37
|
-
|
|
40
|
+
pointer_text = specific_output["additionalContext"]
|
|
41
|
+
assert pointer_text.index(str(HTML_PLAN_TEMPLATE_README_PATH)) < pointer_text.index(
|
|
42
|
+
str(ARTIFACT_TEMPLATE_PATH)
|
|
43
|
+
)
|
|
38
44
|
assert "permissionDecision" not in specific_output
|
|
39
45
|
|
|
40
46
|
|
package/package.json
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Before asking, give a short formatted chat brief with context and each choice's effect. Add helpful visuals or artifacts.
|
|
4
4
|
|
|
5
|
-
For Codex visual comparisons, find Page creation, visualization upload, and Page opening tools. Create the comparison, upload its visualization, and open its Page here before asking. If tools are missing, steps fail, or opening queues, compare in chat before asking. Put inline Visualize references only in final replies. An async acknowledgement or saved visual is context only; wait for and use the submitted answer before dependent work.
|
|
6
|
-
|
|
7
5
|
Ask one short, self-contained question with two or three choices. Give each a short label and one short sentence. Reuse labels in the brief, comparison, and picker.
|
|
8
6
|
|
|
9
7
|
Find the native question tool and schema. Claude may use `AskUserQuestion`; Codex may use `request_user_input_async` or `request_user_input`. Honor mode rules. Put the question in its title or question field and choices in string or object fields. If unusable, ask in chat.
|
|
8
|
+
|
|
9
|
+
When the user asks for option cards, or for a Codex visual comparison, read the full text first.
|
|
10
|
+
|
|
11
|
+
**Full text:** [`~/.claude/docs/rule-guides/question-presentation.md`](../docs/rule-guides/question-presentation.md).
|