把课程、作业和考试放在一起,少花时间来回查。
31/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add kw78/academic-agent该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · market
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 83 处,展示前 71 条)
- 发起网络请求adapters/fixture-lms/src/index.ts:135
async fetch(): Promise<AdapterResult> { - 读取本地文件adapters/fixture-lms/src/index.ts:149
const raw = JSON.parse(readFileSync(path, 'utf8')) as unknown - 发起网络请求adapters/ustc-blackboard/src/engine.ts:208
async fetch(context?: AdapterFetchContext): Promise<AdapterResult> { - 写入本地文件adapters/ustc-blackboard/src/index.ts:136
mkdirSync(outputDir, { recursive: true }) - 写入本地文件adapters/ustc-blackboard/src/index.ts:163
writeFileSync(saved[0]!, html) - 写入本地文件adapters/ustc-blackboard/src/index.ts:190
writeFileSync(path, courseHtml) - 写入本地文件adapters/ustc-blackboard/src/index.ts:209
writeFileSync( - 读取本地文件apps/academic-cli/src/main.ts:705
return JSON.parse(readFileSync(path, 'utf8')) as unknown - 发起网络请求apps/academic-cli/src/main.ts:847
const result = await app.webSessions.fetch(sessionId, url) - 写入本地文件apps/academic-cli/src/main.ts:850
writeFileSync(out, result.body) - 读取本地文件apps/academic-cli/src/main.ts:992
const text = filePath ? readFileSync(filePath, 'utf8') : inline! - 发起网络请求packages/academic-adapter-runtime/src/runtime.ts:363
return this.request(url, 'GET') - 发起网络请求packages/academic-adapter-runtime/src/runtime.ts:547
const body = await this.request(currentUrl, method, requestBody, { - 发起网络请求packages/academic-adapter-runtime/src/runtime.ts:675
async fetch(context?: AdapterFetchContext): Promise<AdapterResult> { - 发起网络请求packages/academic-adapter-runtime/src/runtime.ts:1180
const result = await adapter.fetch() - 发起网络请求packages/academic-agent-tools/src/tools.ts:706
const result = await dependencies.webSessions!.fetch( - 写入本地文件packages/academic-application/src/app.ts:488
mkdirSync(dirname(options.databasePath), { recursive: true }) - 删除本地文件递归packages/academic-application/src/app.ts:2422
rmSync(materialRoot, { recursive: true, force: true }) - 读取本地文件packages/academic-application/src/backup.ts:21
if (existsSync(targetPath)) { - 写入本地文件packages/academic-application/src/backup.ts:24
mkdirSync(dirname(targetPath), { recursive: true }) - 读取本地文件packages/academic-application/src/backup.ts:29
if (!existsSync(backupPath)) { - 读取本地文件packages/academic-application/src/backup.ts:32
if (existsSync(targetPath)) { - 写入本地文件packages/academic-application/src/backup.ts:35
mkdirSync(dirname(targetPath), { recursive: true }) - 删除本地文件packages/academic-application/src/backup.ts:37
rmSync(`${targetPath}${suffix}`, { force: true }) - 写入本地文件packages/academic-application/src/backup.ts:39
copyFileSync(backupPath, targetPath) - 读取本地文件packages/academic-application/src/backup.ts:58
return createHash('sha256').update(readFileSync(path)).digest('hex') - 读取本地文件packages/academic-application/src/backup.ts:62
return { sha256: sha256File(path), bytes: statSync(path).size } - 读取本地文件packages/academic-application/src/backup.ts:68
for (const entry of readdirSync(directory, { withFileTypes: true })) { - 写入本地文件packages/academic-application/src/backup.ts:143
mkdirSync(targetDir, { recursive: true }) - 写入本地文件packages/academic-application/src/backup.ts:155
mkdirSync(dirname(target), { recursive: true }) - 写入本地文件packages/academic-application/src/backup.ts:156
copyFileSync(join(materialsDir, file), target) - 删除本地文件递归packages/academic-application/src/backup.ts:172
rmSync(targetDir, { recursive: true, force: true }) - 删除本地文件递归packages/academic-application/src/backup.ts:212
rmSync(targetDir, { recursive: true, force: true }) - 执行外部命令固定命令packages/academic-connections/src/vault.ts:104
const child = spawn( - 执行外部命令固定命令packages/academic-connections/src/vault.ts:162
const result = spawnSync( - 写入本地文件packages/academic-connections/src/vault.ts:174
mkdirSync(this.#directory, { recursive: true }) - 写入本地文件packages/academic-connections/src/vault.ts:175
writeFileSync(this.#path(reference), encrypted, { - 读取本地文件packages/academic-connections/src/vault.ts:184
if (!existsSync(path)) return undefined - 读取本地文件packages/academic-connections/src/vault.ts:185
const ciphertext = readFileSync(path, 'utf8').trim() - 读取本地文件packages/academic-connections/src/vault.ts:193
if (!existsSync(path)) return false - 删除本地文件packages/academic-connections/src/vault.ts:194
rmSync(path, { force: true }) - 发起网络请求packages/academic-connectors/src/connector.ts:215
const result = await adapter.fetch(credentials ? { credentials } : undefined) - 发起网络请求packages/academic-connectors/src/connector.ts:321
adapterResult = await adapter.fetch(credentials ? { credentials } : undefined) - 发起网络请求packages/academic-contracts/src/connector.ts:30
fetch(context?: AdapterFetchContext): Promise<AdapterResult> - 删除本地文件递归packages/academic-dsh-plugin/build.mjs:9
rmSync(join(packageRoot, 'lib'), { recursive: true, force: true }) - 删除本地文件递归packages/academic-dsh-plugin/build.mjs:10
rmSync(join(packageRoot, 'migrations'), { recursive: true, force: true }) - 写入本地文件packages/academic-dsh-plugin/build.mjs:11
mkdirSync(join(packageRoot, 'lib'), { recursive: true }) - 删除本地文件递归packages/academic-dsh-ui/build.mjs:9
rmSync(lib, { recursive: true, force: true }) - 写入本地文件packages/academic-dsh-ui/build.mjs:10
mkdirSync(lib, { recursive: true }) - 读取本地文件packages/academic-dsh-ui/build.mjs:41
const body = readFileSync(clientBodyPath, 'utf8') - 写入本地文件packages/academic-dsh-ui/build.mjs:52
writeFileSync(join(lib, 'client.js'), wrapped) - 删除本地文件packages/academic-dsh-ui/build.mjs:53
rmSync(clientBodyPath, { force: true }) - 发起网络请求packages/academic-dsh-ui/lib/host.js:21828
return ok(await app.webSessions.fetch(body.sessionId, body.url)); - 发起网络请求packages/academic-dsh-ui/src/api.ts:1978
return ok(await app.webSessions.fetch(body.sessionId, body.url)) - 写入本地文件packages/academic-materials/src/library.ts:263
mkdirSync(this.#rootDir, { recursive: true }) - 读取本地文件packages/academic-materials/src/library.ts:319
bytes = readFileSync(input.filePath) - 发起网络请求packages/academic-materials/src/library.ts:340
const resource = await this.#fetch(input.url, { - 发起网络请求packages/academic-materials/src/library.ts:490
const resource = await this.#fetch(input.pageUrl, { - 发起网络请求packages/academic-materials/src/library.ts:555
const attachment = await this.#fetch(candidate.url.toString(), { - 读取本地文件packages/academic-materials/src/library.ts:648
if (existsSync(absolute)) rmSync(absolute, { force: true }) - 删除本地文件packages/academic-materials/src/library.ts:648
if (existsSync(absolute)) rmSync(absolute, { force: true }) - 读取本地文件packages/academic-materials/src/library.ts:722
if (!existsSync(absolute)) { - 读取本地文件packages/academic-materials/src/library.ts:740
extraction = this.#extract(row.kind as MaterialKind, readFileSync(absolute)) - 发起网络请求packages/academic-materials/src/library.ts:974
async #fetch(url: string, options: MaterialFetchOptions): Promise<MaterialFetchedResource> { - 写入本地文件packages/academic-materials/src/library.ts:1012
mkdirSync(directory, { recursive: true }) - 读取本地文件packages/academic-materials/src/library.ts:1014
if (!existsSync(absolute)) { - 写入本地文件packages/academic-materials/src/library.ts:1016
writeFileSync(absolute, bytes, { flag: 'wx' }) - 发起网络请求packages/academic-source-browser/src/index.ts:332
const request = response.request() - 读取本地文件packages/academic-storage-sqlite/src/database.ts:37
const files = readdirSync(migrationsDir) - 读取本地文件packages/academic-storage-sqlite/src/database.ts:44
const sql = readFileSync(join(migrationsDir, file), 'utf8') - 发起网络请求packages/academic-web-sessions/src/index.ts:249
async fetch(sessionId: string, targetUrl: string): Promise<WebSessionFetchResult> {
扫描于 2026/11/2(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
本地优先的学术助手,课程、任务、计划采用事件溯源,支持课程资料,并提供 DSH 插件和智能体工具。
README
由 DeepSeek 最新模型翻译生成Academic Agent
| English
把课程、作业和考试放在一起,少花时间来回查。
Academic Agent 是一个在本机运行的学业助手。它汇总学校平台上的课程、作业和考试,保存你的学习进度,并根据空闲时间安排计划。你也可以导入课件和讲义,在需要时请 Agent 查资料、讲题或给复习建议。
日常同步、去重、提醒和基础规划都由程序完成,不调用大模型。遇到尚未支持的网站时,可以在 DSH 对话中让 Agent 帮忙分析页面、生成接入规则;规则经过验证并获准启用后,后续同步就能重复使用。
业务数据默认留在本机,凭据只进系统凭据库;重要变化有来源和历史,用户可以暂停自动化、确认或锁定计划。
接入学校平台
不同学校的网站、接口和页面结构各不相同。Academic Agent 将这些差异保存在可验证的 Manifest(声明式接入规则) 中,让已有引擎承担执行,新平台优先通过配置接入。
1. 观察真实网站:用户完成登录后,Agent 通过受控工具探测页面、有限抓取栏目,寻找列表、字段、分页与接口线索;支持 HTML / JSON,以及显式声明的只读 JSON POST。
2. 生成候选规则:Agent 在 DSH 对话中将发现整理为 Manifest,声明读取哪些主机、路径、课程和学业字段。候选可以暂存,供用户查看。
展开完整文档(README 剩余 1 节)
Academic Agent | English 把课程、作业和考试放在一起,少花时间来回查。 Academic Agent 是一个在本机运行的学业助手。它汇总学校平台上的课程、作业和考试,保存你的学习进度,并根据空闲时间安排计划。你也可以导入课件和讲义,在需要时请 Agent 查资料、讲题或给复习建议。 日常同步、去重、提醒和基础规划都由程序完成,不调用大模型。遇到尚未支持的网站时,可以在 DSH 对话中让 Agent 帮忙分析页面、生成接入规则;规则经过验证并获准启用后,后续同步就能重复使用。 业务数据默认留在本机,凭据只进系统凭据库;重要变化有来源和历史,用户可以暂停自动化、确认或锁定计划。 接入学校平台 不同学校的网站、接口和页面结构各不相同。Academic Agent 将这些差异保存在可验证的 Manifest(声明式接入规则) 中,让已有引擎承担执行,新平台优先通过配置接入。 1. 观察真实网站:用户完成登录后,Agent 通过受控工具探测页面、有限抓取栏目,寻找列表、字段、分页与接口线索;支持 HTML / JSON,以及显式声明的只读 JSON POST。 2. 生成候选规则:Agent 在 DSH 对话中将发现整理为 Manifest,声明读取哪些主机、路径、课程和学业字段。候选可以暂存,供用户查看。 3. 用样本检验推断:在真实页面 / JSON 样本上离线回放,检查规则结构、字段契约与访问范围;宿主捕获的样本可通过 sampleId 引用,原始响应无需交给模型。 4. 授权后持续复用:只有验证通过的版本才能启用;启用会创建或更新同步源,后续由确定性运行时按规则执行,无需每轮重新推理网站结构。 flowchart LR A[用户登录与入口 URL] --> B[Agent 探测与生成候选] B --> C[样本回放与契约验证] C --> D[授权启用 Manifest 版本] D --> E[零 LLM 日常同步] E --> F[任务、计划与提醒] E -. 同步异常:当前在对话中诊断 .-> B 已有实例:USTC 教务考试接入。 新增一个 Manifest、两个 fixture 和一组集成测试,即可读取考试信息;无需修改内核、Connector 或 UI,也无需新增网站专属引擎。覆盖范围见 真实数据源验证。 自适应也体现在日常安排中:截止时间、任务进度或可用时间改变后,系统可以重新计算计划建议,保留用户锁定的时间块,并说明无法安排的冲突。 网站改版后怎么处理 系统积累的是可验证的接入规则、候选版本和验证记录。网站变化后,可以结合失败信息重新探测、生成新版本、回放验证,再切换生效版本;旧版本保留,可回滚。规则演进与学业事实分开管理,同步失败会保留已有数据和用户进度。 | 环节 | 当前进展 | | 探测 → 候选 → 验证 → 启用 / 回滚 | 已实现;候选生成由 DSH 对话中的 Agent 完成 | | 启用 → 真实预览 / 同步 | 已实现;设置页开启“Agent 自动接入”后,Agent 可在授权范围内完成,无需逐次审核 | | 失败诊断 → 修改规则 → 新版本验证 | 目前由用户发起 Agent 对话,结合现有工具完成 | | 同步失败自动唤起 Agent 并修复 | 后续目标;尚未实现无人值守的自修复闭环 | 样本回放通过只说明规则能解析给定样本;真实预览、真实同步与重复同步 no-op 需要分别验证。 当前能力与进展详见 MVP 验收 和 路线图。 “Agent 自动接入”默认关闭,用户可随时关闭;开启后也仅允许启用已验证候选、预览和同步声明式数据源。任务修改等其他写入仍需可信宿主逐次授权。Agent 不获得 Cookie / Token,也不会替你提交作业或修改学校账户。 平时可以用它做什么 - 汇总课程和待办:已实测 Blackboard 课程 / 作业与 USTC 教务考试,也可手动添加。重复同步不会重复建课,同学期同名课程复用同一身份。 - 安排学习时间:按截止时间、任务及课程优先级和你设置的空闲时间规划;支持计划确认、锁定和冲突说明。 - 截止前提醒:默认本地扫描 72 小时 / 24 小时提醒,去重并在重启后补偿检查。 - 检索课件和讲义:导入 PDF、PPTX、DOCX、网页或文本后按关键词检索;提供资料标题、片段和可用页码,供 Agent 引用。扫描版 PDF 暂无 OCR。 - 按需查询与讲解:在 DSH 对话中使用课程、任务、计划和资料工具;Tutor skill 约束讲解先查资料、标注来源,缺少资料时明确说明。 - 跨会话保留成果:数据、配置、计划和后台作业可恢复;宿主运行时,例行自动化独立于 Agent 会话。停用 Agent 或 UI 插件仍保留学业事实。 最短上手 要求 Node.js ≥ 22.12;凭据库目前使用 Windows DPAPI。 npm ci npm run build:dsh npm run build:ui 用内置演示数据跑通:同步 → 任务 → 计划 ACADEMIC_DB=.data/academic.db npm run demo 第一次完整使用可以按这个顺序:添加课程 → 连接/同步 → list 看任务 → plan --accept 确认计划 → 导入资料。demo 会用内置数据把这条链路跑一遍。 常用操作: npm run demo -- list # 看今天/近期要做什么 npm run demo -- course add 2026-fall CS101 "Computer Science" npm run demo -- task add "复习第三章" --minutes 60 npm run demo -- plan --accept # 生成并确认未来 7 天计划 npm run demo -- material add notes.pdf --course <courseId> npm run demo -- material search "隐函数" npm run demo -- help 完整命令见 CLI 参考。数据库默认在 .data/academic.db,可用 ACADEMIC_DB 改路径。 在 DSH 里使用(可选) 需要 DSH 0.2.1-rc.3。只装 Host/工具: dsh plugin --profile academic add <path-to-repo>/packages/academic-dsh-plugin 同时装「学业」界面(Web 或 Desktop): dsh plugin --profile academic-web add \ <path-to-repo>/packages/academic-dsh-plugin \ <path-to-repo>/packages/academic-dsh-ui 界面分两块:「日常学习」(今天、任务、计划、课程、资料)和「管理」(连接、自动化、设置)。今天页先显示下一学习时段、今日任务与逾期;课程页汇总任务、来源和资料。 智能体默认只读;修改任务、导入/删除资料等写入操作,必须由可信宿主逐次批准。当前没有接入 DSH 审批弹窗时,这些写入会被拒绝,命令行/UI 操作不受影响。上文的「Agent 自动接入」是用户单独开启的有限授权,只覆盖已验证候选启用和声明式源的预览 / 同步。 DSH 没有官方中央市场;插件 Discover 读取用户配置的索引。Academic Agent 索引: https://kw78.github.io/academic-agent/market/index.json 添加方式见 market/README.md。 安装细节:插件 README、UI README。 数据放在哪里 - 数据库:命令行默认 .data/academic.db;DSH 默认 $DSH_HOME/academic-agent/academic.db。 - 课程资料:数据库同目录的 materials/,按内容哈希保存;SQLite 只存元数据和检索分块。 - 凭据:Windows DPAPI;数据库、日志和智能体结果里没有明文 Cookie/Token。 - 备份:backup 只快照 SQLite;backup-app 连同 materials/ 与 SHA-256 清单一起备份,整库迁移用后者。 - 删除/恢复与故障处理见 运维文档。 已知限制 - 凭据库目前只支持 Windows DPAPI。 - 扫描版 PDF 没有 OCR,只能保存原件。 - 自动附件导入只扫描你给出的单个课程页,不做全站爬虫。 - Blackboard 已覆盖课程/作业/文件夹;真实考试/测验样本仍以脱敏 fixture 验证。 - DSH 文件级 HMR、真实 Session 生命周期和完整审批 UI 尚未专项验证。 - npm 包尚未正式发布;当前从源码或本地 tarball 安装。 更完整的验收边界见 MVP 验收,架构与工程状态见 AGENTS.md。 文档 - CLI 参考 - 运维、备份与故障处理 - 测试与架构矩阵 - 前端验证记录 - 架构决策 - 当前路线图 - v0.2.0 发布说明 - 架构基线:Intent、Architecture Spec License Apache License 2.0。见 LICENSE;第三方依赖保留各自许可证。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
kw78/academic-agent
把课程、作业和考试放在一起,少花时间来回查。
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,025未汉化DSH
73.6
新词雷达zhuyansen/new-term-radar
new-term-radar新词雷达
★ 2,049已汉化MCP
72.8
插件生态导航0xsline/awesome-deepseek-harness
安装 贡献指南 DeepSeek Docs 公开插件目录 Issues
★ 1,188已汉化DSH
72.6
技能注册中心iflytek/skillhub
企业级开源智能体技能注册中心——发布、发现并管理组织内可复用的技能包。
★ 5,358已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13938 个插件含 PR 收录与…
★ 350已汉化DSH
71.8
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7