Commit Graph

245 Commits

Author SHA1 Message Date
hongjr03 ceaf64c4f9 Merge pull request 'fix(hub): expose TodoWrite via SDK default toolset' (#26) from fix/todowrite-default-toolset into main 2026-07-23 22:56:28 +08:00
hongjr03 bb426dfaf5 fix(hub): expose TodoWrite via SDK default toolset
Unrestricted roles were still passed an explicit --tools name list. The
native Claude binary only reliably registers bundled tools like TodoWrite
on --tools default. Treat role tools JSON null as unrestricted, use the
claude_code preset (→ default) in that case, and keep TodoWrite on allowedTools.
2026-07-23 22:56:26 +08:00
hongjr03 b4fe734e80 Merge pull request 'feat(hub): live TodoWrite checklist on Feishu agent cards' (#25) from feat/agent-todo-progress-card into main 2026-07-23 22:42:54 +08:00
hongjr03 2f79b7743f feat(hub): live TodoWrite checklist on Feishu agent cards
Always expose Claude Agent SDK TodoWrite (todoFeatureEnabled) so multi-step
runs can plan in the open. Parse TodoWrite payloads into a progress panel on
the streaming Feishu card (completed/in_progress/pending) and filter raw
TodoWrite noise out of the tool-use list.
2026-07-23 22:42:02 +08:00
hongjr03 4a03bc1f4a Merge pull request 'fix(hub): extract PBank zips in-process without host unzip' (#24) from fix/pbank-pure-node-unzip into main 2026-07-23 21:05:26 +08:00
hongjr03 8a81c60ea5 fix(hub): extract PBank zips in-process without host unzip
pbank materialize previously shelled out to `unzip` and soft-failed when
the binary was missing, so agents only saw titles. Read zip entries with
Node zlib (store/deflate) and write under workspace .pbank-sources.
2026-07-23 21:05:15 +08:00
hongjr03 00f7a8db39 Merge pull request 'feat(hub): built-in PBank 题库 capability + role tools (v0.0.42)' (#23) from feat/hub-pbank-capability into main 2026-07-23 20:13:19 +08:00
hongjr03 54837717fd feat(hub): built-in PBank 题库 capability + role tools (v0.0.42)
Register pbank as an ADR-0027 external capability with org-scoped
username/password envelopes, readiness via /login, and in-process
cph_hub MCP tools (search/get/get_many) that materialize sources under
the run workspace. Extend the capability secret payload for docmind vs
pbank kinds, admin capabilities UI, role tool umbrella `pbank`, and the
pbank-problem-report skill. Credentials never reach the Agent process.
2026-07-23 20:13:00 +08:00
hongjr03 2285ae871e Merge pull request 'fix(hub): enable tenant Typst package resolution' (#22) from fix/tenant-typst-package-resolution into main
Reviewed-on: EduCraft/curriculum-project-hub#22
2026-07-22 17:50:55 +08:00
hongjr03 36660f72d6 fix(hub): enable tenant Typst package resolution 2026-07-22 17:47:56 +08:00
hongjr03 6462e42823 fix(hub): stamp CheckMark/CrossMark when agent run finishes (v0.0.41) (#21) 2026-07-21 14:36:21 +08:00
hongjr03 6f7497bce8 fix(hub): stamp CheckMark/CrossMark when agent run finishes (v0.0.41)
After removing the Typing reaction, add CheckMark on success or CrossMark
on failure so teachers can see completion on the source message without
opening the card.
2026-07-21 06:36:09 +00:00
hongjr03 e634418a02 feat(hub): concurrent multi-PDF convert_pdf_to_md + readable skills (v0.0.40) (#20) 2026-07-21 13:56:10 +08:00
hongjr03 db49a0d23d feat(hub): concurrent multi-PDF convert_pdf_to_md + readable skills (v0.0.40)
Teachers convert many PDFs in one tool call with bounded Docmind concurrency.
Each item keeps its own output_dir/document.md and UsageFact; failures are
per-file. Mirror role skills to .cph/runtime-skills and CPH_RUNTIME_SKILLS_DIR
so agents can Read SKILL.md instead of dead .claude/sandbox stubs.
2026-07-21 05:55:55 +00:00
hongjr03 54b9fee22c fix(hub): agent 会话记忆在配置变更/发版后丢失 + Feishu thread 400 (#19)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-20 22:45:42 +08:00
hongjr03 5f668d71a2 fix(hub): forward host HTTP_PROXY into agent sandbox (v0.0.39) (#18) 2026-07-20 21:46:09 +08:00
hongjr03 3fbc4b81c2 fix(hub): forward host HTTP(S)_PROXY into agent sandbox (v0.0.39)
Host egress requires the local forward proxy; sandbox env previously
omitted PROXY vars so Bash/curl timed out on public image URLs. Pass
HTTP(S)/ALL/NO_PROXY (+ lowercase) and NODE_USE_ENV_PROXY from the
trusted service environment into the agent subprocess.
2026-07-20 13:46:07 +00:00
hongjr03 e016564cc5 feat(hub): raise agent limits + teacher failure notices (v0.0.38) (#17) 2026-07-20 20:07:47 +08:00
hongjr03 6cefb2a938 feat(hub): raise agent turns/time limits and notify teachers on failure
Defaults and silo env go to 150 turns / 1800s wall clock. Run completion
appends a clear Feishu notice for max-turns, timeout, and other failures
(partial answer kept). Startup process-restart kills notify the bound chat.
Release v0.0.38.
2026-07-20 12:07:45 +00:00
hongjr03 34c4908237 chore(hub): default HUB_MAX_FILES_PER_MESSAGE to 20 (#16) 2026-07-20 19:50:47 +08:00
hongjr03 46687dd5f6 chore(hub): default HUB_MAX_FILES_PER_MESSAGE to 20
Match production silos (raised for multi-image Feishu posts).
2026-07-20 11:50:45 +00:00
hongjr03 e9b578153e fix(hub): strip card markdown images + prefer inline ![] over send_file (v0.0.37) (#15)
fix card inline images v0.0.37
2026-07-20 19:39:08 +08:00
hongjr03 93f3f2424c fix(hub): strip card markdown images + prefer inline ![] over send_file
Feishu interactive markdown rejects ![](http...) without image_key
(error 230099 empty/missing imagekey). Always mask residual image md in
card builders; skip img tags with empty keys; skip inline-code examples;
fetch remote images with a browser UA and without env HTTP_PROXY.
Steer the agent: use ![alt](workspace-path) for 图文, send_file only for
downloadable attachments.

Release v0.0.37.
2026-07-20 11:38:55 +00:00
hongjr03 73cb0e5b47 feat(hub): embed agent images via Feishu upload + release v0.0.36 (#14)
feat(hub): embed agent images via Feishu upload + release v0.0.36

Merge pull request #14
2026-07-20 18:42:38 +08:00
hongjr03 e21096c642 feat(hub): embed agent images via Feishu upload + release v0.0.36
Materialize markdown image refs on agent finish: fetch/read bytes, upload
im.v1.image, and render native card img elements so remote image URLs no
longer trip Feishu content-security. Stream masks image URLs mid-run;
card failure falls back to plain text plus standalone image messages.

Docs: clarify im:resource covers outbound Agent image send.
2026-07-20 10:40:03 +00:00
hongjr03 dc2d1c2f9e Merge pull request 'chore: remove Lean spec; ADRs are the single source of truth' (#13) from chore/remove-lean-spec into main
Reviewed-on: EduCraft/curriculum-project-hub#13
2026-07-20 17:21:14 +08:00
hongjr03 3f9b60f692 chore: remove Lean spec; ADRs are the single source of truth
The spec/ Lean semantic master had no conformance gate, no codegen, and
no CI tie to implementations — alignment was carried entirely by human
review, the same mechanism that carries the ADRs. In practice the ADRs
plus greppable code comments were already the load-bearing artifacts,
so spec/ was the most expensive kind of stale documentation.

- delete spec/ and the spec-check CI workflow
- README: constitution rewritten around ADRs as decision truth
- AGENTS.md/CLAUDE.md: discipline re-anchored (new decisions -> new ADR,
  never rewrite ADR history; supersede instead)
- code comments: re-anchor 'Mirrors Spec.X' invariants to ADR numbers
  (cph-diag, cph-check, cph-model, hub runner/capacity/org, prisma)
- leave ADR bodies and .scratch audit snapshots untouched (history);
  fix live references in open readiness tickets
2026-07-20 09:07:26 +00:00
hongjr03 4234ba4c96 Merge pull request 'fix(hub): mark bootstrap Inbox as SYSTEM_INBOX' (#12) from fix/hub-bootstrap-system-inbox into main 2026-07-19 20:16:09 +08:00
hongjr03 15f9443d3d fix(hub): mark bootstrap Inbox as SYSTEM_INBOX
Alpha silo bootstrap created the root Inbox without kind=SYSTEM_INBOX, so
Feishu card project creation tried to insert a second Inbox and hit the
sibling-name unique index. Tag the bootstrap folder correctly and promote
any legacy root Inbox on ensure.
2026-07-19 20:08:44 +08:00
hongjr03 7f09fb1f13 feat(hub): drop redundant /admin/org/:slug path + release v0.0.35 (#11)
Silo hostname already carries tenancy. Admin SPA routes become /admin/..., legacy bookmarks redirect, login lands on /admin.

Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
v0.0.35
2026-07-19 01:36:10 +08:00
hongjr03 eb0be43eac feat(hub): usage fact breakdown API + admin usage/session UI + release v0.0.34 (#10)
Expose UsageFact kind/capability rollups on org and project usage reports, and add admin pages that separate model tokens from external-capability meters.

Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
v0.0.34
2026-07-19 01:19:59 +08:00
hongjr03 ce18740870 feat(hub): expose pdf_to_md_bundle as MCP tool to agent + skill (ADR-0027) (#9)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 21:43:00 +08:00
hongjr03 ef96f8d33d feat(hub): capability connection admin API + UI + release v0.0.32 (#8)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 17:57:04 +08:00
hongjr03 5e10419fc8 fix(hub): docmind client stream upload + correct API response parsing (#7)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 17:26:11 +08:00
hongjr03 64b3d1fc64 feat(hub): switch capability provider to Aliyun Doc Mind (ADR-0027) (#6)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 16:42:42 +08:00
hongjr03 b673dd1fe9 feat(hub): external capability registry for PDF/ASR transforms (ADR-0027) (#5)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 15:55:02 +08:00
hongjr03 aaa098bb8b feat(hub): usage fact ledger for run-scoped cost attribution (ADR-0026) (#4)
Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 14:46:41 +08:00
hongjr03 97f7972cc5 chore(hub): remove markdown_to_pdf tool (#3)
Drop markdown_to_pdf MCP surface, implementation, tests, and md-to-pdf dependency.

Roles that still list markdown_to_pdf must be cleaned before startup.

Co-authored-by: Hong Jiarong <me@jrhim.com>
Co-committed-by: Hong Jiarong <me@jrhim.com>
2026-07-18 13:57:27 +08:00
hongjr03 cc42e6a7c6 chore: release v0.0.31 2026-07-18 13:38:07 +08:00
hongjr03 4e01c18cac feat(hub): add markdown_to_pdf tool and default web tools
Teachers need ad-hoc Markdown → PDF. Ship an MCP tool powered by
md-to-pdf (Marked + headless Chrome) so remote images/CSS work, with
workspace-scoped basedir, front-matter stripped so untrusted markdown
cannot override dest/basedir/launch options, and MathJax for $/$ math.

Also include WebFetch and WebSearch in the unrestricted role tool
surface by default. Deploy skips Puppeteer's browser download and
expects a host Chrome/Chromium (PUPPETEER_EXECUTABLE_PATH / CHROME_PATH).
2026-07-18 13:38:07 +08:00
ChickenPige0n a12984d174 feat(admin-web): add folder and project creation functionality in FolderNode and FolderTree components 2026-07-18 12:32:45 +08:00
hongjr03 b93acd8e8c chore: release v0.0.30 2026-07-16 01:26:28 +08:00
hongjr03 35251986af feat(hub): derive admin model picker from org provider connection via OpenRouter API
The admin role model picker was hardcoded to the env-default model registry
(createDefaultModelRegistry), which only ever returned a single Sonnet model.
Roles could not select any other model regardless of what the org's provider
connection supported.

Replace the env-only model list with a ProviderModelCatalog that:
- Resolves the org's ACTIVE provider connection credential (BYOK or
  platform-managed, encrypted via ADR-0024 envelope)
- Calls OpenRouter GET /v1/models?supported_parameters=tools to list
  tool-capable models available to that org
- Caches results in-memory with a 5-minute TTL per organization
- Falls back to the env-default registry when no ACTIVE provider exists

The runtime modelRegistry no longer validates role.defaultModel against the
env model list — the admin already validated by selection from the provider
catalog. The env list remains as the fallback for roles with null defaultModel.

The admin roles page loads models independently (non-blocking) so roles
remain editable even if the provider API is slow or unreachable.
2026-07-16 01:24:00 +08:00
hongjr03 3ee6da7ceb chore: release v0.0.29
Web-based skill management: create, read, edit, disable skills from the
org admin surface. File tree editor with SKILL.md manifest support.
v0.0.29
2026-07-16 01:12:51 +08:00
hongjr03 79f72ecca8 feat(admin): web-based skill management with file editor
Add full skill lifecycle to the org-admin web surface: create, read,
edit, disable. Skills are directories (SKILL.md manifest + supporting
files), content-addressed by SHA-256 in an immutable store.

Backend:
- skillStore: extract commitSkillContent (shared populate→inspect→
  dedup→atomic rename); add importSkillFromFiles (in-memory file list
  ingestion) and readSkillFiles (read stored version back as UTF-8)
- configuration: add installSkillFromFiles, readSkillFiles, disableSkill
  (soft-delete + archive bound role sessions), updateSkillDescription
  (label-only, no archival); refactor installSkill to share
  commitInstalledSkill
- agentConfigRoutes: wire skillStoreRoot; add GET
  /agent-skills/:name/files, PUT /agent-skills/:name (create/replace),
  PATCH /agent-skills/:name (description/disable)
- orgRoutes: pass readSkillStoreRoot() to agent config routes

Frontend:
- api.ts: agentSkillFiles, installAgentSkill, patchAgentSkill methods
- SkillEditor.svelte: file tree + text editor + version/description form
- skills/+page.svelte: skill list, create form (generates SKILL.md
  template), per-skill editor
- layout: add 技能 nav item

ADR-0018: update Decision to reflect web surface joining host-console
CLI in the shared content-addressed ingestion pipeline.

Spec (AgentRole.lean): unchanged — storage mechanism is OPEN, web
installation is one implementation of it.
2026-07-16 01:11:49 +08:00
hongjr03 ae5f78f036 chore: release v0.0.28
Exempt SPA static assets and admin HTML shell from silo HTTP rate limit so
page loads no longer exhaust HUB_HTTP_REQUESTS_PER_MINUTE.
v0.0.28
2026-07-15 22:33:07 +08:00
hongjr03 0782e155f6 chore: release v0.0.27
Agent role/skill admin restore, OAuth login URL fixes, project create 404 fix.
v0.0.27
2026-07-15 21:35:26 +08:00
ChickenPige0n 0726dc13c8 feat(admin): restore org Agent role/skill management and fix 404 after project create
- explorer POST /projects now returns {id,name} matching the SPA contract
  (previously returned ProjectOnboardingResult.projectId, so res.id was
  undefined and the redirect to /projects/undefined 404'd)
- add OrganizationAgentConfiguration.listRoles/listSkills + AgentRoleRow/
  AgentSkillRow exports; upsertRole now returns the full row
- new agentConfigRoutes: GET/PUT /agent-roles, PUT /agent-roles/:id/skills,
  GET /agent-skills, GET /agent-models (env-default picker)
- restore admin-web roles page + RoleCard rewired to ADR-0017/0018 backend
  (label, defaultModel, tools whitelist, skill binding, systemPrompt,
  sortOrder, default toggle); add 角色 nav item + roles icon
- skill installation stays out-of-band (CLI/seed) per spec; the surface only
  lists installed skills and binds them to roles
2026-07-15 18:19:47 +08:00
ChickenPige0n fb66614e38 fix(admin-web): break /admin/login returnTo redirect loop in dev
vite dev only proxied /api and /auth, so /admin/login hit the SPA root
layout, re-ran loadSession, got 401, and redirected back to /admin/login
with an ever-nesting returnTo. Proxy /admin/login to the backend (which
owns it before the SPA fallback) and guard redirectToLogin against
re-entering /admin/login.

Replace the only emoji-as-icon (the back-arrow on project detail) with
the Icon component (new arrow-left glyph).

Add scripts/dev-bootstrap.ts for seeding a local Silo (stub probes) so
npm run dev can start on a fresh dev DB.
2026-07-15 18:19:47 +08:00
hongjr03 11de9e81db fix(hub): redirect Feishu OAuth default login to org admin SPA
Default returnTo=/admin previously landed on the static complete page
meant for chat onboarding; send users to /admin/org/:slug instead.
2026-07-15 14:29:42 +08:00