Commit Graph

311 Commits

Author SHA1 Message Date
hongjr03 a426490ae3 Merge pull request 'feat(cli): cph init / cph add 子命令' (#101) from feat/cph-init-add into main
Reviewed-on: EduCraft/curriculum-project-hub#101
2026-08-05 21:36:50 +08:00
hongjr03 5866b3d6cc feat(cli): cph init / cph add 子命令(工程脚手架)
init 生成可 check 的工程根(manifest.toml + .cph-version + 默认 exports/student.typ + 空 kind 目录);
add 按 kind 建 part 目录/element.toml/必填内容文件并追加 [[parts]]。均纯本地,不涉及 hub 语义;
Engine 改惰性构造。cph-schema 新增 required_content_field_names() 作为 add 建文件合同。
2026-08-05 21:22:26 +08:00
hongjr03 7a0b4b0c4f Merge pull request 'feat(cph): implement nested outline manifest and batch/combined export' (#96) from feat/adr-0029-0030-nested-manifest-export into main
Reviewed-on: EduCraft/curriculum-project-hub#96
2026-08-05 18:34:13 +08:00
hongjr03 3d46525f40 fix(cph): correct nested outline hierarchy 2026-08-05 18:34:05 +08:00
hongjr03 dd8fcfd366 chore(cph): track TH-141 outline PDF 2026-08-05 18:34:05 +08:00
hongjr03 fe8a17c6ad feat(cph): add outline export command 2026-08-05 18:34:05 +08:00
hongjr03 9927d38c18 feat(cph): implement nested outline manifest and batch/combined export
ADR-0029 — nested outline manifest, supersedes ADR-0008's flat [[parts]]:
- cph-model: recursive loader over manifest.toml containers / element.toml
  leaves; Lesson.parts (pure elements, DFS order) + Lesson.outline (elements
  interleaved with section headings at their DFS-open position); rejects
  ambiguous/incomplete folders and root-vs-container table misplacement
- cph-diag: new DiagCode::ManifestMalformed for carrier-document structure
  errors (discharges an existing TODO)
- cph-typst: augmented manifest now serializes the outline (element/section
  entries) instead of a flat parts array
- render/lib.typ: render-lesson renders section headings at their depth
- examples/TH-141 migrated to 5 nested section containers + 3 root segments,
  byte-identical element order; smoke-verified via cph check/build + pdftotext

ADR-0030 — batch & combined export, extends ADR-0009/0011:
- cph build with no --target batches every declared target (repeatable
  --target for an explicit subset); any target failure => non-zero exit,
  per-target ledger, independent per-target execution
- cph-model: bundle.toml loader (directory + [info]/[targets.*]/ordered
  lessons with per-lesson target overrides)
- cph-typst: augmented bundle manifest (path-prefixed member outlines),
  Engine::{compile_check_bundle,build_bundle_pdf}
- render/lib.typ: render-bundle assembles member lessons under per-lesson
  headings, depth-shifts their own section headings, resets example/lemma
  counters at each lesson boundary by default
- cph-cli: `cph bundle <path> --target <name>` subcommand, same batching
  contract as `cph build`
- new bundle fixtures/tests (cph-model unit + cph-typst through-template PDF
  compile), smoke-verified via a real 2-lesson merged PDF

Verification: cargo fmt/clippy/test clean across the workspace (68 tests);
real cph check/build/bundle runs against TH-141 and a bundle fixture, PDF
content inspected via pdftotext.
2026-08-05 18:34:05 +08:00
hongjr03 e0bd6120ec docs(adr): nested outline manifest and batch/combined export design
ADR-0029 supersedes ADR-0008's flat [[parts]] with a per-folder
manifest.toml outline tree (root = implicit top container, single
section container kind, DFS pre-order = lesson order).

ADR-0030 extends ADR-0009/0011: cph build batches all targets (any
failure => non-zero), cph bundle assembles ordered lessons into one
SingleFile/FileTree artifact (self-contained lessons, export-time
combination only).
2026-08-05 18:34:05 +08:00
hongjr03 66fc9516d9 Merge pull request 'fix(hub): clear npm audit high gate (deploy-admin CI)' (#98) from fix/hub-audit-production-vulns into main
Reviewed-on: EduCraft/curriculum-project-hub#98
2026-08-05 15:44:12 +08:00
hongjr03 9c5021f8ed fix(hub): bump transitive deps to clear npm audit high gate
npm audit --omit=dev --audit-level=high (audit:production, enforced in the
deploy-admin fleet workflow) was failing on high-severity advisories in
fast-uri (3.1.4) and ip-address (10.2.0), plus moderate hono and
@hono/node-server. All fixes resolve within existing ^ ranges, so a plain
npm audit fix regenerated the lock only (package.json untouched):
fast-uri 3.1.4 -> 3.1.5, ip-address 10.2.0 -> 10.4.0, hono 4.12.28 -> 4.13.0.
audit:production now reports 0 vulnerabilities.
2026-08-05 15:43:50 +08:00
hongjr03 6290b39c63 Merge pull request 'fix(admin-web): sync package-lock so fleet deploy npm ci succeeds' (#97) from fix/admin-web-lockfile-emnapi-sync into main
Reviewed-on: EduCraft/curriculum-project-hub#97
2026-08-05 15:26:27 +08:00
hongjr03 79734b5435 fix(admin-web): sync package-lock so fleet deploy npm ci succeeds
The wasm32-wasi optional native bindings (tailwindcss oxide, rolldown)
declare @emnapi/* ranges that now resolve to 1.11.3 / 1.2.3 on the
registry, but the committed lock still pinned the older .1/.2 patch
versions. npm ci (strict sync) therefore failed with EUSAGE, breaking
the deploy-admin fleet workflow. Regenerated the lock with
npm install --package-lock-only.
2026-08-05 15:25:09 +08:00
hongjr03 5754005a97 Merge pull request 'fix(admin-web): 创建项目后跳转修正为使用 projectId' (#43) from fix/admin-projects-redirect-undefined into main
Reviewed-on: EduCraft/curriculum-project-hub#43
2026-08-04 16:55:04 +08:00
ChickenPige0n 97313aba0f fix(admin-web): redirect to created project using projectId not id 2026-08-01 22:54:34 +08:00
hongjr03 cfe733554a Merge pull request 'feat(admin-web): skill zip import and folder-grouped role picker' (#41) from feat/upload-skill-zip into main
Reviewed-on: EduCraft/curriculum-project-hub#41
2026-07-31 20:25:09 +08:00
ChickenPige0n ff990b4caf feat(admin-web): skill zip import and folder-grouped role picker
- parse skill package zips client-side, mirroring backend ingestion limits (ADR-0018)
- add zip upload flow on skills page and zip replace in SkillEditor
- group role skill bindings by the shared management folder tree (ADR-0028)
- add fflate dependency
2026-07-31 15:41:42 +08:00
hongjr03 6ea8e33148 Merge pull request 'fix(hub): enable SDK auto-compact for resumed sessions' (#40) from fix/sdk-auto-compact into main
Reviewed-on: EduCraft/curriculum-project-hub#40
2026-07-30 17:13:15 +08:00
hongjr03 295f07d111 fix(hub): enable SDK auto-compact for resumed sessions
Sessions resume across runs (ADR-0017). Without auto-compact the SDK jsonl
grows unboundedly — a 7-day / 26-run session hit 31 MB / 1995 lines, making
every API call resend the full history and inflating a trivial "change a
title" task to 22 minutes. Enable autoCompactEnabled in the SDK settings so
the SDK compacts automatically when the context window fills.
2026-07-30 17:12:31 +08:00
hongjr03 e1da845bfc Merge pull request 'feat(hub): org-scoped agent role/skill folder tree (ADR-0028)' (#37) from feat/agent-config-folder-tree into main
Reviewed-on: EduCraft/curriculum-project-hub#37
2026-07-30 16:18:51 +08:00
hongjr03 ace724c609 fix(hub): always send interrupt notice when card finalize fails
If StreamingAgentCard.finish cannot patch the live card, plain-text fallback
can still succeed with partial answer text. Interrupt is terminal — always
emit the explicit 已中断 notice when the card path failed so teachers see the
abort. Harden the integration assertion with waitFor.
2026-07-30 15:02:08 +08:00
hongjr03 ee928b5832 fix(hub): restore project create payload and stabilize integration DB seed
Explorer POST /projects was dropping projectId/folderId/workspaceDir after a
narrowed response shape, breaking admin-explorer. Make seedTestOrganization
idempotent under shared-DB isolation, force single-worker vitest, and align the
OAuth no-membership redirect expectation with authRoutes.
2026-07-30 14:44:11 +08:00
hongjr03 0f4377f16c fix(hub): assert DB wipe and single-worker integration tests
Fail fast if TRUNCATE left Organization rows, drop the extra deleteMany
before seed create, and force vitest maxWorkers=1 so forks cannot race
the shared Postgres.
2026-07-30 14:24:05 +08:00
hongjr03 751d0c4100 fix(hub): harden test org seed and run hub-check only on push
seedTestOrganization now wipes+creates instead of fragile upsert.
hub-check drops pull_request triggers so push/PR pairs no longer double
migrate against the runner; branch push status remains the gate.
2026-07-30 14:05:22 +08:00
hongjr03 0ebfeb927a fix(ci): cancel concurrent hub-check runs on the same ref 2026-07-30 13:37:08 +08:00
hongjr03 4eafbf20a9 fix(hub): reset integration DB with TRUNCATE CASCADE
deleteMany could not reliably clear nested agent-config folders and left
ghost Organization rows that broke the next upsert. Truncate every public
table except _prisma_migrations before seeding the default org.
2026-07-30 13:28:42 +08:00
hongjr03 49e1e2f19e fix(hub): cascade agent-config folder parent deletes
parentId RESTRICT prevented Organization.deleteMany from clearing nested
folder trees during test resetDb, leaving half-wiped rows and breaking
subsequent upserts. Service still refuses non-empty folder deletes;
DB cascade only unblocks org teardown / full wipe.
2026-07-30 13:20:24 +08:00
hongjr03 9c1f9de9c1 fix(hub): give integration tests skill-store root and portable DB URL
Admin routes always construct OrganizationAgentConfiguration via
readSkillStoreRoot(); CI and local runs without HUB_SKILL_STORE_ROOT
failed open. Seed a tmp root when unset. Also make preflight CLI tests
honor DATABASE_URL and set the skill-store env in hub-check.
2026-07-30 13:12:08 +08:00
hongjr03 ac53d42a0a fix(hub): honor DATABASE_URL in integration test helpers
CI hub-check reaches Postgres as the service hostname `postgres`, but
helpers hard-coded 127.0.0.1:5432, so migrate ran against the service
while vitest connected to the wrong place. Prefer env when set.
2026-07-30 13:00:58 +08:00
hongjr03 e0e25ca4c5 fix(hub): expect always-on todo_write in pbank tool mapping 2026-07-30 12:51:48 +08:00
hongjr03 6ddc0b5bd1 fix(ci): skip live bwrap sandbox proof without unprivileged userns
Act/docker runners commonly block non-privileged user namespaces, so
setpriv+CapEff=0 cannot run bwrap. Gate the proof on `unshare --user`
and keep unit + remaining integration tests as the default CI net.
2026-07-30 12:44:41 +08:00
hongjr03 b91938071d fix(ci): enable unprivileged userns for hub-check bwrap 2026-07-30 12:38:11 +08:00
hongjr03 6f736abe50 fix(hub): assert sandbox skills by deny-list, not exact set
Claude SDK may report an extra host/doctor skill id even with
disableBundledSkills. Keep the ADR-0018 guarantee: managed outline
loads and workspace-local untrusted skills do not.
2026-07-30 12:31:33 +08:00
hongjr03 fdd83999df fix(ci): clear caps as root when switching sandbox uid 2026-07-30 12:24:12 +08:00
hongjr03 d4cd1ad74f fix(ci): drop caps after runuser without setgroups 2026-07-30 12:17:49 +08:00
hongjr03 315e4bd018 fix(ci): keep node/npx on PATH for unprivileged sandbox proof 2026-07-30 12:09:20 +08:00
hongjr03 3a46ebc54d fix(ci): run hub-check sandbox proof as unprivileged user
agent-sandbox-linux requires uid>0, CapEff=0, and NoNewPrivs=1. Act runners
often execute as root with residual caps; create cphci and drop privileges
via setpriv before vitest.
2026-07-30 12:09:02 +08:00
hongjr03 213f00eb07 fix(ci): install Rust in hub-check for shipping cph
hub-check builds cph via cargo install; the runner image has no rustup.
Mirror checker-check's dtolnay/rust-toolchain + cargo cache.
2026-07-30 12:02:49 +08:00
hongjr03 127a8c3418 fix(ci): install admin-web deps in hub-check before build
hub build runs admin:build; fleet deploy already npm ci --prefix admin-web
but hub-check only installed hub/. Without that, vite fails on @sveltejs/kit.
2026-07-30 11:58:02 +08:00
hongjr03 61512454cc fix(ci): use service DNS for hub-check Postgres (no host port)
Concurrent hub-check jobs raced on host-published 5432/15432. Drop the
host port mapping and talk to the service container as postgres:5432.
2026-07-30 11:47:44 +08:00
hongjr03 03142c75ea fix(ci): reach hub-check Postgres by service DNS
Concurrent hub-check jobs on the shared runner fought over published
host ports (5432 then 15432). Drop host port mapping and connect to the
service container as postgres:5432 on the job network.
2026-07-30 11:47:21 +08:00
hongjr03 46d6722254 fix(ci): restore hub-check postgres wait deadline 2026-07-30 11:46:18 +08:00
hongjr03 3a4b9e052a fix(ci): bind hub-check Postgres on host 15432
Runner host 5432 is already allocated (leftover containers), causing
hub-check service Postgres to fail start. Map service DB to 15432 and
point wait/integration DATABASE_URL at that port.
2026-07-30 11:45:36 +08:00
hongjr03 faafece1a4 ci: re-run hub-check after postgres flake 2026-07-30 11:42:18 +08:00
hongjr03 d7bbffb9c6 fix(hub): rebase agent config folders onto main and sync lockfile
Rebased feat/agent-config-folder-tree onto current main, keeping cursor
invalidation (not session archive) and requireFolder helpers. Regenerated
package-lock so npm ci finds @emnapi/*; tighten session-cursor test assert
for missing claudeSessionId key.
2026-07-30 11:37:34 +08:00
ChickenPige0n 6c8d2da897 feat(hub): add SearchableSelectField component and update RoleCard to use it 2026-07-30 11:36:28 +08:00
ChickenPige0n c9adf83e5c feat(hub): org-scoped agent role/skill folder tree (ADR-0028)
Add a shared transparent OrganizationAgentConfigFolder tree for grouping
agent roles and skills in the admin UI without affecting identity, bindings,
run loading, or slash commands.
2026-07-30 11:36:27 +08:00
hongjr03 db7b7ec094 Merge pull request 'fix(hub): download Feishu resources via bot-owned lark-cli' (#39) from fix/feishu-bot-cli-download into main 2026-07-30 11:28:09 +08:00
hongjr03 88386fb943 fix(hub): download Feishu resources via bot-owned lark-cli
Agent tool downloads and trigger attachment staging both used the SDK
messageResource path, which fails closed for multi-MB teacher files and
did not share the bot-identity transport contract. Route every download
through Hub-owned createFeishuBotCli (secret via stdin, disposable HOME,
HUB_FEISHU_CLI_BIN), keep workspace containment on write, and inject the
adapter in trigger tests.
2026-07-30 11:27:53 +08:00
hongjr03 97c7054529 Merge pull request 'fix(hub): raise Docmind OSS upload timeout past httpx 3s default' (#38) from fix/docmind-oss-upload-timeout into main 2026-07-30 11:17:25 +08:00
hongjr03 97a99cd381 fix(hub): raise Docmind OSS upload timeout past httpx 3s default
SubmitDocParserJobAdvance uploads PDFs to Aliyun OSS via tea/httpx, which
defaults readTimeout to 3000ms when RuntimeOptions is empty. Multi-MB
teacher PDFs on para silo failed with ReadTimeout(3000) before the job
could start. Set connectTimeout=15s and readTimeout=5m.
2026-07-30 11:16:56 +08:00