Hi all,
A lot has happened with Tsugi in terms of making Tsugi a more solid product for the long term over the past two months. Here is a summary:
- I built a tool I call AI paper that talks to an LLM backend (the protocol for this is a little fragile at this point) so you can make an assignment that is peer graded and one of the peers is an LLM with an instructor defined prompt - this tool is kind of emergent - I will use it this semester in two of the classes I am teaching to make it more solid both technically and pedagogically.
I added an encoded settings feature for the AI endpoint and key that can be placed at the tenant, course, or link to protect your LLM API integration info.
- I greatly upgraded the badge support. Tsugi now supports OBI2 and OBI3 and has its own LinkedIn integration. Check out my sweet badge:
You can earn your own on
www.py4e.com and add it to linkedin. Still a bit more work to do - my logo is not showing up - bit I will get there :)
- I added an Announcements tool, Pages tool, some of my sites allow for editing the front page of the web site using the pages tool. There is now a Announcements bell when logged in. You can see this the Pages tool and announcements notification bell by logging in to
www.ca4e.com note that the front page now has text I can edit without updating my site in githhub.
- I added the ability to get mailing lists of recently logged in users for a course that is running in a site like
www.ca4e.com
- I deprecated, then removed all support for SQLite and PostgreSQL - it never worked anyways and it was a lot of code that kind of made a lot of the SQL handing code (i.e. like PDOX) unnecessarily complex. As I want AI to really understand this code base PostgreSQL and SQLite were becoming red herrings and distracting the AI as it fixed code or added features.
- I built a completely new user interface for Lessons - It allows arbitrary reordering of the content types - this follows the pattern of Sakai’s Lessons and Canvas’ Modules - it includes headers. This new format exports better to Canvas and imports more cleanly into Canvas and Sakai since the data models are better aligned.
- I built a Lessons authoring interface that allows adding, editing, and reordering lesson items. At this point, the lessons json is still stored in github so the authoring environment only works on localhost (yes, weird - but it is a stepping stone ;) ). Screen shot below.
- I also added progress tracking to Lessons - it tells you how far you are done with each module in Lessons. Screen shot attached.
- Improved the Common Cartridge export to Canvas. I last used the Tsugi->Canvas export / import process three years ago and it worked great - Canvas handled standard stuff in the cartridge. Now Canvas broke it all and demands proprietary stuff for LTI to work. I made as many improvements as I could so I could import into Canvas. It works better for everything except LTI. But things lik headers and other structure and ordering - all come in very nicely with Canvas. You just have to patch assignment LTI things because Canvas now looks for proprietary structures in CC's to make LTI links work. Grrr. But other than LTI, the import is better now than it was in the Fall.
- Thanks to Sam Ottenhoff, we have PHPStan working to scan the code and greatly improve the validation that is run upon checkin. If we commit something that breaks it will tell us before we merge the PR :) A good reason to start using branches and PRs for bigger things
- Thanks to Sam and Matt Jones there is a GitHub commit hook to start a docker, run Tsugi and do some smoke testing upon each checkin.
- Thanks to Sam we have Symfony Panther working using a headless browser to run QA tests on each check in. You can run them from a command line and watch them in a browser.
- We went from < 100 unit tests to > 300 unit tests thanks to AI and Sam.
I also changed how the code base is managed. From the beginning of time there were three repositories:
There were three repos so the main code could import the reusable library code (tsugi/lib) as a packagist artifact without pulling all the UI code which lived in the tsugi repo. As I built UI features like lessons and badges I put them into koseu-php and also released them to packagist. I had a dream that you could just add two artifacts via composer and add an LMS to any php-based web site.
It kind of worked. The tsugi/lib turns out to be more useful that the koseu/lib and the koseu/lib was never really used outside of a ful checkout of the tsugi repo.
Also it turns out that ten years ago when git was just coming out monorepos and subtrees were dangerous not well supported. For a good time ask ChatGPT to tell you
"Why was git subtree so bad in the early days of git. Was it because git wanted to *not* be like svn (which we loved back in the day)? How did subtree support start out in git and how well does it work today?”
So back when Tsugi started, instead of using subtrees, I made three repos and use duct tape - which was a good decision at the time. It is no longer a good decision. I pulled the koseu-php repo into tsugi/koseu and tsugi-php repo into tsugi/lib as subtrees, removing both from the vendor folder retaining commit history The subtree approach allows for pushing commits from the tsugi repo back to the other two repos to keep packagist happy. Subtrees now work perfectly.
This monorepo approach to tsugi is great - it means we can start using PRs in the Tsugi repo to make changes in both the main trusig code, the lib code, and the koseu code. Using PR’s means all of the Sam / Matt check in magic will be done to the PR before we merge it.
Going forward this is not the end for Tsugi - It was just a lot of catching up of tech debt that accumulated over a decade of the life of the Tsugi project (since September 2013).
Starting February 2026, I will be teaching an online course using only Tsugi at
www.ca4e.com using the new LMS features I added to Tsugi. That course will lead me down a path to improve things like the announcements, discussions, pages, badges, and lessons activity tracking based on my experiences with real students.
The future direction is to turn Tsugi in to a real (albeit small) LMS with the ability to author multiple courses without JSON and associate multiple rosters with those courses to make multiple course sections. The new use case would be in effect a “Wordpress LMS” where you check Tsugi out into a PHP + MySQL environment, create or import a course, and start teaching. Take a look at
online.dr-chuck.com and that shows a hand-constructed course catalog - imagine for a moment that the tsugi next generation could author and teach all those courses on one platform.
In the shorter term, I will be getting rid of the Lumen dependency, advancing the dependency versions, and supporting PHP 8.5 by summer. Initial scans of the code base suggest PHP 8.5 is not too bad.
I would add that all of the above changes *should* not break any of your current uses of Tsugi - if you are near master and upgrade to master - things should just keep working. I have 20+ sites with tsugi embedded - If I broke something I will keep it first and fix it. I am committed to staying upwards compatible.
If I break anything - let me know. If you are interested in using any of these new features - let me know.
/Chuck