monash-study-kit 1.2.0__tar.gz

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.
Files changed (83) hide show
  1. monash_study_kit-1.2.0/.github/ISSUE_TEMPLATE/bug_report.yml +39 -0
  2. monash_study_kit-1.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. monash_study_kit-1.2.0/.github/ISSUE_TEMPLATE/feature_request.yml +23 -0
  4. monash_study_kit-1.2.0/.github/pull_request_template.md +10 -0
  5. monash_study_kit-1.2.0/.github/workflows/release.yml +115 -0
  6. monash_study_kit-1.2.0/.github/workflows/test.yml +71 -0
  7. monash_study_kit-1.2.0/.gitignore +7 -0
  8. monash_study_kit-1.2.0/CHANGELOG.md +75 -0
  9. monash_study_kit-1.2.0/CODE_OF_CONDUCT.md +7 -0
  10. monash_study_kit-1.2.0/CONTRIBUTING.md +37 -0
  11. monash_study_kit-1.2.0/LICENSE +21 -0
  12. monash_study_kit-1.2.0/PKG-INFO +464 -0
  13. monash_study_kit-1.2.0/README.md +435 -0
  14. monash_study_kit-1.2.0/README.zh-CN.md +408 -0
  15. monash_study_kit-1.2.0/SECURITY.md +21 -0
  16. monash_study_kit-1.2.0/docs/adr/0001-one-shared-core.md +27 -0
  17. monash_study_kit-1.2.0/docs/adr/0002-read-only-public-package.md +21 -0
  18. monash_study_kit-1.2.0/docs/adr/0003-release-from-a-tag.md +27 -0
  19. monash_study_kit-1.2.0/docs/adr/README.md +11 -0
  20. monash_study_kit-1.2.0/docs/releasing.md +46 -0
  21. monash_study_kit-1.2.0/docs/security.md +265 -0
  22. monash_study_kit-1.2.0/glama.json +6 -0
  23. monash_study_kit-1.2.0/pyproject.toml +60 -0
  24. monash_study_kit-1.2.0/scripts/check_dist.py +75 -0
  25. monash_study_kit-1.2.0/scripts/measure_tokens.py +129 -0
  26. monash_study_kit-1.2.0/scripts/smoke_test.py +93 -0
  27. monash_study_kit-1.2.0/src/monash_study_kit/__init__.py +4 -0
  28. monash_study_kit-1.2.0/src/monash_study_kit/__main__.py +5 -0
  29. monash_study_kit-1.2.0/src/monash_study_kit/browser_login.py +213 -0
  30. monash_study_kit-1.2.0/src/monash_study_kit/cdp.py +188 -0
  31. monash_study_kit-1.2.0/src/monash_study_kit/claude_setup.py +152 -0
  32. monash_study_kit-1.2.0/src/monash_study_kit/cli.py +843 -0
  33. monash_study_kit-1.2.0/src/monash_study_kit/cli_ed.py +238 -0
  34. monash_study_kit-1.2.0/src/monash_study_kit/clients.py +230 -0
  35. monash_study_kit-1.2.0/src/monash_study_kit/content_index.py +324 -0
  36. monash_study_kit-1.2.0/src/monash_study_kit/doctor.py +228 -0
  37. monash_study_kit-1.2.0/src/monash_study_kit/doctor_deep.py +275 -0
  38. monash_study_kit-1.2.0/src/monash_study_kit/edlib.py +551 -0
  39. monash_study_kit-1.2.0/src/monash_study_kit/edquery.py +431 -0
  40. monash_study_kit-1.2.0/src/monash_study_kit/edsync.py +183 -0
  41. monash_study_kit-1.2.0/src/monash_study_kit/features.py +591 -0
  42. monash_study_kit-1.2.0/src/monash_study_kit/help_menu.py +121 -0
  43. monash_study_kit-1.2.0/src/monash_study_kit/htmldom.py +162 -0
  44. monash_study_kit-1.2.0/src/monash_study_kit/jobs.py +233 -0
  45. monash_study_kit-1.2.0/src/monash_study_kit/lesson_reader.py +94 -0
  46. monash_study_kit-1.2.0/src/monash_study_kit/lessons.py +231 -0
  47. monash_study_kit-1.2.0/src/monash_study_kit/mcp_server.py +713 -0
  48. monash_study_kit-1.2.0/src/monash_study_kit/moodlelib.py +485 -0
  49. monash_study_kit-1.2.0/src/monash_study_kit/output.py +73 -0
  50. monash_study_kit-1.2.0/src/monash_study_kit/paths.py +126 -0
  51. monash_study_kit-1.2.0/src/monash_study_kit/recordings.py +312 -0
  52. monash_study_kit-1.2.0/src/monash_study_kit/syncer.py +393 -0
  53. monash_study_kit-1.2.0/src/monash_study_kit/textextract.py +89 -0
  54. monash_study_kit-1.2.0/src/monash_study_kit/todo.py +178 -0
  55. monash_study_kit-1.2.0/src/monash_study_kit/transcribe.py +128 -0
  56. monash_study_kit-1.2.0/src/monash_study_kit/update_check.py +113 -0
  57. monash_study_kit-1.2.0/src/monash_study_kit/webnotes.py +312 -0
  58. monash_study_kit-1.2.0/tests/conftest.py +7 -0
  59. monash_study_kit-1.2.0/tests/test_cdp.py +80 -0
  60. monash_study_kit-1.2.0/tests/test_cli.py +72 -0
  61. monash_study_kit-1.2.0/tests/test_clients.py +88 -0
  62. monash_study_kit-1.2.0/tests/test_content_index.py +50 -0
  63. monash_study_kit-1.2.0/tests/test_doctor.py +87 -0
  64. monash_study_kit-1.2.0/tests/test_doctor_deep.py +173 -0
  65. monash_study_kit-1.2.0/tests/test_ed_auth.py +22 -0
  66. monash_study_kit-1.2.0/tests/test_ed_markdown.py +77 -0
  67. monash_study_kit-1.2.0/tests/test_ed_query.py +203 -0
  68. monash_study_kit-1.2.0/tests/test_ed_quiz.py +48 -0
  69. monash_study_kit-1.2.0/tests/test_features.py +229 -0
  70. monash_study_kit-1.2.0/tests/test_help_menu.py +53 -0
  71. monash_study_kit-1.2.0/tests/test_layout.py +121 -0
  72. monash_study_kit-1.2.0/tests/test_lesson_reader.py +108 -0
  73. monash_study_kit-1.2.0/tests/test_mcp.py +166 -0
  74. monash_study_kit-1.2.0/tests/test_recordings.py +64 -0
  75. monash_study_kit-1.2.0/tests/test_removed_files.py +92 -0
  76. monash_study_kit-1.2.0/tests/test_security.py +470 -0
  77. monash_study_kit-1.2.0/tests/test_setup.py +93 -0
  78. monash_study_kit-1.2.0/tests/test_shared_core.py +231 -0
  79. monash_study_kit-1.2.0/tests/test_sync_robustness.py +109 -0
  80. monash_study_kit-1.2.0/tests/test_todo.py +88 -0
  81. monash_study_kit-1.2.0/tests/test_update_check.py +81 -0
  82. monash_study_kit-1.2.0/tests/test_webnotes.py +113 -0
  83. monash_study_kit-1.2.0/uv.lock +1675 -0
