250 Commits

Author SHA1 Message Date
26523d1b54 feat(filelib): 操作日志模块——防篡改哈希链、组合查询与 CSV 导出
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:54:45 +08:00
c96ea60482 docs(adr): member-group ADR 改号 0028→0038,避免与 agent-config-folder-tree 撞号 2026-08-06 00:58:51 +08:00
e878b46701 Merge remote-tracking branch 'educraft/main' into merge/educraft-cph
# Conflicts:
#	.gitignore
#	hub/.env.example
#	hub/deploy/deploy_fleet_release.sh
#	hub/deploy/deploy_platform.sh
#	hub/test/integration/helpers.ts
2026-08-06 00:49:02 +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 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
dc271ff9f3 Merge branch 'maoyuanyang-main'
# Conflicts:
#	hub/filelib-web/src/lib/GrantsPanel.svelte
#	hub/filelib-web/src/lib/OverviewPanel.svelte
#	hub/filelib-web/src/lib/types.ts
#	hub/src/database/filelib/grantService.ts
2026-08-03 15:35:44 +08:00
ChickenPige0n 97313aba0f fix(admin-web): redirect to created project using projectId not id 2026-08-01 22:54:34 +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
ymy 53ef364af2 chore(filelib-web): 老师端左栏宽度对齐管理员后台(240px) 2026-07-31 15:06:08 +08:00
ymy 06aa6f0dfb chore(filelib-web): 左栏加宽168->200px,标题与菜单间加横线 2026-07-31 15:02:59 +08:00
ymy 672f05c66a chore(filelib-web): 左栏加「教研数据库」标题,用户身份+退出移至栏底,顶栏去掉身份区 2026-07-31 14:57:01 +08:00
ymy e9cecbf071 chore(filelib-web): 放大网格图标(文件夹54->72/项目50->66/文件46->60),列宽118->132 2026-07-31 14:51:55 +08:00
ymy d9cde19bdf fix(filelib): 恢复保留原名,撞名报清晰错误而非自动加后缀(ADR-0035,supersede ADR-0033)
恢复不再改名;同名兄弟占位时抛 409 name_conflict_on_restore + 人话提示,
操作者自行重命名现有节点或彻底删除旧节点后再恢复。
2026-07-31 14:28:34 +08:00
ymy d39ebed62e fix(filelib-web): 卡片右键补 stopPropagation,不再被背景菜单覆盖(导致看不到删除等节点操作) 2026-07-31 14:16:20 +08:00
ymy 09338f355a chore(filelib-web): 详情弹窗加删除按钮(MANAGE 专属,进回收站可恢复),删除入口不再只在右键菜单 2026-07-31 14:11:26 +08:00
ymy beaa92de2e feat(filelib): 彻底删除改与条目可见性同权(ADR-0034,supersede ADR-0031 仅管理员条款)
能删进回收站(MANAGE)的人就能清空;无关者 404(D8)。二次确认与
node.purge 审计不变;BinView 彻底删除按钮对全部可见条目开放。
2026-07-31 14:01:46 +08:00
ymy 9e38d1e011 fix(filelib): 恢复撞名不再死锁,自动改名「(已恢复)」(ADR-0033)
- restore 前查活跃兄弟:撞名则恢复为「原名(已恢复[/ N])」(截断计入
  128 长度预算),同事务落审计并记 renamedFrom;API 返回最终名
- BinView toast 提示改名;测试补撞名/二次恢复用例
2026-07-31 13:52:23 +08:00
ymy 83a6b012b7 feat(filelib): 移除最近打开模块(ADR-0032,supersede ADR-0031 对应半部)
- FileLibRecentVisit 删表(手写迁移;表当日新建无生产数据)
- recentService/recentRoutes/RecentView 删除;GridLibraryView 埋点与
  navTarget 跳转一并移除;types 清 RecentEntry
- 左栏保留 文件库/回收站(ADR-0031 回收站半部不受影响)
- breadcrumb 的 role 字段保留(独立可用的增量字段)
2026-07-31 13:39:18 +08:00
ymy d072e9ec1e feat(filelib): 老师端左栏导航:回收站 + 最近打开(ADR-0031)
- 回收站:listBin(祖先全活跃的已删顶点;管理员/直连 MANAGE 可见)、
  restore(与 D15 对称只清本节点,落审计)、purge(仅管理员,pathIds 枚举
  子树按深度降序分批硬删,绕过 self-FK RESTRICT)
