aboutsummaryrefslogtreecommitdiff
path: root/modules/test
Commit message (Collapse)AuthorAgeFilesLines
* fix(newos4): agent registration is absolute-path and honest about what it storedAgando12 days1-0/+93
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three of the four agent-cluster items, each with a test that is red on HEAD. - MAINT-008 (module-agent-registry.js + module-orchestrator.js): registerAgent took args[0] as the agent id and only args[1] as the capability list, while both orchestrator callers passed the command word first — so the boot log read "Agent 'register' registered with 1 capabilities" and four capabilities were stored as one. The command word is now stripped, args[1..] are joined and split on commas (both "a,b" and "a b c" work), and the callers pass [id, ...caps]. - MAINT-007 (registry + aiassist): mkdir/rm used relative paths, so a registration made from /docs created /docs/agents/<id> and an unregister from any other cwd removed nothing — the leaked directories the report suspected. Every path in the registry (and the four /_sessions writes in module-aiassist.js) is absolute now. - MAINT-009 (listAgents): a directory alone counted as a registered agent, so a hand-made /agents/foo appeared as "foo — unknown (0 capabilities)". Only a readable status.json with an id counts now; the rest are reported as unregistered directories. Verification: test-agent-registry.js (11 asserts). RED on HEAD: 9 of 11 fail, including the exact `✅ Agent 'register' registered with 1 capabilities` line and `hand-made — unknown (0 capabilities)`. Suite 15/15 files green; maintain --fix "node tests 15/15 pass". Live on v4.6.109: boot prints "✅ Agent 'orchestrator-0' registered with 4 capabilities"; `agent-list` warns "1 directory(ies) in /agents have no status.json (not registered): hand-made"; register from / with a comma list stores 3; unregister from /docs removes the directory and leaves no /docs/agents. MAINT-006 stays open with a narrower note: the hard stop was only reachable when every call in a batch was blocked, so a mixed batch (one repeated + one novel call) never ended. The same ceiling now applies on the mixed path, but that branch lives inside agenticLoop and is not covered by a unit test — it needs a live agent run that repeats a call.
* fix(newos4): help names the owner of an undocumented command; loop lessons ↵Agando12 days1-0/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | leave /skills Two board items plus the context-window close-out. - MAINT-019 (module-system.js): `help <cmd>` answered "No help available for X" for a command that is registered but has no help line, which reads as if the command does not exist. It now says "X — registered by <Module>, which publishes no help line for it. Try: help". A command that genuinely does not exist still gets the old message. - MAINT-020 (module-aiassist.js): auto-generated loop lessons were written into /skills with their own index entries, so `skill list` filled up with system noise. Lessons now live in /lessons with /lessons/index.json; the reader still falls back to legacy loop-lesson-* entries in /skills for one release, and the one-time migration deletes them from the skills index. Verification: test-help-and-lessons.js (10 asserts, includes a lint-style guard that no lesson is written into /skills). Suite 14/14 files green; maintain --fix "node tests 14/14 pass", "help coverage 362/362". Live on v4.6.108: `help agent-register` -> "registered by AgentRegistryModule, which publishes no help line for it"; `help a2a-prune` unchanged; `help nope-not-real` still "No help available". MAINT-001 close-out (no code change here): history is capped at 20 messages with a "[context trim]" marker (first trim at turn 11 in a 60-turn probe), token compression took 80 msgs/8080 tok to 17/2625, and since v4.6.107 one turn's tool bodies are clipped to 6 000 chars each and elided past 24 000 with the newest 4 kept verbatim. Residual, recorded on the board: maxContextTokens is never sent to the server as num_ctx, so the real window is whatever the endpoint defaults to. MAINT-018 close-out: not reproducible. Live probes on v4.6.107/108 — `sed -n '1,3p' /probe.txt` prints lines 1-3, `sed -n "2,4p"` prints 2-4, `grep 'line4'` matches, and the same commands inside `script /q.sh` print correctly. The "Command not found: for;" symptom belongs to the line-by-line script runner, which is MAINT-021 and stays open.
* fix(newos4): bound one turn's tool context, honest skill-create, quarantine ↵Agando12 days3-0/+283
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a corrupt memory graph The three items the last review and probes left open, each with a test that is red on HEAD. - MAINT-023 (module-aiassist.js): one agentic turn grew without limit — every role:'tool' body was pushed verbatim and only this.context was trimmed BETWEEN turns (measured 6 -> 112 705 tokens across 8 model calls against maxContextTokens 12 000). Observations are now clipped to maxToolResultChars (6 000) with a note saying how much was withheld and to re-read with offset/limit, and _boundToolContext() elides the oldest tool bodies once the running total passes toolContextBudgetChars (24 000), always keeping the newest 4 verbatim. The ceiling is turn-independent: the same ~26 k chars at 8 turns and at 20. - MAINT-024 (modules/ext/skill-pack-core.js): the command printed "✅ Skill created" with fs.writeFile()'s boolean discarded (probe: fresh VFS, success printed, no file), stripped invalid characters instead of rejecting the name (My-Skill -> y-kill, DevOps_Thing -> evpshing), and treated an unreadable /path argument as the skill body. Now: kebab-case is validated (uppercase normalises and the final name is reported; anything else is refused), /skills is created on first use, the write and index results are checked, and an unreadable body path is an error. - MAINT-003 (module-memory-graph.js): a corrupt store looked exactly like a fresh install — fsReadJSON returns null on a parse failure, so 85 nodes could vanish with no warning and no copy. The probe confirmed the loss: seed 6 nodes, truncate nodes.json and export.json, reload -> 1 node, no message, nothing in .trash. _quarantineCorrupt() now keeps the unreadable file as <name>.corrupt, warns, and then loads from whatever remains. Tests: test-tool-context-bound.js (11), test-skill-create.js (16), test-memory-graph-recovery.js (8). RED on HEAD: tool-context crashes on _clipToolResult (exit 1), skill-create 16 assertions fail on the missing file/index, memory-graph B1/B2/C1 fail (no warning, no .corrupt copy). Suite now 13/13 files green; maintain --fix reports "node tests 13/13 pass". Live on v4.6.107: skill-create My-Skill -> ✅ "my-skill"; DevOps_Thing -> Invalid skill name; /does/not/exist.md -> Cannot read skill body; only my-skill in the index.
* fix(newos4): name the real Ollama failure, bound auto-connect, fix the ↵Agando12 days3-1/+199
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | review findings Second pass over v4.6.105, driven by an independent review that reproduced each item. - ollama-manager.js: chat() now reports the captured cause ("Ollama error: Failed to fetch", "…: HTTP 500") instead of the generic "No provider responded"; _lastChatError is reset per call so an old reason is never replayed. chatWithTools carries the reason in its error string. - ollama-manager.js: _ensureConnected() bounds connect() with a deadline (connectTimeoutMs, default 10 s). connect() uses a bare fetch(), so a blackholed endpoint previously left the shared in-flight promise pending forever and hung every later message — the old code failed fast. The attempt is now try/finally, so a throwing terminal.log() can no longer poison _connecting and suppress the retry on the next message. - ollama-manager.js: an automatic connect no longer silently rewrites the user's saved model; the previous choice is restored in memory and in localStorage, and the user is told. - ollama-manager.js: the DeepSeek empty-content branch returned top-level tool_calls with content '', so the caller pushed an assistant message with no tool_calls and then a role:'tool' reply — an orphan tool message, which is the HTTP 400 that branch exists to prevent. tool_calls now live inside the message as well. - module-aiassist.js: a no-argument list_files returned the ROOT instead of the cwd (readDir('/') instead of ls()); it now means the current directory again. Error text keeps the path as the caller wrote it, and write_file distinguishes a read-only virtual path (/sys/…) from a missing parent instead of blaming the parent. Tests: test-ollama-error-text.js (new, 14 asserts, RED 9/5 before the edit), test-ai-fs-tools.js 7 → 16 asserts (write onto a directory, /sys write, list a file, '/', no-arg cwd, relative path), test-ollama-autoconnect.js 11 → 19 (blackholed endpoint settles + retries, saved model survives; the old "connecting hint" assertion is now falsifiable — the reviewer showed it also matched connect()'s pre-existing line). Suite: 10/10 files green. Live on v4.6.106: healthy auto-connect 42 ms with the hint; blackholed endpoint settles in 1242 ms with connectTimeoutMs=1200, prints "timed out" and "unreachable", _connecting cleared.
* fix(newos4): connect to Ollama on first use, honest write_file, list_files ↵Agando12 days2-0/+172
| | | | | | | | | | | | | | | | | | | | | | | | | | | sees /sys Three defects, each re-probed first and covered by a test that is red on HEAD. - ollama-manager.js: nothing connects at boot; only the Ollama tab button called connect(), so a user's first message died with "Ollama not connected. Use ollamaconnect first." even when the endpoint was healthy. New _ensureConnected() runs from chat(), chatStream() and chatWithTools(): one attempt, shared by concurrent callers, a "Connecting…" hint, and only then the error — which now says the endpoint is unreachable instead of telling the user to run a command they already expected to work. - module-aiassist.js write_file tool: fs.writeFile()'s false return was dropped and the tool answered "File written: …" anyway, sending the model on to a read that found nothing (MAINT-012). It now returns "Write FAILED: … — parent directory missing or target is a directory; nothing was written". - module-aiassist.js list_files tool: the hand-rolled walk over root.content never resolved the virtual mounts, so /sys — a directory the UI and `ls` both show — answered "Directory not found" (MAINT-011). It now uses fs.readDir(), which resolves mounts and returns null for a genuinely missing path. Tests: modules/test/test-ai-fs-tools.js (7 asserts) and modules/test/test-ollama-autoconnect.js (11 asserts). RED on HEAD: ai tools 4 passed/3 FAILED (/sys → "Directory not found", write_file → "File written: …"), ollama 2 passed/9 FAILED ("Use ollamaconnect first"). GREEN now 7/7 and 11/11; maintain --fix reports "node tests 9/9 pass". Live on v4.6.105: connectedBefore=false, _ensureConnected()=true in 41 ms, 37 models.
* fix(newos4): never overwrite a directory node; ls honours a path after its flagsAgando12 days1-0/+109
| | | | | | | | | | | | | | | | | | | | | MAINT-010 and MAINT-016, the two high items the review left open. Both were re-probed before the change and the new test is red on HEAD (5 passed, 7 FAILED). - virtual-fs.js rename()/copy(): they assigned dst.dir.content[dst.name] with no destination type check, so `mv file /docs` replaced the /docs node and every child vanished while the command printed "Moved: …". Refuse when the destination is a real directory node (the virtual /sys entry is exempt). rename() also erased the file on `mv a a`, because assigning and then deleting the same key removes it; that path is now an explicit no-op. - module-fs.js mv/cp: a refusal used to surface as "No such file or directory", which sent the operator looking for a missing source. The destination is now inspected first and the message says "is a directory — refusing to overwrite it". - module-fs.js ls: the path was only read from argv[0], so `ls -l /work` listed the cwd. The first non-flag argument is now the target; the path-first form is unchanged. Tests: modules/test/test-fs-mv-cp-guard.js (12 asserts) — RED on HEAD (A1-A3, B1, B2, C2, E1), GREEN now; maintain --fix reports "node tests 7/7 pass". Browser on v4.6.104: "mv: /vtest: is a directory — refusing to overwrite it", child and source intact, "ls -l /vtest" lists /vtest (keep.txt), not the cwd.
* fix(newos4): rollback keeps scaffolding, checkpoints cannot collide, tests ↵Agando12 days2-0/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | gate the build Review of the 08:30 implementer run (v4.6.102, checkpoint name fix). The shipped fix was correct; these are the defects it introduced or left behind, each measured first. - virtual-fs.js rollback(): the snapshot strips _snapshots/_sessions/.trash for bloat. Restoring it verbatim deleted every checkpoint, every agent session and the trash, made rollback irreversible and unrepeatable. Re-attach the live copies after the root swap. - checkpoint(): names are millisecond-resolution, so tight calls overwrote each other (measured 6 calls -> 3 snapshots). Dedupe with a -N suffix, refuse names containing "/" (written but unlistable), and prune by snapshot createdAt instead of filename sort, which let a custom name ("aaa-oldest") evict newer auto-named checkpoints. - module-predictor.js: legacy pre-v2 points have no `usable`, so a 0.079 s aborted run re-entered similarity as evidence and floored every prediction at 1 s. Backfill `usable` from the measurement on load, drop the ones it rejects, add a belt-and-braces guard in _findSimilar and count only usable points as actual executions. - newos4-maintain.py: run every node-runnable modules/test/test-*.js on each maintenance pass. The v4.6.102 regression was written but no job ever executed it. - newos4-steer.py: `done` now requires --commit <sha> that exists in the repo, and gains `reopen`. A written plan was being closed as done at 06:17 while the predictor fix shipped nowhere, so the implementer's pre-flight queue was empty. - steering.json: predictor item reopened, checkpoint item stamped with f7249ff. - maintenance board: MAINT-002/005/015 were fixed in v4.6.81-85 but still listed open/high; closed with their commit ids, and MAINT-010/016 annotated with the probes that keep them open. Tests: test-vfs-checkpoint 23/23 (RED 14/9 before), test-predictor-accuracy 38/38 (T1-T3 RED on HEAD), maintain --fix all PASS, browser round-trip "Checkpoint created: <name>" -> "Rolled back to checkpoint: <name>" on v4.6.103. Also carries the already-deployed 2026-10-26 syntax-gate hunk in newos4-maintain.py (syntax_failures + gated rebuild) that had never been committed.
* fix(newos4): regression test for checkpoint name round-trip (auto)Agando12 days1-0/+92
| | | | | | | | | | | | | | | | | | | | | Task 3 of plan 2026-10-27_061724-newos4-checkpoint-name-mismatch.md. New modules/test/test-vfs-checkpoint.js loads the real VirtualFileSystem and SystemModule with guarded localStorage/indexedDB/window stubs and asserts: A1-A4 checkpoint('') returns the resolved name; two calls differ; the file exists under the returned name B1-B2 checkpoint-list shows the returned name; rollback(<that name>) is true C1-C4 the `checkpoint` command prints exactly the name it created (and an explicit name verbatim) RED before the fix (v4.6.101): FAIL C2 printed name exists on disk — printed=2026-10-27T07:31:21.575Z listed=["2026-10-27T07:31:21.574Z"] test-vfs-checkpoint: 2 passed, 8 FAILED GREEN after: $ node modules/test/test-vfs-checkpoint.js test-vfs-checkpoint: 10 passed, 0 failed
* feat(newos4): mobile download/share UX — deferred blob revoke, ↵Agando13 days1-17/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | multi-select, Web Share, 44px targets Executes .hermes/plans/2026-10-24_051600-newos4-mobile-download-share.md (approved via the feedback dashboard; marker autonomy: safe). Front-end only, v4.6.94 -> v4.6.95. T1 modules/ext/filemgr.js — URL.revokeObjectURL ran in the same tick as a.click(); iOS Safari and Android Chrome hand the blob: URL to the download manager asynchronously, so the transfer was aborted while the status line still said "Downloaded". Now revoked after 30 s. T2 download honours the multi-selection via _getSelectedPaths() (falling back to _selectedFile), reports "⬇ Downloaded N files" and "❌ Skipped <path>" instead of a silent partial success. T3 share: navigator.share -> clipboard.writeText -> inline read-only <input> (focused, selected). prompt() is suppressed in iOS standalone PWAs and most Android WebViews, which is why tapping 🔗 did nothing. Unresolvable space now reports "🔗 Share unavailable — no space resolved". T4 both preview toolbar buttons: min-height/min-width 44px, touch-action manipulation, 1em, gap 10px (was 24px/0.85em/6px — the smallest tap targets in the UI). T5 _previewShareUrl falls back _resolveSpaceName -> _detectSpaceName (webdav.js:22) -> page path, and returns null rather than emitting /spaces//<path>. T6 the URL helpers are now module-scope pure functions exported for Node, so modules/test/test-download-url.js tests the shipped code instead of a local copy (4 -> 6 cases). Also fixes a latent bug that made require() impossible: `typeof window.webx11` throws under Node because typeof does not protect a member access on an undefined global. Verified on the served bundle (filemgr.js is concatenated into critical-ext-bundle.js, NOT core-bundle.js — the plan's T7 grep pointed at the wrong file): HTTP 200, 129 867 B, 2x navigator.share, 3x fmBuildShareUrl, deferred revoke present, 11x min-height:44px. Live browser probe on /spaces/newos4/main.html: _previewShareUrl('docs/a.md') -> https://webx11.duckdns.org/spaces/newos4/docs/a.md (no double slash); with navigator.share absent and clipboard blocked, clicking 🔗 produced .fm-share-input containing that URL; button style ends min-height:44px;min-width:44px;touch-action:manipulation; toolbar gap:10px. node modules/test/test-download-url.js -> 6 PASS. lint-no-undef clean (55 files). maintain: PASS version v4.6.95 x3, syntax OK, HTTP 200 /main.html. Also adds admin/docs/session-overview-2026-10-26.md (glm-5.3-compressed session record).
* fix(newos4): predictor arithmetic, deployed-source viewer, ls text output ↵Agando2026-10-231-1/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (v4.6.57) Acting on the "Request to the newOS4 team" packet (spaces/agando/guides/, re-verified by its author on 4.6.56). Three verified defects fixed: Packet 5 (predictor arithmetic) - module-predictor.js - the persisted field named mape held a SUM while predictor-status divided by the paired count: renamed to errorSum, older payloads read through - errorPct is stored raw; the 500% clamp is now render-only, so a 475x miss stays visible instead of being flattened to the ceiling - predictions are floored at 1 s and marked floored; a floored prediction is consumed but never scored as 100% error (a 0 s prediction is not a prediction) - observations shorter than 1.5 s (aborted/instant runs) are marked unusable and no longer train _findSimilar - one 0.079 s run was rounding the next prediction to 0 s - status prints an unpaired and an unscored count alongside the mean Packet 10 (verification cannot see its own fixes) - module-aiassist.js - view_module now returns the DEPLOYED source, prefixed with file and version, and only falls back to the _mods copy with a "may be stale" banner. The unversioned _mods/<Class>.js edit cache used to shadow the deployed file forever, so the viewer showed pre-fix code while the bundle was new. Proven by seeding a stale _mods/PredictorModule.js and calling the tool. Packet 1b (ls exits clean with no output) - module-fs.js - ls rendered only via printClickable(), which writes straight to the DOM, so any capture (AI run_command, diagnostics) saw an empty result and reported "empty directory". It now always prints a text line and keeps the clickable chips when nothing is capturing. Test: modules/test/test-predictor-accuracy.js 34/34 (new cases Q, R, S).
* fix(newos4): measure predictor accuracy over paired predictions (v4.6.56)Agando2026-10-231-0/+209
| | | | | | | | | | | | | | | | | | | | | | | | | The accuracy readout was structurally 0%: module-predictor.js:187 incremented the denominator on every observed run while the numerator only moved when a stored prediction existed, and predictions were stored only by the manual `predict` command (the AI tool predict_task computed one and discarded it). Replaying the AI loop's own call path with 6 tasks printed "Predictions made: 0, Accuracy: 0/6". - pending predictions with a 15m TTL, consumed by threaded id -> task hash -> cli-only similarity >= 0.5; unpaired runs never enter the denominator - duration scored within 30% or 3s (integer predictions vs fractional observations) - errorPct capped at 500% so one miss cannot poison the mean error - schema v2: v1 correct/total counters dropped on load, observed runs and the prediction counter kept; task text stored as an FNV-1a hash only - tuning (confidence-threshold, min-data-points, pair-ttl) persists - min-data-points now scales confidence (was declared, printed, settable, unread) - AI loop registers a prediction per turn and threads its id; predict_task returns predictionId; durations exclude chat-lock queue wait - status/dashboard say "n/a" instead of "N/A%", and carry paired count, mean error, turns error, pending and unpaired counts - test: modules/test/test-predictor-accuracy.js (26 assertions) Live on main.html v4.6.56: fresh session -> "Accuracy: n/a (0/0 paired)"; one paired run -> "100% (1/1 paired) - mean error 5% - turns +-0.0".
* fix(newos4): empty-pipeline crash, stacks in reports, frame in digest + ↵Agando2026-10-231-0/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | dashboard (v4.6.55) Root cause: splitPipe() splits on every '|', so `help |`, `| wc -l`, `a || b` produced a stage with no argv and executePipeChain() called parts[0].toLowerCase() on undefined — 989 occurrences, first filed 2026-10-20, unfixable from the report because bug reports dropped the stack that named executePipeChain:3955. Same unguarded read existed in _classify(). - terminal.js: _classify() returns an inert classification for empty argv; executePipeChain() parses each stage once, filters stages with no argv (so the last real stage stays final), warns only when the whole pipeline is empty. Last-stage test now compares against the filtered length. - module-system.js: `bug` diagnostics include the stack (10 frames, 1200 chars); auto-filed reports carry it too — they are the majority of the inbox and were previously message-only. - report.php: per-stack 2 KB cap; fingerprint pinned to message/source/count so adding `stack` cannot break dedupe against reports filed before today. - ingest.php: first_frame() parsed once on ingest, stored as `frame` on each signature. - newos4-triage.py: FRAME| line with the first application frame. - dashboard.php: frame under each Top Errors row. - modules/test/test-pipe-guard.js: ordering tripwire (guard must precede the parts[0] read). Verified: test RED exit=1 -> GREEN exit=0; browser matrix on v4.6.55 (help |, | wc -l, echo hi || echo bye, ls | | wc -l, |) -> 0 new error signatures, "|" warns; auto-filed report now carries stack (RPT-...f3e31124, archived after the probe); frame = modules/core/core-bundle.js:3955:42; maintain OK; skill audit 7/7.
* fix(newos4): unmeasured skills are untracked, world-model writes verified, ↵Agando2026-10-231-0/+24
| | | | | | | | | | | | | | | | | | | | | | | skill audit External review packet (os4-external-review-v4.6.51.html) triaged against the code: 2 findings confirmed and fixed, 4 could not be reproduced and were recorded as such. - module-memory-graph.js: getStaleSkills() treated a missing lastUsed as 999 days unused, so skill-audit recommended archiving every skill (22 of 22). Skills with no usage telemetry are now collected by getUntrackedSkills() and never counted stale. Live: "Stale: 0" + "Untracked: 22 (no usage telemetry — NOT stale)". - module-world-model.js: _saveToVFS() ignored fsWriteJSON()'s return value and promoted whatever a truthy read returned. Now write -> read-back -> byte compare -> promote, with every return checked. Regression test modules/test/test-world-model-save.js (red on the old code: promoted=true with errs=[]; green now). - scripts/newos4-skill-audit.py: 5 mechanical probes (version x3, read_file paging + context budget, selection symbols, required scripts, extKeys) + skill presence; exits non-zero on drift. 7/7 pass today. Weekly job cb6bc2a16216 runs it Mondays. Not reproduced (recorded in admin/docs/newos4-external-review-verification-2026-10-23.md): world_model_query empty-payload throw (live call returns JSON), pipes-as-command-names, ls skills empty (23 entries via fs.readDir), ~66 agent dirs (4 live).
* feat(newos4): world-model-ask answers with the LLM, grounded in the model ↵Agando2026-10-221-0/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | (v4.6.50) `world-model-ask` was a 10-keyword lookup: any real question returned "Unknown query. Try: modules, skills, ...". The documented example ("what changed since yesterday") compared nothing — it restated the current snapshot. - _modelDigest(): whitelisted snapshot (measured 942-965 chars on fixtures, ~3.3 KB live) + recent error sample + changesSinceLastSnapshot - _buildAskPrompt(): "answer only from this JSON, never invent numbers, name the command that would produce missing data" - ask(): connects Ollama on demand, answers via chat(), falls back to the facts path with a visible warning; --facts keeps the instant lookup - _diffSincePrev(): keeps one previous snapshot in /system/world-model.prev.json so "what changed" is a real diff (files 136 -> 140) - world_model_query tool returns the snapshot (digest or detail:full) instead of ten canned strings; no nested LLM call inside a tool call - help text now says what it does; node test modules/test/test-world-model-ask.js (11 assertions, runs the real class) Verified live v4.6.50: facts "Loaded 46 modules" | LLM "The snapshot does not contain information regarding the cause of memory growth ... use world-model-refresh" | diff "files 136 -> 140" | tool snapshot 3,334 bytes.
* fix(newos4): download link uses the user's space; WebDAV share copies ↵Agando2026-10-211-0/+32
| | | | | | | | | | | | verified file links; preview fullscreen+share; files->WebDAV upload button (v4.6.45) - download: URL built from _resolveSpaceName() (config url = logged-in user), not the page space - WebDAV browser 🔗: shares selected FILES only, URL-encoded, HEAD-verified (200) before claiming success; folders offer a tar fallback instead of a guaranteed-403 link - file manager preview: ⛶ fullscreen + 🔗 copy-link toolbar (was none) - file manager toolbar: ☁ WebDAV publishes selected/current file via webdav-push - modules/test/test-download-url.js: 4 PASS - rebuild bundles, bump v4.6.44 -> v4.6.45 (loader + 3 script tags)
* auto: 2026-06-08_18:00 changesAgando2026-06-081-0/+54
|
* auto: 2026-06-06_06:00 changesAgando2026-06-061-1/+1
|
* auto: 2026-05-27_06:00 changesAgando2026-05-271-0/+419