@@ -0,0 +1,39 @@
1
+ name: Bug report
2
+ description: Something doesn't work or gives a wrong answer
3
+ labels: [bug]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Please don't paste cookies, tokens, calendar links, unit materials, other students' posts or your grades.
9
+ - type: textarea
10
+ id: what
11
+ attributes:
12
+ label: What happened
13
+ description: What you did or asked Claude, what you expected, and what you got.
14
+ validations:
15
+ required: true
16
+ - type: textarea
17
+ id: doctor
18
+ attributes:
19
+ label: Output of `monash doctor`
20
+ description: Run `monash doctor --deep` if the problem is a wrong or missing result. The output leaves out credentials.
21
+ render: text
22
+ validations:
23
+ required: true
24
+ - type: dropdown
25
+ id: where
26
+ attributes:
27
+ label: Where
28
+ options:
29
+ - Claude Desktop
30
+ - Claude Code
31
+ - The monash command in a terminal
32
+ - Another MCP client
33
+ validations:
34
+ required: true
35
+ - type: input
36
+ id: unit
37
+ attributes:
38
+ label: Unit code (if it only happens in one unit)
39
+ placeholder: FIT2102
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security problem
4
+ url: https://github.com/Waldo0926/monash-study-kit/security/advisories/new
5
+ about: Report it privately, not as a public issue.
@@ -0,0 +1,23 @@
1
+ name: Feature request
2
+ description: Something you'd like it to do
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: need
7
+ attributes:
8
+ label: What do you want to do
9
+ description: What you'd ask Claude or type in the terminal, and what answer you'd want.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: where
14
+ attributes:
15
+ label: Where the data is
16
+ description: Which Moodle or Ed page has this information today.
17
+ - type: checkboxes
18
+ id: readonly
19
+ attributes:
20
+ label: Read-only
21
+ options:
22
+ - label: This only reads from Moodle or Ed. (Submitting, posting or changing things is out of scope.)
23
+ required: true
@@ -0,0 +1,10 @@
1
+ Before:
2
+
3
+ After:
4
+
5
+ How:
6
+
7
+ - [ ] Tests added or updated, and `uv run pytest -q` passes
8
+ - [ ] `uvx ruff@0.6.9 check src tests scripts` passes
9
+ - [ ] If `src/` changed: `__version__` bumped and `CHANGELOG.md` updated
10
+ - [ ] Still read-only, and no real names, ids, cookies or tokens in test samples
@@ -0,0 +1,115 @@
1
+ name: release
2
+
3
+ # 推一个 v 开头的 tag 就发版:tag 和 __version__ 对得上、CHANGELOG 写了、全部测试过了,
4
+ # 才打包上传 PyPI(Trusted Publishing,不存任何密码或令牌),再从 PyPI 装一遍确认能用,最后建 GitHub Release。
5
+ # git tag v1.1.0 && git push origin v1.1.0
6
+ # PyPI 那边第一次要先加好 trusted publisher,步骤见 docs/releasing.md。
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ check:
17
+ runs-on: ubuntu-latest
18
+ outputs:
19
+ version: ${{ steps.v.outputs.version }}
20
+ steps:
21
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
22
+ with:
23
+ fetch-depth: 0
24
+ - name: tag、__version__、CHANGELOG 三处一致,tag 在 main 上
25
+ id: v
26
+ run: |
27
+ tag="${GITHUB_REF_NAME#v}"
28
+ version=$(sed -n 's/^__version__ = "\(.*\)"/\1/p' src/monash_study_kit/__init__.py)
29
+ if [ "$tag" != "$version" ]; then
30
+ echo "::error::tag 是 v$tag,但 __version__ 是 $version"; exit 1
31
+ fi
32
+ if ! grep -qx "## $version" CHANGELOG.md; then
33
+ echo "::error file=CHANGELOG.md::CHANGELOG 里没有 ## $version 这一节"; exit 1
34
+ fi
35
+ git fetch origin main
36
+ if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
37
+ echo "::error::v$version 指向的提交不在 main 上,先合进 main 再打 tag"; exit 1
38
+ fi
39
+ echo "version=$version" >> "$GITHUB_OUTPUT"
40
+
41
+ test:
42
+ needs: check
43
+ uses: ./.github/workflows/test.yml
44
+
45
+ build:
46
+ needs: [check, test]
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
50
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
51
+ - run: uv build
52
+ - run: uv run --no-project scripts/check_dist.py dist "${{ needs.check.outputs.version }}"
53
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
54
+ with:
55
+ name: dist
56
+ path: dist/
57
+
58
+ publish:
59
+ needs: [check, build]
60
+ runs-on: ubuntu-latest
61
+ environment:
62
+ name: pypi
63
+ url: https://pypi.org/project/monash-study-kit/${{ needs.check.outputs.version }}/
64
+ permissions:
65
+ id-token: write # Trusted Publishing 靠这个向 PyPI 证明是这个仓库的这个 workflow
66
+ steps:
67
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
68
+ with:
69
+ name: dist
70
+ path: dist/
71
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
72
+
73
+ pypi-smoke:
74
+ # 用户真正会做的事:从 PyPI 装,然后跑起来
75
+ needs: [check, publish]
76
+ strategy:
77
+ fail-fast: false
78
+ matrix:
79
+ os: [ubuntu-latest, macos-latest, windows-latest]
80
+ runs-on: ${{ matrix.os }}
81
+ steps:
82
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
83
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
84
+ - name: 从 PyPI 装(刚上传可能要等一会儿才装得到)
85
+ shell: bash
86
+ run: |
87
+ v="${{ needs.check.outputs.version }}"
88
+ uv venv --python 3.13 smoke
89
+ if [ -d smoke/Scripts ]; then py=smoke/Scripts/python.exe exe=smoke/Scripts/monash.exe; else py=smoke/bin/python exe=smoke/bin/monash; fi
90
+ for i in 1 2 3 4 5 6; do
91
+ uv pip install --python "$py" --refresh "monash-study-kit==$v" && break
92
+ [ "$i" = 6 ] && exit 1
93
+ sleep 20
94
+ done
95
+ "$py" scripts/smoke_test.py "$exe" "$v"
96
+
97
+ github-release:
98
+ needs: [check, build, pypi-smoke]
99
+ runs-on: ubuntu-latest
100
+ permissions:
101
+ contents: write
102
+ steps:
103
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
104
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
105
+ with:
106
+ name: dist
107
+ path: dist/
108
+ - name: 用 CHANGELOG 里这一版的内容建 Release
109
+ env:
110
+ GH_TOKEN: ${{ github.token }}
111
+ run: |
112
+ v="${{ needs.check.outputs.version }}"
113
+ awk -v h="## $v" '$0 == h {on=1; next} /^## / && on {exit} on' CHANGELOG.md > notes.md
114
+ printf '\nInstall: `uv tool install monash-study-kit` (PyPI: https://pypi.org/project/monash-study-kit/%s/)\n' "$v" >> notes.md
115
+ gh release create "v$v" dist/* --title "v$v" --notes-file notes.md --verify-tag
@@ -0,0 +1,71 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_call: # release.yml 发版前先跑一遍
8
+
9
+ jobs:
10
+ test:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest, windows-latest]
15
+ python: ["3.10", "3.13"]
16
+ runs-on: ${{ matrix.os }}
17
+ steps:
18
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
19
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
20
+ - run: uv sync --python ${{ matrix.python }}
21
+ - name: ruff(语法错误、未定义的名字、没用的 import)
22
+ if: matrix.os == 'ubuntu-latest' && matrix.python == '3.13'
23
+ run: uvx ruff@0.6.9 check src tests
24
+ - run: uv run pytest -q
25
+ - name: CLI 能启动
26
+ run: uv run monash --version
27
+
28
+ package:
29
+ # 打出来的包装进一个干净的 venv 能不能用:只在仓库里 uv run 测不出漏打包的文件
30
+ strategy:
31
+ fail-fast: false
32
+ matrix:
33
+ os: [ubuntu-latest, macos-latest, windows-latest]
34
+ runs-on: ${{ matrix.os }}
35
+ steps:
36
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
37
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
38
+ - name: 打包并检查内容
39
+ shell: bash
40
+ run: |
41
+ version=$(sed -n 's/^__version__ = "\(.*\)"/\1/p' src/monash_study_kit/__init__.py)
42
+ echo "VERSION=$version" >> "$GITHUB_ENV"
43
+ uv build
44
+ uv run --no-project scripts/check_dist.py dist "$version"
45
+ - name: 装进干净的 venv,跑 --version、help 和 MCP 握手
46
+ shell: bash
47
+ run: |
48
+ uv venv --python 3.10 smoke
49
+ if [ -d smoke/Scripts ]; then py=smoke/Scripts/python.exe exe=smoke/Scripts/monash.exe; else py=smoke/bin/python exe=smoke/bin/monash; fi
50
+ uv pip install --python "$py" dist/*.whl
51
+ "$py" scripts/smoke_test.py "$exe" "$VERSION"
52
+
53
+ version-bump:
54
+ # 朋友那边的更新提示比的是 main 上的 __version__:改了代码却没改版本号,他们就收不到提示
55
+ if: github.event_name == 'pull_request'
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
59
+ with:
60
+ fetch-depth: 0
61
+ - name: 改了 src/ 就要改版本号
62
+ run: |
63
+ base=origin/${{ github.base_ref }}
64
+ if git diff --quiet "$base"...HEAD -- src/; then
65
+ echo "没改 src/,不用改版本号"; exit 0
66
+ fi
67
+ old=$(git show "$base":src/monash_study_kit/__init__.py | sed -n 's/^__version__ = "\(.*\)"/\1/p')
68
+ new=$(sed -n 's/^__version__ = "\(.*\)"/\1/p' src/monash_study_kit/__init__.py)
69
+ echo "main: $old → 这个 PR: $new"
70
+ python3 -c "import sys; p=lambda v: tuple(int(x) for x in v.split('.')); sys.exit(0 if p('$new') > p('$old') else 1)" \
71
+ || { echo "::error file=src/monash_study_kit/__init__.py::改了 src/ 就把 __version__ 加一(修 bug 加最后一位,加功能加中间一位),不然朋友收不到更新提示"; exit 1; }
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .pytest_cache/
5
+ dist/
6
+ build/
7
+ *.egg-info/
@@ -0,0 +1,75 @@
1
+ # Changelog
2
+
3
+ Version numbers follow `__version__` in `src/monash_study_kit/__init__.py`: patch for bug fixes, minor for new features.
4
+
5
+ ## 1.2.0
6
+
7
+ - `monash connect <client>` connects Study Kit to Codex, Cursor, VS Code, Windsurf or Gemini CLI in one command. It adds only the `monash` entry with the full path to the program, keeps the rest of the config file and saves a backup first. Codex uses `codex mcp add` when the `codex` command is installed. `monash connect` alone lists the clients and whether each is connected, `--print` shows the entry without writing it, and `--remove` takes it out. A config file that isn't plain JSON (for example with comments) is left alone and the entry is printed to paste by hand.
8
+ - `monash uninstall` also removes the entry from those clients.
9
+
10
+ ## 1.1.1
11
+
12
+ `monash doctor --deep` on my server reported four problems that weren't real. Fixed in the checks, no change to syncing:
13
+
14
+ - "Never synced" on a deployment that syncs Moodle with its own script: the last sync time now falls back to the one stored in the Moodle database when `status.json` has none (`doctor`, `monash status`).
15
+ - Files the teacher made available but hidden from the course page (Moodle "stealth" activities) were counted as missing. Sync follows the course page, so these are skipped.
16
+ - Videos served from CloudFront were counted as missing: the CloudFront address has no file extension, so the check now also looks at the Moodle file name, as sync does.
17
+ - The search probe sometimes picked a word inside a link (for example a Google Docs ID in `links.md`), which the index stores as a different word. It now picks whole words outside links.
18
+ - Ed posts changed after the last sync started are no longer reported as stale; the next sync picks them up.
19
+
20
+ ## 1.1.0
21
+
22
+ The code that runs my own server deployment (moodle-sync on a VPS, and ed-digest) used to be a copy of this package and had drifted. Its fixes and features are now here, so both deployments install this package instead of carrying their own copy.
23
+
24
+ - Full-text search also covers text files inside `.zip` archives (starter code, READMEs). A hit carries `inner`, which `read_file` takes directly.
25
+ - `list_files` takes `since_days` to answer "what's new this week", and `monash todo` / `get_study_todo` list course files synced in the last N days.
26
+ - Ed reading pages saved by ed-digest (`lesson_texts`) are indexed and searchable, and Ed hits carry the original link.
27
+ - Calendar items from the subscription link get a clean activity name: Monash's "- Allocate+ ..." and "- CALLISTA: ..." suffixes are stripped.
28
+ - Forum lists: a row without a discussion id (a pinned-section divider) is skipped instead of breaking the whole list.
29
+ - A lecture transcript is hidden together with its video when the video is removed from Moodle.
30
+ - Interrupted downloads: leftover `.dl-*` files are cleaned up at the start of each unit's sync, temporary names no longer end in `.part.part`, and a cut-off Zoom download is deleted.
31
+ - `monash media` caches each video's fingerprint, so it no longer re-reads every transcribed video on each run.
32
+ - Ed: replies under a deleted reply are kept, as Ed still shows them.
33
+ - Saving the Moodle cookie or Ed token uses a per-process temporary file, so two MCP servers (Claude Desktop and Claude Code) refreshing at once can't clash.
34
+ - Security fixes from a review of the whole package (`docs/security.md`):
35
+ - The Moodle cookie is only sent over the same scheme as `MOODLE_BASE_URL` (HTTPS), never to an `http://` link.
36
+ - The Ed token is no longer carried along if Ed ever redirects a request to another site.
37
+ - The login window talks to the browser over a pipe on macOS and Linux, so no DevTools port is open while you log in.
38
+ - `read_file` refuses text files over 30 MB and zip entries that unpack to more than that, and docx/pptx text is read with a size cap.
39
+ - `monash doctor` also hides `sesskey` values and scrubs error messages from checks that crash.
40
+ - Symlinks in the course-file folders that point outside them are no longer indexed.
41
+ - `read_file` refuses a file that was taken down on Moodle, even when asked for it by path.
42
+ - `monash doctor --deep` cross-checks the tools against a second source: upcoming due dates against the iCal feed, the assignment overview page against the course structure, synced files against the course structure (lecture videos that are deliberately not downloaded are told apart), the search index against the files on disk plus a few real searches that must find their file again, and the latest Ed posts against the local copy. It only reads, and prints counts, unit codes, dates and activity ids, never titles, file names or grades.
43
+ - Published on PyPI: install with `uv tool install monash-study-kit`. `monash update` installs from PyPI (falling back to GitHub), and the update notice checks PyPI first.
44
+ - Releases are made by pushing a tag: CI checks the tag against `__version__` and this changelog, runs the tests, uploads with Trusted Publishing, installs the result back from PyPI on three OSes and creates the GitHub release. Every PR also installs the built wheel into a clean venv and runs `monash --version`, `monash help` and an MCP handshake. See `docs/releasing.md`.
45
+ - New settings `name_limit` and `pdf_extractor` (`pypdf` or `pdftotext`). Every setting can also be overridden with `MONASH_KIT_<NAME>`, and `MONASH_KIT_DATA`, `MONASH_KIT_SECRETS`, `MONASH_KIT_ED_DATA` and `MONASH_KIT_ED_TOKEN` point the package at an existing server layout.
46
+
47
+ ## 1.0.3
48
+
49
+ Fixes for things that went wrong halfway through a sync.
50
+
51
+ - Ed Lessons: if one lesson's details fail to load (a 500 or a timeout), its saved slides and quiz questions are kept instead of being wiped until the next sync.
52
+ - Ed Lessons: lessons that were deleted or hidden on Ed are removed from the local database and from `ed-files`, so search stops returning them.
53
+ - Downloads cut off halfway: Ed lesson PDFs are now written to a `.part` file first, so a half file is never treated as finished, and Moodle downloads clean up their `.part` file instead of leaving it in the course folder.
54
+ - Moodle files: files a teacher removed or re-uploaded under a new name are marked as removed after a clean sync, and drop out of `list_files`, `monash moodle ls`, search and `monash media`. The files stay on disk, and a file that comes back on Moodle is restored. Nothing is marked when any activity in the unit failed to load that run.
55
+ - Ed posts: replies deleted on Ed are removed from the local copy the next time that post is fetched.
56
+ - `monash todo` / `get_study_todo`: when Moodle can't be reached, the Ed half (lessons, announcements, unread replies) is still returned, with a note about what is missing.
57
+ - Full-text index: one unreadable file (encrypted, truncated, deleted mid-sync) no longer stops the whole index run.
58
+ - Word / PowerPoint text: `&amp;` and `&lt;` are decoded, and words split across formatting runs are joined, so searching "Monads" finds a slide written as "Mon" + "ads".
59
+ - Course-notes websites: `robots.txt` is now respected (checked once a day per site).
60
+ - MCP server: a malformed message gets a JSON-RPC error instead of crashing the server, and an unexpected error in the background loop is logged instead of silently stopping hourly sync and session refresh.
61
+ - `monash config`: number settings accept decimals (`tz_offset 9.5` for Adelaide, `auto_sync_hours 0.5`), and a typo in a true/false setting is rejected instead of being read as false.
62
+ - Login window: cookies are only taken from Moodle's own domain or its parent domains, matched on a dot boundary.
63
+ - CI runs `ruff` for syntax errors, undefined names and unused imports.
64
+
65
+ ## 1.0.2
66
+
67
+ - MCP tools renamed to a consistent `get_` / `list_` / `search_` / `read_` / `start_` / `sync_` scheme. The old names still work when called.
68
+
69
+ ## 1.0.1
70
+
71
+ - Every MCP tool parameter has a short description, and tool descriptions say which related tool to use instead.
72
+
73
+ ## 1.0.0
74
+
75
+ First stable release. See the [release notes](https://github.com/Waldo0926/monash-study-kit/releases/tag/v1.0.0).
@@ -0,0 +1,7 @@
1
+ # Code of conduct
2
+
3
+ This project uses the [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
4
+
5
+ In short: be kind and patient, assume good intent, and keep discussion about the code. Harassment, insults and personal attacks are not okay. Don't post anyone's personal information, including other students' names, posts or grades from Moodle or Ed.
6
+
7
+ If something happens, contact the maintainer privately at wensx0926@gmail.com. Reports are kept confidential. The maintainer may remove comments, issues or pull requests that break these rules, and may block people who keep doing it.
@@ -0,0 +1,37 @@
1
+ # Contributing
2
+
3
+ Thanks for helping. Bug reports from other Monash students are the most useful thing, since every unit sets up Moodle a bit differently.
4
+
5
+ ## Reporting a bug
6
+
7
+ Use the bug report form. Run `monash doctor` (or `monash doctor --deep` if something looks wrong in the results) and paste the output. It leaves out cookies, tokens and calendar links. Please don't paste unit materials, other students' posts or your grades.
8
+
9
+ ## Setting up
10
+
11
+ ```bash
12
+ git clone https://github.com/Waldo0926/monash-study-kit
13
+ cd monash-study-kit
14
+ uv sync
15
+ uv run pytest -q
16
+ uvx ruff@0.6.9 check src tests scripts
17
+ uv run monash --help
18
+ ```
19
+
20
+ `uv run monash ...` uses your real data folder. To try things without touching it, set `MONASH_KIT_HOME` to an empty folder first.
21
+
22
+ ## Making a change
23
+
24
+ - Keep it read-only. Tools must not submit, post or change anything on Moodle or Ed.
25
+ - Add a test for the bug or feature. Tests never touch the network; save a trimmed HTML or JSON sample in the test instead.
26
+ - Test samples must not contain real names, student ids, emails, cookies or tokens. Replace them with made-up values.
27
+ - If you change anything under `src/`, bump `__version__` in `src/monash_study_kit/__init__.py` (last number for a fix, middle number for a feature) and add a line to `CHANGELOG.md`. CI checks this.
28
+ - Code comments and CLI messages are in Chinese, docs are in English with a Chinese README. Follow whatever the file you're editing already does.
29
+ - Bigger design choices go in [docs/adr](docs/adr) as a short record.
30
+
31
+ CI runs the tests on macOS, Windows and Linux with Python 3.10 and 3.13, runs ruff, and installs the built package into a clean venv to check that `monash` and the MCP server start.
32
+
33
+ Releases are made by the maintainer from a tag, see [docs/releasing.md](docs/releasing.md).
34
+
35
+ ## Code of conduct
36
+
37
+ This project follows the [Code of Conduct](CODE_OF_CONDUCT.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Waldo0926
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.