- 最近打开:FileLibRecentVisit 表(filePath='' 兜底 PG 唯一索引),客户端
  成功打开后上报(VIEW 门禁,upsert 刷新),列表 20 条,D8/D15 可见性过滤
- 前端:/app 左栏(文件库/最近打开/回收站);RecentView/BinView;
  GridLibraryView 埋点 + navTarget 跳转(breadcrumb 建栈,role 已捎带)
- 测试:filelib-nav 集成 4 例;全套 79 例绿
2026-07-31 13:27:04 +08:00
ymy 0fd21e51f7 feat(filelib-web): 老师端文件库改网盘式网格浏览(下钻导航+右键菜单)
- 新 GridLibraryView:双击下钻文件夹/项目,面包屑+返回跳级,项目内文件同网格,
  双击进 FileEditor 预览;工具条按上下文出新建文件夹/项目/文件
- 右键菜单(ContextMenu):打开/新建子文件夹/重命名/授权管理/详情/删除,
  按节点 role 动态显隐;文件菜单:打开预览/下载/删除;空白处右键出新建+刷新
- GridCard 大图标卡片(琥珀文件夹/立方体项目/文档文件);授权与详情复用
  GrantsPanel/OverviewPanel(Modal 加 maxW prop);Icon 补 5 个图标
- 管理后台 /database 保留树状 LibraryView 不动;后端零改动
2026-07-31 12:02:23 +08:00
ymy 39a2be6347 feat(filelib): 项目级授权恒生效,移除独立权限开关(ADR-0030)
- permission.ts: effectiveRole 删除 D11 冻结分支,输入不再含开关字段
- treeService: 停止读 FileLibProjectSettings;建项目不再写默认行
- grantService/routes: 删 setIndependentPermission 与 PUT 路由;节点详情 DTO 去掉 independentPermission
- filelib-web: 概览 tab 移除开关;NodeDetail 类型同步
- 测试: 单测/集成改为断言恒生效语义;ADR-0030 废除契约 D11/P5
- FileLibProjectSettings 表保留(存量行忽略,不再读写),审计词表保留历史读取
2026-07-30 22:27:45 +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 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 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 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 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 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 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
87bbf0bd57 feat(filelib-web): 刷新页面时保持树展开、选中节点、tab 与文件夹位置 2026-07-27 21:27:09 +08:00
8eda04f1d9 fix(filelib-web): 文件内容无变化时不提交 commit 2026-07-27 21:21:15 +08:00
1dab83f9db feat(filelib): 项目新增修改历史 tab 并隐藏 version hash id 2026-07-27 21:19:59 +08:00
8c26c42e0c feat(filelib-web): 编辑器增加 Typst 语法高亮支持 2026-07-27 21:02:02 +08:00
fe38d0b8a9 feat(filelib-web): 文件编辑改为模态框并集成 CodeMirror 语法高亮 2026-07-27 20:53:16 +08:00
e194670d74 feat(filelib-web): 文件面板支持资源管理器式文件夹导航与图标视图切换 2026-07-27 20:48:23 +08:00
3b544d99f4 feat(filelib): 导出改为下载 cph 编译的真实 PDF 2026-07-27 20:25:29 +08:00
ymy 947f969967 chore(filelib-web): 详情容器加宽到 1400px,宽屏下授权表格全列无遮挡;仅文件预览挤压时出横向滚动条 2026-07-27 17:00:41 +08:00
ymy 2e08c0a734 chore(filelib-web): 授权表格外套横向滚动容器,修删除列贴边与文件预览打开时表格挤压 2026-07-27 16:54:07 +08:00
ymy fc908eaf3b chore(filelib-web): 拉宽授权表格:容器 880→1120px,单元格留白/禁换行,长 id 截断+悬停全文 2026-07-27 16:47:05 +08:00
ymy cc4d9d907c chore(filelib-web): 授权成员单元格只留头像+名称,userId 与飞书 ID 拆为独立两列
GrantDto 增加 principalOpenId(USER 主体的 feishuOpenId),GROUP 行两列显示 —;
搜索过滤同步覆盖 openId。
2026-07-27 16:40:25 +08:00
ymy ad1a464f22 chore(filelib-web): 授权成员单元格改用首字母圆形头像(复用 Avatar 组件) 2026-07-27 16:22:01 +08:00
ymy 12a1246a7a chore(filelib-web): 移除添加授权弹窗底部的 8.1 规则提示语 2026-07-27 16:16:16 +08:00