diff options
| author | Agando <roduccomm@gmail.com> | 2026-10-18 14:05:18 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-10-18 14:05:18 +0200 |
| commit | 88ad8ed2fbbda61920b11a79df29acb58928b5af (patch) | |
| tree | 7fd3df420ed78e59ccdc7861c7408347b207cfb5 /course/chapters | |
| parent | 005a1ad651383cca9793f24213de3a22c2474967 (diff) | |
newOS4: interactive AI course (terminal module, portal, atlas, telemetry, daily maintenance+cron) + free store card
Diffstat (limited to 'course/chapters')
| -rw-r--r-- | course/chapters/01-orientation.json | 132 | ||||
| -rw-r--r-- | course/chapters/02-architecture.json | 131 | ||||
| -rw-r--r-- | course/chapters/03-commands.json | 119 | ||||
| -rw-r--r-- | course/chapters/04-ai.json | 128 | ||||
| -rw-r--r-- | course/chapters/05-modules.json | 115 | ||||
| -rw-r--r-- | course/chapters/06-files-cloud.json | 132 | ||||
| -rw-r--r-- | course/chapters/07-automation.json | 134 | ||||
| -rw-r--r-- | course/chapters/08-build.json | 117 |
8 files changed, 1008 insertions, 0 deletions
diff --git a/course/chapters/01-orientation.json b/course/chapters/01-orientation.json new file mode 100644 index 0000000..165e140 --- /dev/null +++ b/course/chapters/01-orientation.json @@ -0,0 +1,132 @@ +{ + "id": "01-orientation", + "title": "Orientation β what newOS4 is", + "icon": "π", + "level": "beginner", + "lessons": [ + { + "id": "1.1", + "title": "A terminal in your browser", + "objective": "Understand what newOS4 is and run your first three commands.", + "minutes": 6, + "commands": [ + "help", + "status", + "ls" + ], + "blocks": [ + { + "type": "text", + "text": "newOS4 is a terminal-centric browser OS. Every command runs in your tab, files live in a virtual filesystem (VFS), and modules add commands at runtime." + }, + { + "type": "cmd", + "text": "help" + }, + { + "type": "text", + "text": "`help` lists every registered command grouped by the module that owns it." + }, + { + "type": "cmd", + "text": "status" + }, + { + "type": "cmd", + "text": "ls" + }, + { + "type": "tip", + "text": "The VFS survives reloads. Create a file with `touch notes.txt`, then run `ls`." + } + ], + "exercise": { + "instruction": "Run `status` and read the loaded-modules line.", + "accept": [ + "status" + ], + "check": { + "type": "command" + }, + "hint": "Type: status" + }, + "quiz": { + "q": "Where do files live in newOS4?", + "options": [ + "On the web server", + "In the browser VFS", + "In a SQL database" + ], + "answer": 1 + }, + "sources": [ + "modules/core/terminal.js", + "modules/core/virtual-fs.js" + ] + }, + { + "id": "1.2", + "title": "Finding your way around", + "objective": "Navigate the virtual filesystem and create your first file.", + "minutes": 8, + "commands": [ + "pwd", + "cd", + "tree", + "cat", + "touch" + ], + "blocks": [ + { + "type": "text", + "text": "The VFS is a tree rooted at `/`. `pwd` prints where you are, `cd` moves, `tree` shows the branch, `cat` prints a file." + }, + { + "type": "cmd", + "text": "pwd" + }, + { + "type": "cmd", + "text": "tree" + }, + { + "type": "warn", + "text": "`echo \"text\" > file` is NOT supported by the VFS. Use `touch`, the editor (`edit <file>`), or `webx11.fs.writeFile()` in the console." + }, + { + "type": "cmd", + "text": "touch hello.txt" + }, + { + "type": "cmd", + "text": "ls" + } + ], + "exercise": { + "instruction": "From the root, create `hello.txt` and list it.", + "accept": [ + "touch hello.txt", + "ls" + ], + "check": { + "type": "file", + "path": "/hello.txt" + }, + "hint": "Type: touch hello.txt β then ls" + }, + "quiz": { + "q": "Which command prints the current directory?", + "options": [ + "ls", + "pwd", + "cd" + ], + "answer": 1 + }, + "sources": [ + "modules/core/module-fs.js", + "modules/core/virtual-fs.js" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/02-architecture.json b/course/chapters/02-architecture.json new file mode 100644 index 0000000..7dee513 --- /dev/null +++ b/course/chapters/02-architecture.json @@ -0,0 +1,131 @@ +{ + "id": "02-architecture", + "title": "Architecture without the mystery", + "icon": "π", + "level": "beginner", + "lessons": [ + { + "id": "2.1", + "title": "Terminal, modules, commands", + "objective": "See how the terminal, module manager and command registry fit together.", + "minutes": 9, + "commands": [ + "modules", + "status", + "help" + ], + "blocks": [ + { + "type": "text", + "text": "`terminal.js` parses input and dispatches a command to the module that registered it. Each module owns a `commands` map and contributes help strings." + }, + { + "type": "cmd", + "text": "modules" + }, + { + "type": "text", + "text": "The module manager lists every loaded module and its command count." + }, + { + "type": "cmd", + "text": "status" + }, + { + "type": "text", + "text": "`status` shows files, modules and network state in one place." + }, + { + "type": "cmd", + "text": "check" + }, + { + "type": "tip", + "text": "A command that exists in `help` but fails at runtime usually has an unmet module requirement that `check` reports." + } + ], + "exercise": { + "instruction": "List the loaded modules.", + "accept": [ + "modules", + "status" + ], + "check": { + "type": "command" + }, + "hint": "Type: modules" + }, + "quiz": { + "q": "Who executes a command after you press Enter?", + "options": [ + "nginx", + "the module that registered it", + "the browser cache" + ], + "answer": 1 + }, + "sources": [ + "modules/core/terminal.js", + "modules/core/module-manager.js", + "modules/core/module-system.js" + ] + }, + { + "id": "2.2", + "title": "VFS and the three loading tiers", + "objective": "Understand where files live and why a module edit sometimes needs a rebuild and sometimes does not.", + "minutes": 10, + "commands": [ + "status", + "help", + "load-local" + ], + "blocks": [ + { + "type": "text", + "text": "Files live in `virtual-fs.js` (in-memory + localStorage persistence). Directories are nodes; `readFile()` returns `null` for a missing path." + }, + { + "type": "text", + "text": "Modules ship in three tiers:" + }, + { + "type": "table", + "text": "core-bundle.js β core modules (requires rebuild) | critical-ext-bundle.js β editor, shell, alias, finder, filemgr, diff, busybox (requires rebuild) | individually loaded ext modules β cache-busted by LATEST_VER (no rebuild)" + }, + { + "type": "cmd", + "text": "status" + }, + { + "type": "warn", + "text": "Individually loaded modules are cached with `?v=<webx11_cache_ver>`. Without bumping `LATEST_VER`, users keep the old file." + } + ], + "exercise": { + "instruction": "Run `status` and find the VFS size line.", + "accept": [ + "status" + ], + "check": { + "type": "command" + }, + "hint": "Type: status" + }, + "quiz": { + "q": "Which tier needs `rebuild-bundles.py` after an edit?", + "options": [ + "core-bundle.js", + "webdav.js", + "course.js" + ], + "answer": 0 + }, + "sources": [ + "modules/core/virtual-fs.js", + "modules/core/module-loader.js", + "scripts/rebuild-bundles.py" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/03-commands.json b/course/chapters/03-commands.json new file mode 100644 index 0000000..10807cb --- /dev/null +++ b/course/chapters/03-commands.json @@ -0,0 +1,119 @@ +{ + "id": "03-commands", + "title": "Command mastery", + "icon": "β¨", + "level": "beginner", + "lessons": [ + { + "id": "3.1", + "title": "Find any command fast", + "objective": "Use help, commands and check to discover what exists before guessing.", + "minutes": 7, + "commands": [ + "help", + "status" + ], + "blocks": [ + { + "type": "text", + "text": "`help` groups all 344 commands by the module that owns them." + }, + { + "type": "cmd", + "text": "help" + }, + { + "type": "cmd", + "text": "help webdav-push" + }, + { + "type": "tip", + "text": "`check` shows module requirements β the fastest way to explain a command that is listed but not working." + } + ], + "exercise": { + "instruction": "Open the help for `webdav-push`.", + "accept": [ + "help webdav-push" + ], + "check": { + "type": "command" + }, + "hint": "Type: help webdav-push" + }, + "quiz": { + "q": "Which command shows usage for one command?", + "options": [ + "help <cmd>", + "status", + "ls" + ], + "answer": 0 + }, + "sources": [ + "modules/core/module-system.js", + "modules/core/module-manager.js" + ] + }, + { + "id": "3.2", + "title": "Pipes, grep, sed, tail", + "objective": "Combine commands and understand the two semantics that bite: per-line sed and tail -f deltas.", + "minutes": 12, + "commands": [ + "grep", + "sed", + "tail", + "sort", + "head" + ], + "blocks": [ + { + "type": "text", + "text": "Pipes feed one command into the next. `grep` filters lines, `sed` substitutes text, `tail` prints the end of a file." + }, + { + "type": "cmd", + "text": "ls | grep txt" + }, + { + "type": "warn", + "text": "`sed s/x/y/` substitutes the first match per LINE, not per file. `sed -i` is flagged destructive and needs confirmation." + }, + { + "type": "text", + "text": "`tail -f` is interactive and stops with Ctrl+C. AI-initiated commands get a bounded read instead." + }, + { + "type": "cmd", + "text": "tail hello.txt" + } + ], + "exercise": { + "instruction": "Search the current listing for `txt`.", + "accept": [ + "ls | grep txt", + "grep txt" + ], + "check": { + "type": "command" + }, + "hint": "Type: ls | grep txt" + }, + "quiz": { + "q": "`sed s/a/b/` replacesβ¦", + "options": [ + "every match in the file", + "the first match on each line", + "only the last line" + ], + "answer": 1 + }, + "sources": [ + "modules/core/module-fs.js", + "modules/ext/shell.js", + "modules/core/terminal.js" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/04-ai.json b/course/chapters/04-ai.json new file mode 100644 index 0000000..3552c53 --- /dev/null +++ b/course/chapters/04-ai.json @@ -0,0 +1,128 @@ +{ + "id": "04-ai", + "title": "The AI assistant", + "icon": "π€", + "level": "intermediate", + "lessons": [ + { + "id": "4.1", + "title": "Ask, and let it use tools", + "objective": "Use the AI assistant and understand the confirmation boundary.", + "minutes": 9, + "commands": [ + "ai", + "ask", + "ai-config", + "ai-model" + ], + "blocks": [ + { + "type": "text", + "text": "`ai` and `ask` open the tool-calling assistant. It can read files, run safe commands and search the web." + }, + { + "type": "cmd", + "text": "ai what can you do?" + }, + { + "type": "text", + "text": "Destructive actions (writes, `sed -i`, deletes) require confirmation. AI-initiated commands run with a loop guard so they cannot recurse." + }, + { + "type": "cmd", + "text": "ai-model" + }, + { + "type": "cmd", + "text": "ai-config" + } + ], + "exercise": { + "instruction": "Ask the AI a short question.", + "accept": [ + "ai *", + "ask *" + ], + "check": { + "type": "command" + }, + "hint": "Type: ai \"hello\"" + }, + "quiz": { + "q": "What happens when the AI wants a destructive command?", + "options": [ + "runs silently", + "asks for confirmation", + "restarts the terminal" + ], + "answer": 1 + }, + "sources": [ + "modules/core/module-aiassist.js", + "modules/core/ollama-manager.js" + ] + }, + { + "id": "4.2", + "title": "Context, memory and skills", + "objective": "Inspect and clear context, then browse the skill library the AI retrieves from.", + "minutes": 8, + "commands": [ + "ai-context", + "ai-clear", + "skill-list", + "skill-validate", + "learn-skill" + ], + "blocks": [ + { + "type": "text", + "text": "The assistant keeps recent context. `ai-context` shows it; `ai-clear` resets it without touching your files." + }, + { + "type": "cmd", + "text": "ai-context" + }, + { + "type": "cmd", + "text": "skill-list" + }, + { + "type": "text", + "text": "Skills are markdown entries in `/skills/` indexed by `/skills/index.json`; `load_skills` retrieves them by query." + }, + { + "type": "cmd", + "text": "skill-validate course-01-orientation" + }, + { + "type": "tip", + "text": "This course installs its chapters as `course-*` skills, so the AI can teach what you are reading." + } + ], + "exercise": { + "instruction": "List the installed skills.", + "accept": [ + "skill-list" + ], + "check": { + "type": "command" + }, + "hint": "Type: skill-list" + }, + "quiz": { + "q": "Where does the skill index live?", + "options": [ + "/skills/index.json", + "/etc/skills", + "localStorage only" + ], + "answer": 0 + }, + "sources": [ + "modules/ext/skill-pack-core.js", + "modules/core/module-aiassist.js" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/05-modules.json b/course/chapters/05-modules.json new file mode 100644 index 0000000..4b68f42 --- /dev/null +++ b/course/chapters/05-modules.json @@ -0,0 +1,115 @@ +{ + "id": "05-modules", + "title": "Modules & packages", + "icon": "π§©", + "level": "intermediate", + "lessons": [ + { + "id": "5.1", + "title": "Browse and install modules", + "objective": "See what is loaded and install from the WebX11 package index.", + "minutes": 8, + "commands": [ + "modules", + "wpm", + "load-local" + ], + "blocks": [ + { + "type": "text", + "text": "`wpm` is the package manager for terminal modules: list the index, install a module from `packages.json` or a URL." + }, + { + "type": "cmd", + "text": "wpm list" + }, + { + "type": "cmd", + "text": "modules" + }, + { + "type": "text", + "text": "Every ext module in the default build auto-loads. There is no separate βneeds loadmodβ tier." + }, + { + "type": "cmd", + "text": "load-local modules/ext/calc.js" + } + ], + "exercise": { + "instruction": "List available packages.", + "accept": [ + "wpm list" + ], + "check": { + "type": "command" + }, + "hint": "Type: wpm list" + }, + "quiz": { + "q": "What does wpm install?", + "options": [ + "terminal modules", + "system packages", + "browser extensions" + ], + "answer": 0 + }, + "sources": [ + "modules/ext/wpm.js", + "packages.json", + "modules/core/module-loader.js" + ] + }, + { + "id": "5.2", + "title": "Module anatomy (a complete mini module)", + "objective": "Read the contract every module follows: class, commands map, help info, registration.", + "minutes": 12, + "commands": [ + "load-local" + ], + "blocks": [ + { + "type": "text", + "text": "A module is a class with `commands`, `registerCommands()`, `getHelpInfo()` and optionally `init(terminal)`. The module manager injects `terminal` before calling `registerCommands()`." + }, + { + "type": "code", + "text": "class HelloModule {\n constructor(){ this.commands = {}; }\n getHelpInfo(){ return { hello: 'hello β print a greeting' }; }\n registerCommands(){ this.commands['hello'] = () => this.terminal.print('hello newOS4'); }\n}" + }, + { + "type": "tip", + "text": "Tier-3 modules register at the end with `webx11.moduleManager.registerModule(new HelloModule(), url)`." + }, + { + "type": "cmd", + "text": "modules" + } + ], + "exercise": { + "instruction": "Open the module list and find a module you have not used.", + "accept": [ + "modules" + ], + "check": { + "type": "command" + }, + "hint": "Type: modules" + }, + "quiz": { + "q": "What does the module manager inject before registerCommands()?", + "options": [ + "the terminal", + "the database", + "nothing" + ], + "answer": 0 + }, + "sources": [ + "modules/core/module-manager.js", + "modules/ext/kanban.js" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/06-files-cloud.json b/course/chapters/06-files-cloud.json new file mode 100644 index 0000000..697a5f5 --- /dev/null +++ b/course/chapters/06-files-cloud.json @@ -0,0 +1,132 @@ +{ + "id": "06-files-cloud", + "title": "Files, editor, WebDAV", + "icon": "β", + "level": "intermediate", + "lessons": [ + { + "id": "6.1", + "title": "Edit and compare files", + "objective": "Use the editor and diff tools on the VFS.", + "minutes": 9, + "commands": [ + "edit", + "diff", + "find", + "files" + ], + "blocks": [ + { + "type": "text", + "text": "`edit` opens the VFS editor. `diff` compares two files. `find` searches names; `filemgr` opens the visual browser." + }, + { + "type": "cmd", + "text": "edit hello.txt" + }, + { + "type": "cmd", + "text": "find hello" + }, + { + "type": "cmd", + "text": "diff hello.txt hello.txt" + }, + { + "type": "tip", + "text": "The editor calls the tutorial/file-saved hook, so exercise progress can be detected from a save." + }, + { + "type": "cmd", + "text": "files" + } + ], + "exercise": { + "instruction": "Search for your file by name.", + "accept": [ + "find hello", + "find hello.txt" + ], + "check": { + "type": "command" + }, + "hint": "Type: find hello" + }, + "quiz": { + "q": "Which command opens the visual file manager?", + "options": [ + "filemgr", + "ls", + "cat" + ], + "answer": 0 + }, + "sources": [ + "modules/ext/editor.js", + "modules/ext/diff.js", + "modules/ext/filemgr.js" + ] + }, + { + "id": "6.2", + "title": "Cloud sync and login", + "objective": "Understand WebDAV auth, the space token, and the 401 self-heal path.", + "minutes": 14, + "commands": [ + "webdav-login", + "webdav-config", + "webdav-status", + "webdav-push", + "webdav-backup" + ], + "blocks": [ + { + "type": "text", + "text": "WebDAV syncs your VFS to your space. The module holds a SPACE token, not your personal token; it refreshes on 401." + }, + { + "type": "cmd", + "text": "webdav-status" + }, + { + "type": "cmd", + "text": "webdav-login" + }, + { + "type": "warn", + "text": "Sessions do not cross browser contexts. If a push 401s, run `webdav-login` in THIS browser, then retry." + }, + { + "type": "cmd", + "text": "webdav-push" + }, + { + "type": "cmd", + "text": "webdav-backup" + } + ], + "exercise": { + "instruction": "Check the WebDAV status.", + "accept": [ + "webdav-status" + ], + "check": { + "type": "command" + }, + "hint": "Type: webdav-status" + }, + "quiz": { + "q": "A 401 push usually meansβ¦", + "options": [ + "the file is too big", + "no session/token in this browser context", + "WebDAV is disabled" + ], + "answer": 1 + }, + "sources": [ + "modules/ext/webdav.js" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/07-automation.json b/course/chapters/07-automation.json new file mode 100644 index 0000000..3345fc2 --- /dev/null +++ b/course/chapters/07-automation.json @@ -0,0 +1,134 @@ +{ + "id": "07-automation", + "title": "Automation", + "icon": "β", + "level": "advanced", + "lessons": [ + { + "id": "7.1", + "title": "Schedule commands with cron", + "objective": "Run a command on an interval and manage the schedule.", + "minutes": 8, + "commands": [ + "cron-every", + "cron-list", + "cron-stop", + "cron-clear" + ], + "blocks": [ + { + "type": "text", + "text": "`cron-every` schedules a command inside the terminal (minimum 5 seconds). Jobs live only while the tab is open." + }, + { + "type": "cmd", + "text": "cron-every 60 echo hello" + }, + { + "type": "cmd", + "text": "cron-list" + }, + { + "type": "cmd", + "text": "cron-stop 1" + }, + { + "type": "cmd", + "text": "cron-clear" + }, + { + "type": "tip", + "text": "For server-side schedules use Hermes cron; the terminal scheduler is per-tab." + } + ], + "exercise": { + "instruction": "List active cron jobs.", + "accept": [ + "cron-list" + ], + "check": { + "type": "command" + }, + "hint": "Type: cron-list" + }, + "quiz": { + "q": "How long does a terminal cron job live?", + "options": [ + "forever on the server", + "while the tab is open", + "until reboot" + ], + "answer": 1 + }, + "sources": [ + "modules/ext/cron.js" + ] + }, + { + "id": "7.2", + "title": "Kanban and checkpoints", + "objective": "Track work on a board and snapshot the VFS before risky changes.", + "minutes": 8, + "commands": [ + "kanban", + "checkpoint", + "checkpoint-list", + "rollback" + ], + "blocks": [ + { + "type": "text", + "text": "`kanban` is a local board with todo/doing/done columns. `checkpoint` snapshots the VFS; `rollback` restores it." + }, + { + "type": "cmd", + "text": "kanban add \"Try the course\"" + }, + { + "type": "cmd", + "text": "kanban list" + }, + { + "type": "cmd", + "text": "checkpoint before-project" + }, + { + "type": "cmd", + "text": "checkpoint-list" + }, + { + "type": "cmd", + "text": "rollback before-project" + }, + { + "type": "warn", + "text": "`rollback` replaces current VFS state β checkpoint before experiments." + } + ], + "exercise": { + "instruction": "Create a checkpoint.", + "accept": [ + "checkpoint *", + "checkpoint" + ], + "check": { + "type": "command" + }, + "hint": "Type: checkpoint my-test" + }, + "quiz": { + "q": "What does checkpoint do?", + "options": [ + "snapshots the VFS", + "deletes files", + "pushes to WebDAV" + ], + "answer": 0 + }, + "sources": [ + "modules/ext/kanban.js", + "modules/core/module-fs.js" + ] + } + ] +}
\ No newline at end of file diff --git a/course/chapters/08-build.json b/course/chapters/08-build.json new file mode 100644 index 0000000..48a60bd --- /dev/null +++ b/course/chapters/08-build.json @@ -0,0 +1,117 @@ +{ + "id": "08-build", + "title": "Build & extend", + "icon": "π§", + "level": "advanced", + "lessons": [ + { + "id": "8.1", + "title": "Add a command safely", + "objective": "Follow the edit β syntax β test β rebuild β version-bump loop.", + "minutes": 12, + "commands": [ + "load-local", + "status", + "help" + ], + "blocks": [ + { + "type": "text", + "text": "Edit the source, run `node --check`, run the relevant test harness, rebuild bundles for tiers 1β2, then bump BOTH `main.html` and `LATEST_VER`." + }, + { + "type": "cmd", + "text": "status" + }, + { + "type": "cmd", + "text": "help load-local" + }, + { + "type": "warn", + "text": "Editing a tier-3 module without bumping `LATEST_VER` means users keep the stale cached file indefinitely." + } + ], + "exercise": { + "instruction": "Run the built-in test suite.", + "accept": [ + "status" + ], + "check": { + "type": "command" + }, + "hint": "Type: test auto" + }, + "quiz": { + "q": "Which two places carry the version?", + "options": [ + "main.html and LATEST_VER", + "package.json only", + "localStorage" + ], + "answer": 0 + }, + "sources": [ + "scripts/rebuild-bundles.py", + "modules/core/module-loader.js" + ] + }, + { + "id": "8.2", + "title": "Debug and observe", + "objective": "Use the debug panel, console and health checks when something breaks.", + "minutes": 8, + "commands": [ + "debug", + "health-check", + "js" + ], + "blocks": [ + { + "type": "text", + "text": "`debug` toggles the runtime debug panel; `console` opens a JS console in the terminal; `health-check` audits VFS, modules, logs and skills." + }, + { + "type": "cmd", + "text": "health-check" + }, + { + "type": "cmd", + "text": "debug" + }, + { + "type": "tip", + "text": "Errors are posted to `/spaces/newos4/api/debug/ingest.php` and clustered in the debug dashboard." + }, + { + "type": "cmd", + "text": "js 1+1" + } + ], + "exercise": { + "instruction": "Run a health check.", + "accept": [ + "health-check" + ], + "check": { + "type": "command" + }, + "hint": "Type: health-check" + }, + "quiz": { + "q": "Where do runtime errors get ingested?", + "options": [ + "/api/debug/ingest.php", + "/dev/null", + "localStorage" + ], + "answer": 0 + }, + "sources": [ + "modules/ext/debug-panel.js", + "modules/core/module-debug-supervisor.js", + "api/debug/ingest.php" + ] + } + ] +}
\ No newline at end of file |