cert-coach-web 0.1.0 → 0.1.2
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/AGENTS.md +4 -2
- package/README.md +15 -4
- package/engine/core/cert-core.mjs +6 -1
- package/engine/extractor.js +1 -1
- package/engine/scripts/export_private.ps1 +8 -6
- package/package.json +4 -3
- package/web/public/app.js +77 -1013
- package/web/public/index.html +1 -1
- package/web/public/spa-api.js +33 -0
- package/web/public/spa-chat.js +181 -0
- package/web/public/spa-dom.js +89 -0
- package/web/public/spa-logic.js +20 -0
- package/web/public/spa-mermaid.js +54 -0
- package/web/public/spa-question.js +206 -0
- package/web/public/spa-render.js +107 -0
- package/web/public/spa-store.js +100 -0
- package/web/public/spa-ui.js +62 -0
- package/web/public/spa-views.js +279 -0
- package/web/public/styles.css +1 -0
- package/web/server/chat.mjs +74 -4
- package/web/server/http.mjs +7 -2
package/AGENTS.md
CHANGED
|
@@ -54,7 +54,9 @@ Load the extension: `pi --extension ./.pi/extensions/cert-coach.ts`.
|
|
|
54
54
|
|
|
55
55
|
## Current certs
|
|
56
56
|
|
|
57
|
-
- `DP600/` — Microsoft Fabric Analytics Engineer (DP-600). Blueprint verified 2026-10-21 (skills measured 2026-10-19). Bank: 117 items, 74 gradeable, 110 verified (
|
|
58
|
-
- `PL300/` — Microsoft Power BI Data Analyst (PL-300).
|
|
57
|
+
- `DP600/` — Microsoft Fabric Analytics Engineer (DP-600). Blueprint verified 2026-10-21 (skills measured 2026-10-19). Bank: 117 items, 74 gradeable, 110 verified (105 confirmed, 5 corrected), 7 unverifiable, 0 pending; all 16 authored gap questions human-reviewed. Free half: 21/43 pages. `DP600/theory.md` is a manual `DEEP_PASS`. Direct Lake on OneLake has **no** DirectQuery fallback; only the SQL analytics endpoint variant does.
|
|
58
|
+
- `PL300/` — Microsoft Power BI Data Analyst (PL-300). Current **four** domains (25–30/25–30/25–30/15–20). Bank: 234 items, 155 gradeable, 231 verified (230 confirmed, 1 corrected), 3 unverifiable, 0 pending. Free half 47/95 pages.
|
|
59
|
+
- `DATABRICKSDA/` — Databricks Certified Data Analyst Associate (DA-ASSOC, 45 MCQ / 90 min). Blueprint verified 2026-10-26: nine domains 11/8/5/20/15/16/12/5/8. **Dump ingested, verified, and gap-filled 2026-10-26**: bank **106 items, 91 gradeable, all answer-verified** (88 confirmed · 3 corrected · 15 unverifiable), **0 pending**, **0 unmapped**; **36-node DAG, all 36 used**, a hands-on `lab` per node, thin-bank gate `minCoverage: 0.5`. Every domain is now within ~±5 pts of blueprint share. 10 items are medium confidence — a targeted docs pass would firm them up. Note: docs have rebranded Delta Sharing → **OpenSharing** and Genie → a family (Genie One / Genie Agents / Genie Code); stems use exam-era wording, keywords carry both.
|
|
60
|
+
- `SAPC02/` — AWS Certified Solutions Architect – Professional (SAP-C02: 75 questions delivered = 65 scored + 10 unscored, 180 min, pass 750/1000, $300, 3-yr). Blueprint **fetched and verified 2026-10-26**: four domains 26/29/25/20. Bootstrap starter bank: 20 gradeable scenario items (all doc-verified), 31-node DAG with a hands-on AWS `lab` per node, thin-bank gate `minCoverage: 0.5`. Scenario/trade-off exam; Domain 2 is heaviest (genAI/Bedrock, event-driven, Control Tower), and scored content is 65 — not 75. ⚠️ **SAP-C02 last test day 2026-11-16; SAP-C03 registration opens 2026-10-27** (`cert_meta.lifecycle`) — confirm the booked version. Dump still to ingest.
|
|
59
61
|
|
|
60
62
|
Do not trust counts written in prose; `cert_status` and `validate.mjs` are the source of truth.
|
package/README.md
CHANGED
|
@@ -23,9 +23,10 @@ Counts are live in `progress.json` / `/api/status`; this is a snapshot.
|
|
|
23
23
|
|---|---:|---:|---|---:|
|
|
24
24
|
| **DP-600** | 117 | 74 | 105 confirmed · 5 corrected · 7 unverifiable · 0 pending | 22% |
|
|
25
25
|
| **PL-300** | 234 | 155 | 230 confirmed · 1 corrected · 3 unverifiable · 0 pending | 23% |
|
|
26
|
+
| **Databricks DA** | 24 | 24 | 24 confirmed · 0 corrected · 0 unverifiable · 0 pending | bootstrap |
|
|
26
27
|
|
|
27
28
|
- **Works today:** TUI (`cert_*` tools) + web console (Study, Path, Dashboard, Theory, Logs, teaching chat), Chat v2 (read + research + verify), full mock, live Mermaid, browser cert scaffold, `pi` auto-install, OpenRouter free-model config.
|
|
28
|
-
- **Green:**
|
|
29
|
+
- **Green:** 67 tests, both certs `validate` PASS, `npm pack` 64 files / no banks.
|
|
29
30
|
- **Next:** npm publish; generated-question review; optional extension slimming.
|
|
30
31
|
|
|
31
32
|
## Quickstart
|
|
@@ -187,9 +188,16 @@ engine/ the pure cert engine (no pi/web coupling)
|
|
|
187
188
|
run-script.mjs cert_run runner (no pi dependency)
|
|
188
189
|
server/ web console server (server-owned StudyLoop, SSE, auth)
|
|
189
190
|
public/ study SPA (Study, Path, Dashboard, Theory, Logs, chat)
|
|
191
|
+
app.js wiring: boot, fetch, submit/next, events, listeners
|
|
192
|
+
spa-dom.js spa-store.js element handles + session store (+ pure helpers)
|
|
193
|
+
spa-question.js question/feedback/teach/mock cards and the timer
|
|
194
|
+
spa-chat.js teaching chat: log, streaming, tool cards
|
|
195
|
+
spa-views.js Path, Dashboard, Theory, Logs, command strip
|
|
196
|
+
spa-ui.js spa-api.js leaf helpers (notice/layout/log) and the fetch wrapper
|
|
197
|
+
spa-logic.js spa-render.js spa-mermaid.js URL guards, markdown, Mermaid
|
|
190
198
|
bin/ web console entry point
|
|
191
199
|
tests/ deterministic core/server/web/chat/mock tests
|
|
192
|
-
DP600/ PL300/
|
|
200
|
+
DP600/ PL300/ DATABRICKSDA/ SAPC02/ internal data (shareable as-is; progress.json is owner-only)
|
|
193
201
|
```
|
|
194
202
|
|
|
195
203
|
## Move your own workspace to another PC
|
|
@@ -200,7 +208,8 @@ For a private move (your own second machine), use the archive script:
|
|
|
200
208
|
powershell -ExecutionPolicy Bypass -File engine/scripts/export_private.ps1
|
|
201
209
|
```
|
|
202
210
|
|
|
203
|
-
It writes a zip to your Desktop containing the engine **and** `DP600/`, `PL300
|
|
211
|
+
It writes a zip to your Desktop containing the engine **and** `DP600/`, `PL300/`,
|
|
212
|
+
`DATABRICKSDA/`, `SAPC02/`
|
|
204
213
|
including `raw/`, verified `bank.json`, and `vision_assets/`. Progress is reset
|
|
205
214
|
in the archive and study logs are removed by default. Page state (`.cert-coach/`)
|
|
206
215
|
and `node_modules/` are excluded. Use `-KeepProgress` to include attempts/history.
|
|
@@ -260,6 +269,8 @@ npm run test:e2e:real
|
|
|
260
269
|
|
|
261
270
|
The Chrome test checks question render, no key before submit, feedback, Next, Path, and chat/tool cards. Playwright uses the installed Chrome channel. The header **+ New** button scaffolds a workspace from the browser; research and ingest still run through the agent (see `BROWSER_CERT_CREATION.md`).
|
|
262
271
|
|
|
272
|
+
Long chat sessions are compacted automatically so a small-context model never dies mid-study. After **12 learner turns** the server starts a fresh pi session and carries a recap of the earlier questions forward; if the model reports a context-limit error anyway, the same compaction happens on the spot and the chat keeps working. Tune the threshold with `CERT_COACH_CHAT_MAX_TURNS` (or `maxTurns` on `ChatBridge`). The chat log shows a dashed *session compacted* line when it happens.
|
|
273
|
+
|
|
263
274
|
Mock: choose **10 / 20 / 65 questions** and **untimed / 90 / 130 minutes** before starting. The summary is isolated from `progress.json`.
|
|
264
275
|
|
|
265
276
|
Mermaid fences in agent chat/theory now render as live diagrams via a local `public/vendor/mermaid.min.js`.
|
|
@@ -317,5 +328,5 @@ Pi: `cert_setup`, `cert_status`, `cert_ask`, `cert_next`, `cert_answer`, `cert_v
|
|
|
317
328
|
- **DP-600:** 74/74 gradeable items verified; ledger 117 items (105 confirmed, 5 corrected, 7 unverifiable, 0 pending). Free half only (21/43 pages) — full coverage needs a paid account and `MAX_PAGES`.
|
|
318
329
|
- **PL-300:** 155/155 gradeable items verified; ledger 234 items (230 confirmed, 1 corrected, 3 unverifiable, 0 pending). Free half (47/95 pages). `manage_secure` is ~14.5% of the bank vs the 15–20% blueprint.
|
|
319
330
|
- **Image items are not lost.** 42 DP-600 / 79 PL-300 items depend on exhibits or code images. They are marked `needs_vision` with asset URLs; a vision pass can recover them.
|
|
320
|
-
- **Data is internal-shareable, as-is.** `DP600
|
|
331
|
+
- **Data is internal-shareable, as-is.** `DP600/`, `PL300/`, `DATABRICKSDA/`, and `SAPC02/` (banks, `raw/`, `vision_assets/`) ship in the *internal* package only, never the public npm tarball. Scraping is still subject to the source site's terms, so keep the internal export inside your org. `progress.json` is owner-only and reset on export.
|
|
321
332
|
- **The extension is pi-only.** The portable protocol is the certification-coach skill; the deterministic state layer requires pi.
|
|
@@ -143,12 +143,17 @@ export function computeReadiness(c) {
|
|
|
143
143
|
const gradeable = c.bank.filter((q) => q.gradeable).length || 1;
|
|
144
144
|
const seen = Object.values(by).reduce((a, b) => a + b.seen, 0);
|
|
145
145
|
const coverage = seen / gradeable;
|
|
146
|
-
const
|
|
146
|
+
const gate = c.meta.readiness || {};
|
|
147
|
+
const minAccuracy = Number.isFinite(gate.minAccuracy) ? gate.minAccuracy : 0.85;
|
|
148
|
+
const minCoverage = Number.isFinite(gate.minCoverage) ? gate.minCoverage : 0.8;
|
|
149
|
+
const label =
|
|
150
|
+
value >= minAccuracy && coverage >= minCoverage ? "ready" : value >= 0.65 ? "borderline" : "not_ready";
|
|
147
151
|
c.progress.readiness = {
|
|
148
152
|
method: "blueprint_weighted_last_answer_accuracy",
|
|
149
153
|
value: Number(value.toFixed(4)),
|
|
150
154
|
label,
|
|
151
155
|
coverage: Number(coverage.toFixed(4)),
|
|
156
|
+
gate: { minAccuracy, minCoverage },
|
|
152
157
|
by_domain: Object.fromEntries(
|
|
153
158
|
Object.entries(by).map(([k, v]) => [k, { ...v, accuracy: v.seen ? Number((v.lastCorrect / v.seen).toFixed(3)) : null }])
|
|
154
159
|
),
|
package/engine/extractor.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
30
30
|
|
|
31
31
|
function detectCert() {
|
|
32
|
-
if (INJECTED_CERT && INJECTED_CERT
|
|
32
|
+
if (INJECTED_CERT && !INJECTED_CERT.includes("{")) return INJECTED_CERT;
|
|
33
33
|
if (window.CERT_CODE) return window.CERT_CODE;
|
|
34
34
|
const text = `${location.href} ${document.title} ${document.body?.innerText?.slice(0, 4000) || ""}`;
|
|
35
35
|
const m = text.match(/\b([A-Z]{2,4}-\d{3})\b/);
|
|
@@ -17,10 +17,9 @@ if (Test-Path $stage) { Remove-Item $stage -Recurse -Force }
|
|
|
17
17
|
New-Item -ItemType Directory -Force $stage | Out-Null
|
|
18
18
|
|
|
19
19
|
$items = @(
|
|
20
|
-
"AGENTS.md", "README.md", ".
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"DP600", "PL300"
|
|
20
|
+
"AGENTS.md", "README.md", "EERO_PORT.md", "BROWSER_CERT_CREATION.md", "LICENSE", "package.json",
|
|
21
|
+
".pi", "engine", "web", "tests",
|
|
22
|
+
"DP600", "PL300", "DATABRICKSDA"
|
|
24
23
|
)
|
|
25
24
|
foreach ($item in $items) {
|
|
26
25
|
$src = Join-Path $Repo $item
|
|
@@ -28,10 +27,13 @@ foreach ($item in $items) {
|
|
|
28
27
|
Copy-Item $src (Join-Path $stage $item) -Recurse -Force
|
|
29
28
|
}
|
|
30
29
|
}
|
|
30
|
+
# Never ship dependencies; they are reinstalled on the other PC.
|
|
31
|
+
Get-ChildItem $stage -Recurse -Directory -Filter "node_modules" -ErrorAction SilentlyContinue |
|
|
32
|
+
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
|
31
33
|
|
|
32
34
|
# Reset learner state in the archive (not in the real workspace) unless asked.
|
|
33
35
|
if (-not $KeepProgress) {
|
|
34
|
-
foreach ($cert in @("DP600", "PL300")) {
|
|
36
|
+
foreach ($cert in @("DP600", "PL300", "DATABRICKSDA")) {
|
|
35
37
|
$certDir = Join-Path $stage $cert
|
|
36
38
|
if (-not (Test-Path $certDir)) { continue }
|
|
37
39
|
$metaPath = Join-Path $certDir "cert_meta.json"
|
|
@@ -80,7 +82,7 @@ if (-not $KeepProgress) {
|
|
|
80
82
|
@"
|
|
81
83
|
PRIVATE CERT COACH WORKSPACE — DO NOT REDISTRIBUTE
|
|
82
84
|
|
|
83
|
-
This archive includes the engine plus DP600
|
|
85
|
+
This archive includes the engine plus DP600, PL300, and DATABRICKSDA cert data (raw dumps,
|
|
84
86
|
verified banks, vision assets). Progress is reset; study logs are removed.
|
|
85
87
|
|
|
86
88
|
On the other PC:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cert-coach-web",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Local web study console for a pi certification coach: server-owned quiz loop, images, and teaching chat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"start": "node web/server/main.mjs",
|
|
15
|
-
"test": "node --test tests/core.test.mjs tests/server.test.mjs tests/web.test.mjs tests/chat.test.mjs tests/mock.test.mjs",
|
|
15
|
+
"test": "node --test tests/core.test.mjs tests/server.test.mjs tests/web.test.mjs tests/chat.test.mjs tests/mock.test.mjs tests/spa.test.mjs tests/spa-store.test.mjs tests/spa-render.test.mjs tests/ingest.test.mjs tests/validate.test.mjs tests/extractor.test.mjs",
|
|
16
16
|
"pack:check": "npm pack --dry-run",
|
|
17
17
|
"test:e2e:chrome": "node tests/e2e-chrome.mjs",
|
|
18
18
|
"test:package": "node tests/package-smoke.mjs",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"access": "public"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@playwright/test": "^1.64.1"
|
|
67
|
+
"@playwright/test": "^1.64.1",
|
|
68
|
+
"jsdom": "^30.1.3"
|
|
68
69
|
}
|
|
69
70
|
}
|