dsh-diagnostic-tutor 0.1.1 → 0.2.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 +224 -59
- package/lib/api.js +178 -0
- package/lib/api.js.map +1 -1
- package/lib/block-types.js +25 -0
- package/lib/block-types.js.map +1 -0
- package/lib/client.js +9448 -1654
- package/lib/client.js.map +1 -1
- package/lib/diagnostics.js +170 -0
- package/lib/diagnostics.js.map +1 -0
- package/lib/index.js +75 -13
- package/lib/index.js.map +1 -1
- package/lib/insights.js +82 -0
- package/lib/insights.js.map +1 -0
- package/lib/interactions.js +70 -0
- package/lib/interactions.js.map +1 -0
- package/lib/journal.js +122 -0
- package/lib/journal.js.map +1 -0
- package/lib/lesson-markdown.js +72 -0
- package/lib/lesson-markdown.js.map +1 -0
- package/lib/lesson.js +152 -3
- package/lib/lesson.js.map +1 -1
- package/lib/math.js +126 -0
- package/lib/math.js.map +1 -0
- package/lib/path-api.js +140 -0
- package/lib/path-api.js.map +1 -0
- package/lib/path-runtime.js +361 -0
- package/lib/path-runtime.js.map +1 -0
- package/lib/path-tools.js +107 -0
- package/lib/path-tools.js.map +1 -0
- package/lib/path.js +179 -0
- package/lib/path.js.map +1 -0
- package/lib/plan-tools.js +89 -0
- package/lib/plan-tools.js.map +1 -0
- package/lib/plan.js +82 -0
- package/lib/plan.js.map +1 -0
- package/lib/project-session.js +48 -0
- package/lib/project-session.js.map +1 -0
- package/lib/prompt.js +4 -19
- package/lib/prompt.js.map +1 -1
- package/lib/review-sync.js +51 -0
- package/lib/review-sync.js.map +1 -0
- package/lib/review-tools.js +115 -0
- package/lib/review-tools.js.map +1 -0
- package/lib/review.js +103 -0
- package/lib/review.js.map +1 -0
- package/lib/source-schema.js +24 -0
- package/lib/source-schema.js.map +1 -0
- package/lib/source-tools.js +61 -0
- package/lib/source-tools.js.map +1 -0
- package/lib/sources.js +78 -0
- package/lib/sources.js.map +1 -0
- package/lib/state.js +148 -7
- package/lib/state.js.map +1 -1
- package/lib/tools.js +456 -40
- package/lib/tools.js.map +1 -1
- package/lib/types/api.d.ts +7 -0
- package/lib/types/api.d.ts.map +1 -1
- package/lib/types/block-types.d.ts +12 -0
- package/lib/types/block-types.d.ts.map +1 -0
- package/lib/types/contract.d.ts +33 -1
- package/lib/types/contract.d.ts.map +1 -1
- package/lib/types/diagnostics.d.ts +95 -0
- package/lib/types/diagnostics.d.ts.map +1 -0
- package/lib/types/handoff.d.ts +2 -2
- package/lib/types/index.d.ts +15 -9
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/insights.d.ts +57 -0
- package/lib/types/insights.d.ts.map +1 -0
- package/lib/types/interactions.d.ts +23 -0
- package/lib/types/interactions.d.ts.map +1 -0
- package/lib/types/journal.d.ts +57 -0
- package/lib/types/journal.d.ts.map +1 -0
- package/lib/types/lesson-markdown.d.ts +11 -0
- package/lib/types/lesson-markdown.d.ts.map +1 -0
- package/lib/types/lesson.d.ts +697 -5
- package/lib/types/lesson.d.ts.map +1 -1
- package/lib/types/math.d.ts +50 -0
- package/lib/types/math.d.ts.map +1 -0
- package/lib/types/path-api.d.ts +5 -0
- package/lib/types/path-api.d.ts.map +1 -0
- package/lib/types/path-runtime.d.ts +1558 -0
- package/lib/types/path-runtime.d.ts.map +1 -0
- package/lib/types/path-tools.d.ts +4 -0
- package/lib/types/path-tools.d.ts.map +1 -0
- package/lib/types/path.d.ts +744 -0
- package/lib/types/path.d.ts.map +1 -0
- package/lib/types/plan-tools.d.ts +4 -0
- package/lib/types/plan-tools.d.ts.map +1 -0
- package/lib/types/plan.d.ts +53 -0
- package/lib/types/plan.d.ts.map +1 -0
- package/lib/types/project-session.d.ts +33 -0
- package/lib/types/project-session.d.ts.map +1 -0
- package/lib/types/prompt.d.ts.map +1 -1
- package/lib/types/review-sync.d.ts +17 -0
- package/lib/types/review-sync.d.ts.map +1 -0
- package/lib/types/review-tools.d.ts +4 -0
- package/lib/types/review-tools.d.ts.map +1 -0
- package/lib/types/review.d.ts +65 -0
- package/lib/types/review.d.ts.map +1 -0
- package/lib/types/source-schema.d.ts +31 -0
- package/lib/types/source-schema.d.ts.map +1 -0
- package/lib/types/source-tools.d.ts +4 -0
- package/lib/types/source-tools.d.ts.map +1 -0
- package/lib/types/sources.d.ts +33 -0
- package/lib/types/sources.d.ts.map +1 -0
- package/lib/types/state.d.ts +516 -9
- package/lib/types/state.d.ts.map +1 -1
- package/lib/types/tools.d.ts +3 -1
- package/lib/types/tools.d.ts.map +1 -1
- package/lib/types/version.d.ts +11 -0
- package/lib/types/version.d.ts.map +1 -0
- package/lib/types/vocabulary.d.ts +2 -2
- package/lib/version.js +26 -0
- package/lib/version.js.map +1 -0
- package/package.json +20 -18
package/README.md
CHANGED
|
@@ -11,24 +11,35 @@ learn interactively, and move to the next best step.
|
|
|
11
11
|
|
|
12
12
|
## Status
|
|
13
13
|
|
|
14
|
-
`v0.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
`v0.2.0` is the published release. It includes the learning-path flow — saved
|
|
15
|
+
goal and time budget, evidence-referenced initial assessment, versioned course
|
|
16
|
+
routes with per-lesson Overviews, session-scoped attempts, and the
|
|
17
|
+
English/Simplified-Chinese interface — plus the content/input/review loop:
|
|
18
|
+
|
|
19
|
+
- typeset math, formula/code/quiz/flashcard/resource/comparison blocks;
|
|
20
|
+
- learner sources with `sourceRefs` citations;
|
|
21
|
+
- Today plan with ICS export and learner-controlled completion;
|
|
22
|
+
- spaced review with automatic flashcard cards, four ratings and undo;
|
|
23
|
+
- read-only Insights.
|
|
24
|
+
|
|
25
|
+
Install it with
|
|
26
|
+
`dsh plugin --profile web add dsh-diagnostic-tutor@0.2.0` — no clone, no
|
|
27
|
+
`pnpm install`, no build step. A checkout can be installed instead (see
|
|
28
|
+
[Installing a checkout](#installing-a-checkout-instead-of-the-package)).
|
|
22
29
|
|
|
23
30
|
The learning loop works end to end: a real goal in your own words, a diagnosis
|
|
24
31
|
map grown one node at a time, a tutor-written lesson, a check answered in the
|
|
25
32
|
chat, recorded evidence, and a next step the tutor chose — which the learner
|
|
26
|
-
presses Continue to take.
|
|
33
|
+
presses Continue to take. The route flow adds a full plan the learner reviews
|
|
34
|
+
and accepts, lesson by lesson; the content loop adds math, sources, Today and
|
|
35
|
+
review on top of it.
|
|
27
36
|
|
|
28
37
|
It is also early. The [limitations](#known-limitations) are listed rather than
|
|
29
38
|
left to be discovered, and nothing below claims a capability that is not there:
|
|
30
|
-
no PDF
|
|
31
|
-
|
|
39
|
+
no PDF extraction, no RAG, no automatic external resource fetching, no analytics.
|
|
40
|
+
Review scheduling is a local interval heuristic, not FSRS. Course routes are
|
|
41
|
+
proposed by the teaching model, never generated by the runtime, and a route never
|
|
42
|
+
marks knowledge as mastered.
|
|
32
43
|
|
|
33
44
|
## Two halves, one system
|
|
34
45
|
|
|
@@ -124,12 +135,13 @@ see is a *diagnosis map*, not a syllabus.
|
|
|
124
135
|
|
|
125
136
|
Stated plainly, because each one is a real edge a user can reach.
|
|
126
137
|
|
|
127
|
-
**Math is
|
|
128
|
-
inline, `\[...\]` display — and the
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
**Math is rendered as MathML on the host.** The tutor writes LaTeX by convention
|
|
139
|
+
— `\(...\)` inline, `\[...\]` display — and the host pre-renders it with
|
|
140
|
+
KaTeX's MathML output before storing the block. The browser renders native
|
|
141
|
+
MathML through a tag/attribute whitelist; no font or CSS is fetched. Invalid
|
|
142
|
+
TeX inside a text block falls back to the old styled source; an invalid
|
|
143
|
+
`formula` block is refused at write time. Browser MathML quality varies, and
|
|
144
|
+
this build ships no KaTeX CSS/fonts.
|
|
133
145
|
|
|
134
146
|
**Skill presence requires a live Agent.** The runtime checks the open
|
|
135
147
|
conversation's Agent scope on each overview, including its workspace. Before an
|
|
@@ -157,9 +169,12 @@ matrix as load-bearing, not decoration.
|
|
|
157
169
|
|
|
158
170
|
| This plugin | Verified against DSH | Node |
|
|
159
171
|
| --- | --- | --- |
|
|
160
|
-
| `0.
|
|
172
|
+
| `0.2.0` | `0.2.1-rc.3`, `0.2.1-rc.2`, `0.2.0-rc.2` (test suite also on `0.1.7-alpha.2`) | `^22.19.0 \|\| >=24.0.0` |
|
|
173
|
+
| `0.1.1` | `0.2.1-rc.3`, `0.2.1-rc.2`, `0.2.0-rc.2` (test suite also on `0.1.7-alpha.2`) | `^22.19.0 \|\| >=24.0.0` |
|
|
161
174
|
| `0.1.0` | `0.1.7-alpha.2` (also composed under `0.1.5-rc.1`) | `^22.19.0 \|\| >=24.0.0` |
|
|
162
175
|
|
|
176
|
+
Phase 1–6 的本机 boot 矩阵(2026-10-29)覆盖 `0.2.1-rc.3`、`0.2.1-rc.2`、`0.2.0-rc.2`、`0.1.7-alpha.2` 的插件加载、本地路由、domain v1 与客户端启动;其中 rc3/alpha.2 还通过了 tarball 安装,并用真实模型完成 lesson → Review 评分/撤销 → Insights;rc2/rc20 的完整真实会话仍是补充项。详见 [`docs/planning/COMPATIBILITY.md`](docs/planning/COMPATIBILITY.md)。
|
|
177
|
+
|
|
163
178
|
Rules this repository enforces mechanically:
|
|
164
179
|
|
|
165
180
|
- **Named exports only.** A `export default` plugin makes Cordis' loader prefer
|
|
@@ -174,6 +189,38 @@ Rules this repository enforces mechanically:
|
|
|
174
189
|
in the range — so the compatibility matrix above, not the range floor, is the
|
|
175
190
|
contract. Dev dependencies pin one exact cohort for the type baseline.
|
|
176
191
|
|
|
192
|
+
## UI baseline for redesign
|
|
193
|
+
|
|
194
|
+
The current surfaces, state model and screenshots (generated from fixtures) live in
|
|
195
|
+
[`docs/design/ui-baseline/index.html`](docs/design/ui-baseline/index.html) with a
|
|
196
|
+
detailed handoff in
|
|
197
|
+
[`docs/design/ui-baseline/README.md`](docs/design/ui-baseline/README.md). It covers
|
|
198
|
+
the system structure, Learning map / Current lesson surfaces, every route-page state
|
|
199
|
+
and the design constraints a new UI must keep.
|
|
200
|
+
|
|
201
|
+
## Diagnostics
|
|
202
|
+
|
|
203
|
+
Monitoring is local and content-free: no chat, goal, lesson or evidence text is
|
|
204
|
+
recorded, and nothing is sent anywhere.
|
|
205
|
+
|
|
206
|
+
```sh
|
|
207
|
+
pnpm doctor # human-readable health report
|
|
208
|
+
node scripts/doctor.mjs --json # machine-readable
|
|
209
|
+
node scripts/doctor.mjs --strict # exit 1 if an error-severity issue exists
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
It reads `<dsh-home>/storages/udt.json` plus the event journal and reports each
|
|
213
|
+
project's stage, pending/failed tutor requests (with age), stalled attempts and
|
|
214
|
+
route-length conflicts. The same report is available at
|
|
215
|
+
`GET /diagnostic-tutor/api/diagnostics` (loopback-only, like every plugin
|
|
216
|
+
route).
|
|
217
|
+
|
|
218
|
+
The host journal lives at `<dsh-home>/logs/diagnostic-tutor-events.jsonl`
|
|
219
|
+
(`DSH_DIAGNOSTIC_TUTOR_EVENTS` overrides the path, `off` disables it). It logs
|
|
220
|
+
lifecycle events only: tool names and operations, durations, request outcomes,
|
|
221
|
+
provider error messages (truncated). A single file is capped at 1 MB and
|
|
222
|
+
rotated once.
|
|
223
|
+
|
|
177
224
|
---
|
|
178
225
|
|
|
179
226
|
## Install
|
|
@@ -182,7 +229,7 @@ Rules this repository enforces mechanically:
|
|
|
182
229
|
|
|
183
230
|
| | |
|
|
184
231
|
| --- | --- |
|
|
185
|
-
| [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | verified against `0.2.1-rc.
|
|
232
|
+
| [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | verified against `0.2.1-rc.3` |
|
|
186
233
|
| the [Universal Diagnostic Tutor](https://github.com/SenmuuuuW/universal-diagnostic-tutor-skill) skill | the teaching brain. Without it the runtime loads, records and displays state, but **no lesson is ever written** |
|
|
187
234
|
| Node | `^22.19.0 \|\| >=24.0.0` |
|
|
188
235
|
|
|
@@ -234,7 +281,7 @@ learn?*.
|
|
|
234
281
|
|
|
235
282
|
```sh
|
|
236
283
|
npm pack
|
|
237
|
-
dsh plugin --profile web add "$PWD/dsh-diagnostic-tutor-0.
|
|
284
|
+
dsh plugin --profile web add "$PWD/dsh-diagnostic-tutor-0.2.0.tgz"
|
|
238
285
|
```
|
|
239
286
|
|
|
240
287
|
**What gets installed is prebuilt.** The package ships `lib/` — the host half
|
|
@@ -321,7 +368,7 @@ route around them:
|
|
|
321
368
|
|
|
322
369
|
### Tools
|
|
323
370
|
|
|
324
|
-
|
|
371
|
+
Eighteen. None of them decides anything about teaching; they record or report.
|
|
325
372
|
|
|
326
373
|
| Tool | Does |
|
|
327
374
|
| --- | --- |
|
|
@@ -329,8 +376,20 @@ Six, and none of them decides anything about teaching.
|
|
|
329
376
|
| `udt_goal_create` | records a goal and plants only the map root; may also select it for this conversation |
|
|
330
377
|
| `udt_map_get` | reads the selected project's map, or an explicitly named shared course, with each node's relation, state and evidence |
|
|
331
378
|
| `udt_map_update` | `add-nodes` · `set-state` · `add-evidence` |
|
|
332
|
-
| `udt_lesson_update` | writes teaching into the learning surface as blocks |
|
|
379
|
+
| `udt_lesson_update` | writes teaching into the learning surface as blocks; pre-renders math; attaches source citations |
|
|
380
|
+
| `udt_quiz_update` | records a quiz/flashcard submission; never grades and never changes node state |
|
|
333
381
|
| `udt_decide_next` | records where the learner should go next, and why |
|
|
382
|
+
| `udt_path_get` | reads the goal brief, assessment, routes and this conversation's active attempt |
|
|
383
|
+
| `udt_path_update` | saves a brief, assessment or route proposal |
|
|
384
|
+
| `udt_course_run_update` | binds a diagnosed node to an attempt, or completes with evidence |
|
|
385
|
+
| `udt_source_add` | stores pasted text or one explicitly named local `.md`/`.txt` file; deduplicates by SHA-256 |
|
|
386
|
+
| `udt_source_list` | lists source metadata without content |
|
|
387
|
+
| `udt_source_get` | returns one stored source for citation |
|
|
388
|
+
| `udt_plan_get` | reads the learner-owned Today plan |
|
|
389
|
+
| `udt_plan_update` | adds, completes or removes plan items; planning is policy, not teaching |
|
|
390
|
+
| `udt_review_add` | queues review cards; scheduling is policy, not mastery |
|
|
391
|
+
| `udt_review_next` | reads cards due now |
|
|
392
|
+
| `udt_review_grade` | records a review rating and reschedules; never confirms a node |
|
|
334
393
|
|
|
335
394
|
The division is the architecture: the tutor decides **what** to teach, when to
|
|
336
395
|
check, and what an answer showed; the runtime decides **what may be stored** and
|
|
@@ -404,20 +463,19 @@ the button means.
|
|
|
404
463
|
|
|
405
464
|
| Surface | Where | For |
|
|
406
465
|
| --- | --- | --- |
|
|
407
|
-
| **Learning
|
|
408
|
-
| **
|
|
409
|
-
|
|
410
|
-
The tab is the reason the loop is usable: the full panel fills the main column,
|
|
411
|
-
which is also where the conversation lives, so with only that panel answering a
|
|
412
|
-
check meant leaving the lesson. The right sidebar is a separate column.
|
|
466
|
+
| **Learning map** | the main column (`main`, key `diagnostic-tutor-map`) | browsing — course route, every lesson Overview, knowledge & evidence |
|
|
467
|
+
| **Current lesson** | the right sidebar tab, beside the chat | the lesson itself — teaching units, and checks answered in the chat |
|
|
413
468
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
469
|
+
One page for browsing, one surface for learning. The page never starts a lesson;
|
|
470
|
+
the tab never decides what to teach. Both read the same `useLearning` state and
|
|
471
|
+
the same path client, so they cannot disagree about what is focused, accepted or
|
|
472
|
+
written. **Open current lesson** on the map returns to the conversation with the
|
|
473
|
+
lesson tab open in the same step.
|
|
417
474
|
|
|
418
|
-
The
|
|
419
|
-
|
|
420
|
-
|
|
475
|
+
The container for the main column is the map page. A full-page lesson panel used
|
|
476
|
+
to exist as a second main destination; it was removed so the same lesson is not
|
|
477
|
+
offered in two places. The standalone full-page component is still used by the
|
|
478
|
+
preview and the tests, but the plugin does not register it.
|
|
421
479
|
|
|
422
480
|
### Teaching-brain detection
|
|
423
481
|
|
|
@@ -450,20 +508,76 @@ which judged an answer is *not finished* until the next step is recorded — so
|
|
|
450
508
|
the bridge was **deleted rather than kept as a second voice**. The plugin got
|
|
451
509
|
better at it, which is the evidence it belonged upstream.
|
|
452
510
|
|
|
453
|
-
## The
|
|
454
|
-
|
|
455
|
-
The browser half registers
|
|
456
|
-
(`sidebar.panellist`, a `list`)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
511
|
+
## The page and the lesson surface
|
|
512
|
+
|
|
513
|
+
The browser half registers three things: the **Learning map** icon in the
|
|
514
|
+
sidebar (`sidebar.panellist`, a `list`), the page it opens (`main`, a `keyed`
|
|
515
|
+
slot, key `diagnostic-tutor-map`), and the **Current lesson** tab in the right
|
|
516
|
+
sidebar (a tab type plus its body and title). The map's sidebar `id` and its
|
|
517
|
+
`main` key come from one constant — a drift between them would leave the icon
|
|
518
|
+
opening nothing.
|
|
519
|
+
|
|
520
|
+
The page has two tabs: **Course route** (the versioned plan, route canvas,
|
|
521
|
+
ordered lesson list and every Overview) and **Knowledge & evidence** (the
|
|
522
|
+
diagnosis map and its recorded observations). Neither one teaches: they show
|
|
523
|
+
stored state.
|
|
524
|
+
|
|
525
|
+
The route tab shows one stage at a time and one next step. A progress bar names
|
|
526
|
+
the four stages — goal & time, initial diagnosis, route, learning — and a
|
|
527
|
+
**Next step** card always answers "what now?" with a single primary action
|
|
528
|
+
(set the goal, request or answer the diagnosis, request the route, accept the
|
|
529
|
+
version, start the first lesson, continue the current one) plus at most one
|
|
530
|
+
real alternative. Competing action rows live in the folded history, not beside
|
|
531
|
+
it. Before a goal is saved the wizard owns the page; while the tutor is asking
|
|
532
|
+
diagnostic questions the card points back to the conversation, shows how long it
|
|
533
|
+
has waited, says whether the tutor is still thinking, and on a failed turn
|
|
534
|
+
retries with the current model and opens the chat (the failure is recorded on
|
|
535
|
+
the path request, so it survives a restart; provider errors are translated into
|
|
536
|
+
billing / auth / rate-limit / network / context advice); route versions
|
|
537
|
+
appear only after the diagnosis is complete or skipped; once accepted, the page
|
|
538
|
+
leads with the route canvas. A proposed or accepted route shows its total study
|
|
539
|
+
time, the weeks it takes at the saved weekly budget, and any lessons longer than
|
|
540
|
+
the preferred session. Next step moves to the first unfinished lesson after a
|
|
541
|
+
completion, and says when the whole route is done. Completed diagnosis details
|
|
542
|
+
and route settings stay reachable in folded sections.
|
|
543
|
+
|
|
544
|
+
The plugin's own accent is **DeepSeek's brand blue** — `#4d6bfe` on the light
|
|
545
|
+
canvas, `#6a84ff` on the dark one — used sparingly for progress, the active tab,
|
|
546
|
+
the current/selected item, focus rings and action links. Primary buttons keep the
|
|
547
|
+
host's near-black/white fill: the blue marks, it does not act. All other colours
|
|
548
|
+
continue to come from the host theme.
|
|
549
|
+
|
|
550
|
+
The initial diagnosis is asked through DSH's **interactive question card**
|
|
551
|
+
(`ask_user_question`) when the profile provides it: options are tapped rather
|
|
552
|
+
than typed, multi-select works, and a free-text question covers explanations.
|
|
553
|
+
The tutor still owns the questions, evidence and assessment; profiles without
|
|
554
|
+
that tool fall back to chat text.
|
|
555
|
+
|
|
556
|
+
The lesson lives in the docked tab, where the conversation is still on screen.
|
|
557
|
+
That is what makes the check loop work without leaving the lesson. The sidebar
|
|
558
|
+
action **Learn** opens that tab and never takes over the main column; the map's
|
|
559
|
+
**Open current lesson** button returns to the conversation and opens the same
|
|
560
|
+
tab.
|
|
461
561
|
|
|
462
562
|
```
|
|
463
|
-
|
|
563
|
+
sidebar Learn ─────────────▶ Current lesson (right sidebar)
|
|
564
|
+
sidebar Learning map ──────▶ Learning map (main column: route | knowledge)
|
|
565
|
+
|
|
566
|
+
Open current lesson ◀────── returns to chat + lesson tab
|
|
464
567
|
```
|
|
465
568
|
|
|
466
|
-
|
|
569
|
+
Entering learning follows the conversation, not the window. A project is
|
|
570
|
+
shared, but its focus and planned runs belong to a conversation, so the project
|
|
571
|
+
library and **Open current lesson** ask the host which conversation was last
|
|
572
|
+
learning the project (`GET /project/session`, read-only) and switch there with
|
|
573
|
+
the shell's session navigation when it differs. The order is: newest active
|
|
574
|
+
focus, then newest course run with an attempt, then newest project selection;
|
|
575
|
+
only a project no conversation has ever touched falls back to the conversation
|
|
576
|
+
on screen.
|
|
577
|
+
|
|
578
|
+
A full-page lesson panel used to exist as a second main destination. It was
|
|
579
|
+
removed: one page for browsing, one surface for learning, and the conversation
|
|
580
|
+
keeps the main column.
|
|
467
581
|
|
|
468
582
|
### Learning Blocks
|
|
469
583
|
|
|
@@ -473,25 +587,42 @@ keyed by `type`:
|
|
|
473
587
|
|
|
474
588
|
| Type | Content |
|
|
475
589
|
| --- | --- |
|
|
476
|
-
| `text` | `md` — markdown,
|
|
590
|
+
| `text` | `md` — markdown, plus host `math[]` fragments for typeset formulas |
|
|
477
591
|
| `example` | `title`, `steps[]`, `takeaway?` |
|
|
478
592
|
| `diagram` | `format` (`ascii` \| `mermaid`), `spec`, `caption?` |
|
|
479
593
|
| `check` | `prompt`, `expect?`, `hint?` — the stop-and-wait surface |
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
594
|
+
| `formula` | `tex`, `display?`, host-rendered `mathml`, `caption?` |
|
|
595
|
+
| `code` | `language?`, `source`, `caption?` — displayed, never executed |
|
|
596
|
+
| `quiz` | `title?`, `questions[]` (`mcq`/`short`); answers are recorded, never graded by the runtime |
|
|
597
|
+
| `flashcard` | `front`, `back`, `tags?`; self-report is recorded, not scheduled as mastery |
|
|
598
|
+
| `resource` | `title`, optional `sourceId`/`locator`/`url`/`note` |
|
|
599
|
+
| `comparison` | `columns[]`, `rows[][]`, `caption?` |
|
|
600
|
+
|
|
601
|
+
Blocks may also carry `sourceRefs: [{sourceId, locator}]`; every reference is
|
|
602
|
+
checked against the `sources` table at write time. The stored schema accepts an
|
|
603
|
+
**unknown type** from a newer host and the client renders a readable placeholder;
|
|
604
|
+
the current model tool still writes only known types.
|
|
605
|
+
The Learning map also shows a compact **Today** card when `udt_plan_update` has created open plan items, with a done action and an **Export calendar** action for dated items. DSH's own `schedule` is session-local, so this is an explicit calendar export rather than a push notification. Review cards and their local interval scheduler are stored but have no separate review surface yet.
|
|
485
606
|
|
|
486
607
|
### Browser API
|
|
487
608
|
|
|
488
|
-
|
|
609
|
+
The browser's core calls, at `/diagnostic-tutor/api` (the full route list is in
|
|
610
|
+
[the architecture notes](docs/planning/CURRENT-ARCHITECTURE.md)):
|
|
489
611
|
|
|
490
612
|
| Route | Returns |
|
|
491
613
|
| --- | --- |
|
|
492
614
|
| `GET /overview` | the current course and its whole map (`course: null` on a first run) |
|
|
493
615
|
| `GET /node?id=` | one node with its evidence, parent and children |
|
|
616
|
+
| `GET /project/session?courseId=` | the conversation that should resume a project (read-only) |
|
|
494
617
|
| `POST /lesson {nodeId}` | the prototype lesson, built once and reused after that |
|
|
618
|
+
| `GET /source?id=` | one stored source and its text, for a citation preview |
|
|
619
|
+
| `POST /path/answer` | record a quiz/flashcard submission on the active attempt |
|
|
620
|
+
| `GET /plan/ics` | download open, dated Today plan items as an ICS calendar |
|
|
621
|
+
| `GET /review` | due review cards (read-only) |
|
|
622
|
+
| `POST /review/grade` | record a review rating and reschedule |
|
|
623
|
+
| `POST /review/undo` | restore the previous schedule after the latest grade |
|
|
624
|
+
| `GET /insights?courseId=` | read-only course insight counts |
|
|
625
|
+
| `POST /plan/task` | mark a Today plan item done (learner action; plan only) |
|
|
495
626
|
|
|
496
627
|
Every request passes a **trust fence**: a bare `ctx.webServer.register()` route
|
|
497
628
|
inherits no authentication, so the route checks that the request arrived at a
|
|
@@ -499,6 +630,27 @@ loopback `Host`, from a loopback `Origin`, and is not marked cross-site. Anythin
|
|
|
499
630
|
else gets `403` and no body. The browser receives **views only** — no storage
|
|
500
631
|
path, no domain handle, no raw record.
|
|
501
632
|
|
|
633
|
+
### Interface language
|
|
634
|
+
|
|
635
|
+
Every plugin surface ships copy in **English and Simplified Chinese**: the
|
|
636
|
+
Learning map page, the course route, the docked Current-lesson tab, the
|
|
637
|
+
standalone full-page panel used by the preview and tests, and the shared
|
|
638
|
+
next-step card, handoff line and welcome row. The sidebar Learn action and its
|
|
639
|
+
missing-conversation explanation switch too. A toggle in the map header (and in
|
|
640
|
+
the lesson surfaces) changes the copy in place; the language is saved on the
|
|
641
|
+
learner profile (`preferredLanguage`, via `GET /preferences` and
|
|
642
|
+
`POST /preferences/language`), so it survives a restart and applies to every
|
|
643
|
+
conversation. The choice applies immediately and is saved in the background: a
|
|
644
|
+
failed request keeps the local choice rather than flipping the UI back.
|
|
645
|
+
|
|
646
|
+
It is copy, not content: the tutor's teaching, the learner's goal text, lesson
|
|
647
|
+
overviews, node titles and recorded evidence are never machine-translated, and
|
|
648
|
+
the model is not instructed to change language by the toggle. Three things stay
|
|
649
|
+
outside the switch: the **Learning map** sidebar label (registered once when the
|
|
650
|
+
plugin loads, so it cannot follow an in-place change), server/model error text
|
|
651
|
+
and dynamic handoff details as generated, and the development preview's own
|
|
652
|
+
toolbar.
|
|
653
|
+
|
|
502
654
|
## Preview
|
|
503
655
|
|
|
504
656
|
The panel takes its API as a prop, so the UI runs with no DSH and no agent:
|
|
@@ -522,8 +674,10 @@ Machine Learning [goal, unconfirmed]
|
|
|
522
674
|
|
|
523
675
|
Two query parameters reach the states that are otherwise awkward to produce on
|
|
524
676
|
demand — `?scenario=` (`first-use`, `map`, `handoff`, `next`, `stay`, `noskill`,
|
|
525
|
-
`long`, `scroll`, `library`, `new`
|
|
526
|
-
|
|
677
|
+
`long`, `scroll`, `library`, `new`, `showcase`, `curriculum`, `path-draft`,
|
|
678
|
+
`path-setup`, `path-assessment`) and `?surface=tab` / `?surface=map` for the
|
|
679
|
+
docked right-sidebar tab and the standalone map page. The scenario switch is in
|
|
680
|
+
the page's toolbar, and the theme toggle sets the same
|
|
527
681
|
`body[data-ds-dark-theme]` attribute DSH does. The page carries the real DSH
|
|
528
682
|
design tokens for the same reason: with hardcoded fallbacks in their place, a
|
|
529
683
|
token that resolves to near-white in dark mode looks perfectly fine locally.
|
|
@@ -566,15 +720,19 @@ What the surfaces look like now, captured from a live profile:
|
|
|
566
720
|
|
|
567
721
|
| | light | dark |
|
|
568
722
|
| --- | --- | --- |
|
|
569
|
-
|
|
|
723
|
+
| standalone panel (preview/tests only) |  |  |
|
|
570
724
|
| docked tab |  |  |
|
|
571
725
|
|
|
726
|
+
These captures predate the current layout: the standalone full-page panel is no
|
|
727
|
+
longer a product surface. Today the Learning map page owns the main column and
|
|
728
|
+
the Current lesson tab holds the teaching.
|
|
729
|
+
|
|
572
730
|
## Development
|
|
573
731
|
|
|
574
732
|
```sh
|
|
575
733
|
pnpm install
|
|
576
734
|
pnpm typecheck # tsc --noEmit (host and client)
|
|
577
|
-
pnpm test #
|
|
735
|
+
pnpm test # unit, guard, DOM, render, real composition
|
|
578
736
|
pnpm build # tsc -> lib/ (host) + tsdown -> lib/client.js
|
|
579
737
|
```
|
|
580
738
|
|
|
@@ -617,8 +775,10 @@ shows a loader row exists.
|
|
|
617
775
|
| `v0.0.10` | export and delete your data |
|
|
618
776
|
| `v0.0.11` | storage layout tested; `single` kept, with the reason |
|
|
619
777
|
| `v0.1.0-rc.1` | packaged install, no clone or build required |
|
|
620
|
-
| `v0.1.0` |
|
|
621
|
-
| `v0.
|
|
778
|
+
| `v0.1.0` | first stable release, installable from npm |
|
|
779
|
+
| `v0.1.1` | packaged release with the docked learning surface |
|
|
780
|
+
| `v0.2.0` | **published** — Phase 1–6 content/input/review loop, learning-path flow, Today/Review/Insights |
|
|
781
|
+
| next | settings, automatic replan suggestions (the tutor already proposes revisions on request; no runtime auto-replan) |
|
|
622
782
|
|
|
623
783
|
## Trust
|
|
624
784
|
|
|
@@ -626,7 +786,10 @@ DSH does not sandbox plugin code: an installed plugin runs in-process with your
|
|
|
626
786
|
privileges, and a bare `ctx.webServer.register()` route inherits no
|
|
627
787
|
authentication. This plugin's commitments:
|
|
628
788
|
|
|
629
|
-
- reads and writes only its own storage domain
|
|
789
|
+
- reads and writes only its own storage domain, with one explicit exception:
|
|
790
|
+
`udt_source_add(path)` reads exactly one regular `.md`/`.markdown`/`.txt` file
|
|
791
|
+
the caller names, once, then stores its text in that domain. It never scans a
|
|
792
|
+
directory, follows a symlink, accepts a URL, or fetches anything;
|
|
630
793
|
- serves its browser half only from loopback-fenced routes it checks itself;
|
|
631
794
|
- makes no outbound network requests;
|
|
632
795
|
- writes no files outside the harness's own storage;
|
|
@@ -727,4 +890,6 @@ MIT. The Universal Diagnostic Tutor skill is a separate MIT project by the same
|
|
|
727
890
|
author and is not vendored here.
|
|
728
891
|
|
|
729
892
|
Planning and architecture research for this project live in
|
|
730
|
-
[`docs/planning/`](docs/planning/).
|
|
893
|
+
[`docs/planning/`](docs/planning/). Phase 1–6 merge order, acceptance checks and the DSH compatibility checklist are in
|
|
894
|
+
[`docs/planning/PHASE-1-6-MERGE.md`](docs/planning/PHASE-1-6-MERGE.md). 0.2.0 发布清单与验证记录见
|
|
895
|
+
[`docs/planning/RELEASE-0.2.0.md`](docs/planning/RELEASE-0.2.0.md).
|