eklavya 1.27.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -42
- package/dist/artifacts.js +2 -2
- package/dist/artifacts.js.map +1 -1
- package/dist/assets/artifact-template.html +2 -2
- package/dist/assets/dashboard.html +196 -57
- package/dist/assets/tokens.css +6 -4
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/agents/explainer.md +5 -3
- package/dist/plugin/cli/CLAUDE.md +60 -108
- package/dist/plugin/hooks/CLAUDE.md +118 -369
- package/dist/plugin/skills/CLAUDE.md +106 -298
- package/dist/user-skill/eklavya-artifacts/SKILL.md +23 -4
- package/package.json +1 -1
|
@@ -1,304 +1,112 @@
|
|
|
1
|
-
# Editing
|
|
1
|
+
# Editing skills and agent instructions
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Skills define model behavior; the runtime owns data and arithmetic. A stale
|
|
4
|
+
sentence can change the product without raising an error. Read the root
|
|
5
|
+
`CLAUDE.md`, then verify instructions against the tool implementation.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Entry points and ownership
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
and
|
|
13
|
-
|
|
14
|
-
Nine have it, and they are the nine slash commands:
|
|
15
|
-
|
|
16
|
-
`gate`, `learn`, `level`, `memory`, `mode`, `pack`, `progress`, `quiz`, `setup`.
|
|
17
|
-
|
|
18
|
-
`skills/tutor/SKILL.md` deliberately does not. It is the pedagogy — one
|
|
19
|
-
question at a time, honest grading, never the same question twice — and every
|
|
20
|
-
other skill defers to it rather than restating it. `quiz` says "follow the
|
|
21
|
-
`tutor` skill for how to ask and grade"; keep it that way. Pedagogy duplicated
|
|
22
|
-
into a command skill is pedagogy that drifts from the one place Cursor reads.
|
|
23
|
-
|
|
24
|
-
## The description is a trigger, not a summary
|
|
25
|
-
|
|
26
|
-
For a model-invocable skill the `description` is the only part always in
|
|
27
|
-
context; the body is read only once the model has decided to load it. So a
|
|
28
|
-
description that summarises the workflow becomes a shortcut the model takes
|
|
29
|
-
*instead of* reading the body — it answers from the summary and never opens the
|
|
30
|
-
file. The body becomes documentation nobody reads.
|
|
31
|
-
|
|
32
|
-
`skills/tutor/SKILL.md` had exactly that shape. It read "Use while implementing
|
|
33
|
-
any non-trivial task (to log the concepts it touches), and whenever quizzing,
|
|
34
|
-
grading, or explaining" — three steps named, and nowhere in it the words *one
|
|
35
|
-
question, mid-task*. Which is the failure the interleaved cadence had to fix:
|
|
36
|
-
questions arriving in a pile at the end of the work.
|
|
37
|
-
|
|
38
|
-
So, for `tutor` and anything else without `disable-model-invocation`:
|
|
39
|
-
**triggering conditions only**, third person, opening "Use when". Never the
|
|
40
|
-
number of questions, never the order of the tool calls, never the grading.
|
|
41
|
-
Those live in the body, which is where the model has to go to get them.
|
|
42
|
-
|
|
43
|
-
The nine slash commands are exempt, and it is not a technicality:
|
|
44
|
-
`disable-model-invocation: true` means the model never matches on their
|
|
45
|
-
description at all. The developer types the command and the description is its
|
|
46
|
-
one line of help, so those should say what they do. `agents/tutor.md` keeps one
|
|
47
|
-
identity clause for the same kind of reason — a subagent is picked from a roster
|
|
48
|
-
by what it is, not loaded by trigger.
|
|
49
|
-
|
|
50
|
-
## Three directories, and why they are not one
|
|
51
|
-
|
|
52
|
-
- **`skills/`** ships inside the plugin. Slash commands plus `tutor`.
|
|
53
|
-
- **`user-skill/eklavya/`** is copied to `~/.claude/skills/eklavya/` by
|
|
54
|
-
`npx eklavya install` (`installSkill()` in `mcp/src/install.ts`). It is
|
|
55
|
-
model-invocable, so plain chat — "Eklavya is quizzing me too much" — reaches
|
|
56
|
-
it, and it works where the plugin is not loaded. **Never move it under
|
|
57
|
-
`skills/`**: it would then register twice, once per surface. It drives the
|
|
58
|
-
`eklavya` CLI and the read/write config tools; it does not teach or quiz.
|
|
59
|
-
- **`user-skill/eklavya-artifacts/`** travels the same way (`USER_SKILLS` in
|
|
60
|
-
`install.ts`). It writes a page under `~/.eklavya/artifacts/<project>/`
|
|
61
|
-
through `eklavya artifacts new`, which owns the path, the metadata and the
|
|
62
|
-
template — the skill never writes a page from scratch. Its design rules and
|
|
63
|
-
`agents/explainer.md`'s summary of them describe one thing; change both.
|
|
64
|
-
- **`agents/explainer.md`** is the background page-writer `record_attempt`'s
|
|
65
|
-
`explain` block names. No Eklavya MCP tools at all: it cannot grade or log.
|
|
66
|
-
- **`agents/tutor.md`** is the subagent. It has the Eklavya MCP tools and
|
|
67
|
-
read-only file access — and **no `AskUserQuestion`** — so it renders the four
|
|
68
|
-
options as lettered text. Any change to
|
|
69
|
-
`skills/tutor/references/writing-mcq.md` has to hold for a plain-text
|
|
70
|
-
renderer too.
|
|
71
|
-
|
|
72
|
-
## A skill is a prompt, but it is also an API client
|
|
73
|
-
|
|
74
|
-
Twenty tools, all in `mcp/src/tools/`. Nine for learning:
|
|
75
|
-
`get_learner_profile`, `log_session_concepts`, `get_session_quiz_plan`,
|
|
76
|
-
`record_attempt`, `get_gate_status`, `upsert_concepts`, `get_concept_graph`,
|
|
77
|
-
`get_config`, `set_config`. Eleven for memory: `memory_search`, `memory_get`,
|
|
78
|
-
`memory_timeline`, `memory_file_history`, `memory_status`, `memory_write`,
|
|
79
|
-
`memory_correct`, `memory_delete`, `memory_collections`, `code_outline`,
|
|
80
|
-
`code_find_symbol`.
|
|
81
|
-
|
|
82
|
-
The memory tools are two-stage on purpose: the index tools return identifiers
|
|
83
|
-
and titles, and `memory_get` is the only one that returns a narrative. A skill
|
|
84
|
-
that tells the model to hydrate everything a search returned spends exactly
|
|
85
|
-
the context the feature exists to save. Say "search, choose, then get".
|
|
86
|
-
|
|
87
|
-
**Before you write "call `X` with `Y`", open `mcp/src/tools/<X>.ts`.** Check
|
|
88
|
-
`Y` is in the `inputSchema`, and check the field you are telling the model to
|
|
89
|
-
read is in what the handler returns. A skill that names a field the server
|
|
90
|
-
never returns fails silently — the model improvises a plausible value and the
|
|
91
|
-
developer sees a confident number nobody computed.
|
|
92
|
-
|
|
93
|
-
`config_tools.ts` holds `get_config` and `set_config`, and the memory tools are
|
|
94
|
-
grouped the same way — `memory_read_tools.ts`, `memory_write_tools.ts`,
|
|
95
|
-
`code_tools.ts`, `collection_tools.ts`. The nine learning tools are one file
|
|
96
|
-
per tool name.
|
|
97
|
-
|
|
98
|
-
### Not every tool takes `session_id`
|
|
9
|
+
Each skill has a directory and `SKILL.md` with `name` and `description`.
|
|
10
|
+
`disable-model-invocation: true` makes the entry user-invoked only. The shipped
|
|
11
|
+
slash commands are `gate`, `learn`, `level`, `memory`, `mode`, `pack`, `progress`,
|
|
12
|
+
`quiz` and `setup`. Recount from frontmatter when changing this inventory.
|
|
99
13
|
|
|
14
|
+
| Location | Responsibility |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `skills/tutor/` | Shared pedagogy; commands defer to it rather than duplicate it |
|
|
17
|
+
| `user-skill/eklavya/` | Plain-chat configuration and CLI help, installed to `~/.claude/skills/`; does not teach |
|
|
18
|
+
| `user-skill/eklavya-artifacts/` | Create pages through `eklavya artifacts new`, which owns paths, metadata and template |
|
|
19
|
+
| `agents/tutor.md` | Read-only file access and selected learning/memory tools; teaches builder-logged concepts and uses lettered text without `AskUserQuestion` |
|
|
20
|
+
| `agents/explainer.md` | Background artifact writer; no Eklavya MCP tools, grading or concept logging |
|
|
21
|
+
|
|
22
|
+
Never move `user-skill/` entries into `skills/`: they would register twice.
|
|
23
|
+
Keep artifact design instructions and the explainer's summary aligned.
|
|
24
|
+
|
|
25
|
+
Model-invocable descriptions should state triggering conditions, in third person,
|
|
26
|
+
starting “Use when”; put workflow, tool order and grading in the body. A summary
|
|
27
|
+
in the description invites the model to skip reading the rules. User-invoked
|
|
28
|
+
command descriptions instead serve as concise help. Agent descriptions also
|
|
29
|
+
need their role so they can be selected from a roster.
|
|
30
|
+
|
|
31
|
+
## Check the API before writing instructions
|
|
32
|
+
|
|
33
|
+
Open the relevant file in `mcp/src/tools/` before saying “call X with Y”. Verify
|
|
34
|
+
the input schema and every returned field the instruction uses. Learning tools
|
|
35
|
+
mostly have individual files; config, memory read/write, code and collections
|
|
36
|
+
tools are grouped. `tools/index.ts` is the advertised inventory.
|
|
37
|
+
|
|
38
|
+
Normally omit `session_id`: tools that support it resolve the current session.
|
|
39
|
+
Use an explicit ID only when supplied by the host or required by the task.
|
|
100
40
|
`log_session_concepts`, `upsert_concepts`, `get_session_quiz_plan`,
|
|
101
|
-
`record_attempt` and `
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
`
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
- **The seed catalogue holds 87 concepts today** — 33 `web-auth`, 19 `git`, 18
|
|
132
|
-
`react`, 17 `node-backend`, in `mcp/src/seed/*.json`. If you state that
|
|
133
|
-
number in a skill, recount it first; a seed file gains concepts and the
|
|
134
|
-
sentence does not.
|
|
135
|
-
|
|
136
|
-
## The dials are in the status bar, not above the stem
|
|
137
|
-
|
|
138
|
-
Until 1.14 every plan item carried `ask_header` and the tutor printed it above
|
|
139
|
-
the question: `[mode: ambient · focus: concept · level: easy · tier: 2
|
|
140
|
-
mechanism]` — in the vocabulary of the day, when a single `mode` dial still
|
|
141
|
-
existed. It existed for a real reason — on `concept` focus a deliberately
|
|
142
|
-
transferable question reads as a vague one, and on `easy` a tier-2 question
|
|
143
|
-
reads as shallow rather than as a runway — but it spent four settings' worth of
|
|
144
|
-
screen above *every* stem to say something that is true for the whole session.
|
|
145
|
-
|
|
146
|
-
Ambient state belongs somewhere ambient. `statusLine` in `mcp/src/statusline.ts`
|
|
147
|
-
composes `[EKLAVYA concept · interleaved · easy]` for `eklavya statusline`,
|
|
148
|
-
which the host's status bar runs — with `enforced` prepended only when it is
|
|
149
|
-
set, since a segment that is always there is a segment nobody reads. `askHeader` is deleted,
|
|
150
|
-
the plan no longer carries `ask_header`, and both hooks now say *ask the stem on
|
|
151
|
-
its own*.
|
|
152
|
-
|
|
153
|
-
Two consequences for anyone editing a skill:
|
|
154
|
-
|
|
155
|
-
- **Never tell the model to compose a settings line.** Not the dials, not the
|
|
156
|
-
tier, not `question: 2 of 3`. A line a skill assembles is a line the server
|
|
157
|
-
cannot keep consistent, which is the reason this was centralised in the first
|
|
158
|
-
place.
|
|
159
|
-
- **`stripAskHeader` stays, and must.** Every attempt recorded while the line
|
|
160
|
-
existed still has it inside the stem, and `questionFingerprint` (`store.ts`)
|
|
161
|
-
hashes that text. Delete the stripper and the entire back catalogue changes
|
|
162
|
-
fingerprint at once, so *never the same question twice* breaks for every
|
|
163
|
-
question ever asked. It is now a guard for history, plus a model that invents
|
|
164
|
-
a line anyway — plus the one thing that is still allowed above a stem, below.
|
|
165
|
-
|
|
166
|
-
### The one exception: who is asking
|
|
167
|
-
|
|
168
|
-
The status bar carries the dials, and the `header` chip carries the
|
|
169
|
-
attribution. Both are terminal paint. Claude Desktop draws a question card with
|
|
170
|
-
no chip in it and has no status bar to run `eklavya statusline` in, so a
|
|
171
|
-
question there arrived signed by nobody — which is the thing the chip existed
|
|
172
|
-
to prevent, failing silently on a whole host.
|
|
173
|
-
|
|
174
|
-
So `[Eklavya]` goes back above the stem, **on those hosts only**, and only that.
|
|
175
|
-
`needsInlineAttribution` in `mcp/src/surface.ts` decides, `attributionRule`
|
|
176
|
-
composes the sentence, and the plan returns it as `ask_attribution`. That field
|
|
177
|
-
is why this is not a re-run of `ask_header`: the rule is composed once on the
|
|
178
|
-
server, where the host is visible, rather than assembled by a skill that cannot
|
|
179
|
-
see one.
|
|
180
|
-
|
|
181
|
-
A third consequence follows from the two above:
|
|
182
|
-
|
|
183
|
-
- **A skill file must not state the rule itself.** `writing-mcq.md` and
|
|
184
|
-
`SKILL.md` point at `ask_attribution` and stop. A skill is static and a host
|
|
185
|
-
is not, so a skill that spells out "set `header` and nothing else" is correct
|
|
186
|
-
in a terminal and wrong in Claude Desktop, with no way to tell which it is
|
|
187
|
-
being read in.
|
|
188
|
-
|
|
189
|
-
The tier is deliberately nowhere on screen. A status bar refreshes on the host's
|
|
190
|
-
cadence, so a tier there would sometimes name the previous question's
|
|
191
|
-
difficulty, and a stale readout is worse than none. `level` covers what the tier
|
|
192
|
-
was explaining: `easy` already means tiers 1-2.
|
|
193
|
-
|
|
194
|
-
## The tutor skill is an entry point plus references
|
|
195
|
-
|
|
196
|
-
`skills/tutor/SKILL.md` was 5,296 words in one file, loaded whole whenever the
|
|
197
|
-
model decided a task was non-trivial. It is now the part that decides *whether
|
|
198
|
-
to act* — the log loop, checkpoint versus sweep, the shared budget, the tier
|
|
199
|
-
ladder, the plan's authoritative fields, and a Red Flags table of the
|
|
200
|
-
rationalizations that have each shipped a worse session — with the craft in
|
|
201
|
-
three siblings:
|
|
202
|
-
|
|
203
|
-
| File | Holds |
|
|
41
|
+
`record_attempt`, `get_gate_status`, `get_config` and `set_config` accept it for
|
|
42
|
+
session resolution. `memory_timeline` also accepts it, but as a filter: omitting
|
|
43
|
+
it shows the whole project. Check each schema instead of assuming all tools
|
|
44
|
+
accept the same fields.
|
|
45
|
+
|
|
46
|
+
Memory follows “search, choose, then get”. Search returns a small index;
|
|
47
|
+
`memory_get` returns the chosen narrative. Hydrating every result defeats the
|
|
48
|
+
context-saving design.
|
|
49
|
+
|
|
50
|
+
## Preserve the tutoring contract
|
|
51
|
+
|
|
52
|
+
- Read defaults from `mcp/src/config.ts`: focus is `concept`. Search every skill,
|
|
53
|
+
user skill, agent and manual page when changing a shared setting.
|
|
54
|
+
- Planner output is authoritative. Interleaved questions are capped at one only
|
|
55
|
+
when unenforced and without an explicit topic; explicit `max` wins. Unenforced
|
|
56
|
+
Stop hooks can still ask questions.
|
|
57
|
+
- Settings belong in `eklavya statusline`, not a hand-composed question header.
|
|
58
|
+
Follow the plan's `ask_attribution` for host-specific `[Eklavya]` attribution;
|
|
59
|
+
never hardcode a terminal-only rendering rule. Do not display tier/counter
|
|
60
|
+
lines above a stem.
|
|
61
|
+
- `stripAskHeader` in `ask.ts` remains necessary for old recorded questions and
|
|
62
|
+
stable fingerprints. Removing it changes duplicate detection for history.
|
|
63
|
+
- Honor list caps and truncation. Profile `known` is strongest-first, not most
|
|
64
|
+
recent; graph results can be incomplete. Recount seed totals before quoting.
|
|
65
|
+
- Keep `declined` distinct from `dont_know`, MCQ grading capped as the runtime
|
|
66
|
+
requires, and one-question/resume behavior intact.
|
|
67
|
+
|
|
68
|
+
The tutor entry point chooses whether to act and points to required references:
|
|
69
|
+
|
|
70
|
+
| Reference | Read before |
|
|
204
71
|
|---|---|
|
|
205
|
-
| `references/writing-mcq.md` |
|
|
206
|
-
| `references/grading.md` |
|
|
207
|
-
| `references/focus-and-level.md` |
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
`references/writing-mcq.md` was written as the first kind — *never restate the
|
|
247
|
-
answer, no double negatives, avoid "which is NOT", do not number the options*.
|
|
248
|
-
It is now a six-part recipe in build order followed by a checklist of
|
|
249
|
-
properties, so the same rules arrive as "the answer appears among the options
|
|
250
|
-
and nowhere in the stem" rather than as separate bans to weigh.
|
|
251
|
-
|
|
252
|
-
**No nuance clauses in the recipe.** superpowers measured this separately: one
|
|
253
|
-
appended "unless it matters" turns a reliable recipe into a noisy one, because
|
|
254
|
-
it reopens the negotiation the recipe had settled. `writing-mcq.md` carried
|
|
255
|
-
exactly one — *"Save the precise term for when the precision is the point"* —
|
|
256
|
-
and it is gone. If an exception is real, it belongs in the plan's `framing`,
|
|
257
|
-
which is server-side and authoritative, not in a hedge the model gets to weigh.
|
|
258
|
-
|
|
259
|
-
`references/grading.md` keeps its prohibitions on purpose. Inflating a grade
|
|
260
|
-
and offering to stop because someone is blanking are pressure failures, not
|
|
261
|
-
shape failures: the model knows what honest grading is.
|
|
262
|
-
|
|
263
|
-
## The tutor skill has two readers
|
|
264
|
-
|
|
265
|
-
`mcp/scripts/copy-assets.mjs` bundles the whole `skills/tutor/` directory to
|
|
266
|
-
`mcp/dist/assets/tutor/`, and `eklavya export-rules` (`mcp/src/cli.ts`) strips
|
|
267
|
-
the frontmatter and wraps it as a Cursor rules file. So the pedagogy is
|
|
268
|
-
consumed by two editors.
|
|
269
|
-
|
|
270
|
-
**Cursor has no progressive disclosure**, and that is the reason `export-rules`
|
|
271
|
-
concatenates SKILL.md with every `references/*.md` in alphabetical order and
|
|
272
|
-
says so in its preamble. A rules file is one document with `alwaysApply: true`,
|
|
273
|
-
so "read `references/grading.md`" there is a pointer to nothing. Had the split
|
|
274
|
-
shipped without the inlining, Cursor would have got the dispatch logic and none
|
|
275
|
-
of the craft — and every test would still have passed. `test/cli.test.ts` now
|
|
276
|
-
asserts a line from each reference reaches the output.
|
|
277
|
-
|
|
278
|
-
Alphabetical rather than a hand-kept order: in an always-apply document the
|
|
279
|
-
whole thing is in context at once, so order carries no meaning, and a listed
|
|
280
|
-
order is one more place a new reference gets forgotten.
|
|
281
|
-
|
|
282
|
-
**A missing reference is a hard failure there, not a warning.** `export-rules`
|
|
283
|
-
reads the pointers out of SKILL.md and refuses to emit anything if one of them
|
|
284
|
-
did not bundle, naming the file. It has to: the preamble promises the material
|
|
285
|
-
is further down the document, so a half-bundled export is worse than none — the
|
|
286
|
-
model is assured the rules are present and hunts for them instead of falling
|
|
287
|
-
back on what it has. `copy-assets.mjs` only warns when a copy fails, so that
|
|
288
|
-
state is reachable rather than hypothetical.
|
|
289
|
-
|
|
290
|
-
Consequence of the two readers: **no Claude-Code-only instructions in any of
|
|
291
|
-
the four files.** Slash-command names, plugin paths and hook mechanics belong
|
|
292
|
-
in the command skills, not in the pedagogy. `AskUserQuestion` is the one
|
|
293
|
-
unavoidable exception, and `agents/tutor.md` already carries the fallback for
|
|
294
|
-
renderers that lack it.
|
|
295
|
-
|
|
296
|
-
## Consistency
|
|
297
|
-
|
|
298
|
-
The same behaviour described in two skills has drifted apart before — that is
|
|
299
|
-
how `focus: project` got into three files. The dials appear in
|
|
300
|
-
`skills/mode/SKILL.md` and `user-skill/eklavya/SKILL.md`; the level bands
|
|
301
|
-
appear in `skills/level/SKILL.md` and `tutor/references/focus-and-level.md`;
|
|
302
|
-
the cadence cap appears in `mode`, `quiz` and that same reference. **When you
|
|
303
|
-
change one, grep the others for the same claim.** Where any of them disagrees with the code,
|
|
304
|
-
`mcp/src/config.ts` and the tool file are right and the skill is wrong.
|
|
72
|
+
| `tutor/references/writing-mcq.md` | Writing the stem, options and recorded question |
|
|
73
|
+
| `tutor/references/grading.md` | Grading, feedback, blanks and repeated teaching |
|
|
74
|
+
| `tutor/references/focus-and-level.md` | Applying focus, earned levels, cadence and gate retries |
|
|
75
|
+
|
|
76
|
+
Mark references REQUIRED at their point of use. Do not use eager `@` imports.
|
|
77
|
+
Keep the entry point within the packaging test's 2,000-whitespace-token limit.
|
|
78
|
+
Every referenced file must exist and every reference file must be reachable from
|
|
79
|
+
the entry point; the packaging test checks both directions.
|
|
80
|
+
|
|
81
|
+
For craft, describe the desired shape in build order, followed by a checklist.
|
|
82
|
+
For pressure failures such as grade inflation, retain explicit prohibitions and
|
|
83
|
+
the rationalization they prevent. Avoid vague exceptions that let the model
|
|
84
|
+
renegotiate a recipe; genuine framing exceptions belong in planner output.
|
|
85
|
+
|
|
86
|
+
## Bundling and host limits
|
|
87
|
+
|
|
88
|
+
`copy-assets.mjs` bundles the tutor directory. `eklavya export-rules` strips
|
|
89
|
+
frontmatter and inlines reference files alphabetically for consumers that do
|
|
90
|
+
not load them on demand. Missing references must fail export, not emit partial
|
|
91
|
+
pedagogy. Keep shared tutor material independent of plugin paths, hook mechanics
|
|
92
|
+
and slash commands; the tutor agent supplies the plain-text fallback for
|
|
93
|
+
`AskUserQuestion`.
|
|
94
|
+
|
|
95
|
+
Rule export does not provide another editor with Claude Code hooks. Do not
|
|
96
|
+
advertise equivalent ambient learning on a host without that integration.
|
|
97
|
+
Delegation policy lives in `docs/subagent-policy.md`; the tutor exemption from
|
|
98
|
+
the implementer's “do not ask” directive must remain deliberate.
|
|
99
|
+
|
|
100
|
+
## Documentation and checks
|
|
101
|
+
|
|
102
|
+
Update the corresponding manual page in the same PR: commands in `commands`,
|
|
103
|
+
settings in `dials`/`configuration`, grading in `grading-engine`, levels in
|
|
104
|
+
`levels-and-tiers`, artifacts in `dashboard`, and setup in `first-run`.
|
|
105
|
+
Update the landing command list if the public command set changes. Search other
|
|
106
|
+
skills for duplicated claims rather than fixing only the entry you touched.
|
|
107
|
+
|
|
108
|
+
Run the relevant packaging, CLI and tool tests from `mcp/` through `npm test`
|
|
109
|
+
so bundled assets are rebuilt. Tutor behavior changes also require before/after
|
|
110
|
+
evaluation (`eval/README.md`) and the live checkpoint acceptance check
|
|
111
|
+
(`CONTRIBUTING.md`). A successful build alone cannot verify prompt behavior.
|
|
112
|
+
Build `web/` for documentation edits and record any check not run.
|
|
@@ -77,10 +77,29 @@ not.
|
|
|
77
77
|
|
|
78
78
|
**Stay on the design system.** Components already in the template: `.eyebrow`,
|
|
79
79
|
`.lede`, `.card`, `.grid`, `.chip` (`.warn`, `.bad`), `.stat` (`.k`, `.v`,
|
|
80
|
-
`.d`), `.callout`, `td.num`.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
`.d`), `.callout`, `td.num`. Reuse them before adding CSS. Any CSS you add
|
|
81
|
+
follows Eklavya's rules:
|
|
82
|
+
|
|
83
|
+
- **Colour names a role**, never a raw hex, `rgba()` or `--vd-*` step. Grounds
|
|
84
|
+
`--bg`, `--panel` (cards), `--mass` (wells, inline code), `--code-bg`; text
|
|
85
|
+
`--ink`, `--dim` (body), `--faint` (captions, labels); hairlines `--line`,
|
|
86
|
+
`--line-2`; accent `--spot`, `--spot-soft` (tints), `--spot-ink` (text on a
|
|
87
|
+
`--spot` fill); state `--warning`, `--error`. `--faint-2` is for disabled
|
|
88
|
+
marks only, never readable text.
|
|
89
|
+
- **One accent**, verdigris `--spot`, spent a handful of times: the node that
|
|
90
|
+
matters, a key number, a link. No other hues. `--warning` and `--error` mean
|
|
91
|
+
a real warning or mistake, and always carry a word or mark too — never
|
|
92
|
+
colour alone.
|
|
93
|
+
- **Square and flat.** `border-radius: 0` on every box, chip and table; circles
|
|
94
|
+
only for dots. Separate with 1px hairlines, not shadows.
|
|
95
|
+
- **Type through the variables**: `--font-disp` (Archivo) for headings,
|
|
96
|
+
`--font-body` (Inter) for text, `--font-mono` (JetBrains Mono) for code,
|
|
97
|
+
commands, concept slugs and small uppercase labels. Sentence case.
|
|
98
|
+
- **Icons** are inline Lucide-style line SVG: `stroke="currentColor"`, width 2,
|
|
99
|
+
round caps and joins. No emoji, icon fonts or filled icons.
|
|
100
|
+
- **Both grounds.** Every text colour reads at 4.5:1 on ink and on paper —
|
|
101
|
+
check with `data-mode="paper"` on `<html>`. Motion, if any, is short
|
|
102
|
+
(120–320ms on `--ease`) and switched off under `prefers-reduced-motion`.
|
|
84
103
|
|
|
85
104
|
**Keep it one file.** Everything inline. An external stylesheet, script or
|
|
86
105
|
image breaks the HTML download, which hands over the page itself.
|
package/package.json
CHANGED