Commit graph

51 commits

Author SHA1 Message Date
Yucong Sun
89060c5a6b
docs: fully-expandable generated sidebar + Chinese docs via Docusaurus i18n (#1246)
* docs: fully-expandable generated sidebar, replacing index.md link pages

Rework docs navigation so the sidebar expands to every page of every
reference tree, instead of terminating at generated index.md link lists:

- New docs/gen_sidebar.py (replaces gen_index.py + update_index.sh):
  walks efun/, apply/, stdlib/, concepts/, driver/, cli/ and zh-CN/ and
  emits sidebars.generated.json — a full Docusaurus category tree per
  directory. Category landing pages are now `generated-index` card pages
  (title/description/slug), so all generated index.md files are deleted.
  --check mode verifies freshness; new .github/workflows/docs-sidebar.yml
  runs it in CI.
- New docs/sidebar_meta.json holds curated presentation: category labels,
  one-line descriptions (shown on the landing cards), explicit ordering
  (driver/cli/concepts read top-down from user-facing to internals) and
  per-page label overrides.
- sidebars.ts becomes a hand-authored skeleton (Getting Started, lpc/,
  Historical) that splices in the generated trees.

Content reorganization (from a docs-wide review):
- Move misplaced efun pages out of efun/general: terminal/protocol efuns
  (act_mxp, send_zmp, request_term_*) to interactive/, debugging efuns
  (check_memory, dump_*, clear_debug_level, destructed_objects) to
  internals/, shallow_inherit_list to system/.
- Delete stub duplicates superseded by complete pages elsewhere:
  general/parse_{add_synonym,dump,my_rules,remove}, contrib/{shuffle,
  element_of}.

Modernize key pages with MDX:
- index.mdx: landing page with a card grid linking each doc section.
- build.mdx: per-platform <Tabs> (Ubuntu/macOS/Windows/Alpine+Docker),
  admonitions, VitePress [[toc]] leftover removed, stale per-platform CI
  workflow links updated to the unified ci.yml.
- ffi-plan.md: GitHub-style [!CAUTION] alert converted to an admonition.

`npm run build` passes clean (onBrokenLinks: throw, no warnings).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0174GM2azvAHBmvyESwxm5om

* docs: serve the Chinese corpus through Docusaurus i18n

Move the zh-CN/ directory out of the default docs tree and into a proper
Docusaurus locale (i18n/zh-CN/docusaurus-plugin-content-docs/current/):

- The flat zh-CN/efun/ directory (333 pages) is re-homed to mirror the
  categorized English layout (name-matched 1:1; `hash` maps to strings/
  per its own frontmatter). apply/ pages map 1:1; the stray English-text
  zh-CN/apply/master/view_errors.md documents a MudOS-era apply that no
  longer exists in the driver and is dropped; stdlib/db/database_zh.md
  becomes the i18n translation of stdlib/db/database.md; the Chinese
  build guide becomes the translation of build.mdx.
- Untranslated pages automatically fall back to English content under
  /zh-CN/, so the whole site is navigable in either locale from the new
  navbar locale dropdown.
- Both locales share one sidebar. Generated sidebar items now carry
  stable `key` fields (the directory/doc path) so translation keys are
  unique (both efun/ and stdlib/ have an "Arrays" category, crypto and
  strings both document `hash`). Category labels, generated-index
  titles/descriptions, navbar and footer are translated in
  i18n/zh-CN/...; theme UI strings come from Docusaurus' bundled
  zh-Hans translations. Translated landing page at /zh-CN/.
- The "中文文档" sidebar section, the zh-CN tree in gen_sidebar.py /
  sidebar_meta.json, and its slice of sidebars.generated.json are gone.
- Relative .md-file links on pages that render in both locales break
  the localized build (the file->permalink map points at the localized
  copy), so concepts/, the two socket_*_option pages and the config.md
  generator now emit extension-less route links instead.
- zh interactive.md/objects.md get explicit slugs like their English
  counterparts (a doc named after its parent directory is otherwise a
  Docusaurus category-index doc, colliding with the generated-index
  route).

`npm run build` builds both locales clean (onBrokenLinks: throw).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0174GM2azvAHBmvyESwxm5om

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-11 17:20:25 -04:00
Yucong Sun
82d82f3beb
Add recompile_object() efun: in-place program update, state preserved (#1237)
* Add recompile_object() efun: in-place program update, state preserved

Recompiles a master copy's program from its source file and swaps the
fresh program into the LIVE master copy and every clone sharing it -
the "hot update" alternative to destruct+load_object: nothing is
destructed, so object identity (pointers held elsewhere, name,
inventory, shadows, interactive state, call_outs, heart_beat) is
untouched, and each object's global variables carry over BY NAME
inside the driver (private ones included): the new program's __INIT
runs first, then every surviving name gets its old value back. The
recompile behaves like a normal load - unloaded parents resolve
through the retry dance and the compile-time master applies are
consulted. Returns the number of objects updated.

Made possible by moving an object's variable block OUT of the object_t
allocation into its own (TAG_OBJ_VARS, always >= 1 svalue, wired into
the debug-malloc walkers): every access already went through
ob->variables[i], so a program with a different variable count can now
be swapped onto a live object.

Safety: refused while any object sharing the program is executing
anywhere on the call stack (live frames hold bytecode positions and
variable indices of the old layout), for clones (pass the master
copy), the simul_efun object, pending replace_program(), and nested
calls. Function pointers whose behavior depends on the owner's program
layout (FP_LOCAL, FP_FUNCTIONAL) go stale instead of corrupting:
objects carry a prog_generation stamp, funptrs snapshot it at
creation/bind, and call_function_pointer() errors cleanly on mismatch.

Fixing a latent asymmetry this exposed: make_lfun_funp incremented
func_ref on the creation-time program but dealloc_funp decremented the
owner's CURRENT program. FP_LOCAL pointers now store their program and
account against it symmetrically (checkmemory and %O formatting
updated to match) - caught by the debug-build memory checker in the
testsuite.

The hot-reload daemon's default (state-keeping) path now reloads
through recompile_object() - changed ancestors first, then the watched
program - so clones ride along automatically; a cooperative
hot_reload_state()/hot_reload_restore() pair takes the destruct+load
path with exactly the state it chooses, and watch(prog, 0) opts out
entirely. The daemon test demonstrates finding all live instances with
children()/clonep() and both clone behaviors (updated in place vs.
stragglers on the old program); single/tests/efuns/recompile_object.lpc
pins the efun semantics (master+clones count, per-object state incl.
private, initializers for new variables, removed variables, stale
funptrs, executing/clone/missing-source guards, call_out survival).

Docs: efun reference page, hot-reload guide step 5 rewritten around
the efun with the value-transfer technique kept as the manual
alternative, caveats updated (clone behavior per path, stale funptrs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* recompile_object: support master/simul_efun targets; review fixes

The master object and the simul_efun object can now be recompiled
live. Both subsystems dispatch through cached name->runtime-index
tables (master_applies / simuls) whose entries point into the old
program's function table, so recompile_object() rebuilds them against
the new program immediately after the swap and BEFORE the new
program's __INIT runs (an error inside it would already route through
those tables). Simul_efun indices are preserved by NAME across the
rebuild - that table is deliberately unsorted for exactly this reason
- so simul calls compiled into every other program keep working, and
a simul removed by the new source fails with the usual "no longer a
simul_efun" runtime error. set_master()/set_simul_efun() only
ref/assign when the object actually changes, keeping the classic
destruct-driven replacement path intact. %O of a function pointer to
a since-removed simul now prints a placeholder instead of derefing
the null table entry.

Testsuite: the efun test recompiles the live simul_efun object
mid-run (the very next ASSERT dispatches through the rebuilt table),
pins the currently-executing guard on the master (master::flag() sits
on the call stack for the whole run), and re-runs the master recompile
from a post-run call_out where the master is idle - state carry-over
and apply dispatch are enforced by exiting nonzero.

Also from this self-review round (multi-agent):

* f_recompile_object crashed when the target destructed itself from
  its new program's __INIT: destruct sweeps the VM stack, so the efun
  glue's stack slot held a plain 0 by the time it tried to
  free_object() it. Reproduced by a review agent's probe; the glue
  now uses free_svalue(), and the scenario is pinned in the efun test
  (destructed targets drop out of the updated count).

* hot_reload daemon: ancestors() now returns the inherit closure
  DEEPEST-first - recompiling a middle parent bakes in whatever
  grandparent program is live at that moment, so a >=3-level chain
  with two changed ancestors permanently embedded the stale
  grandparent (reproduced by a review agent; pinned by a new
  kid/mid/grand scenario).

* hot_reload daemon: dep records were map_delete'd before the
  recompile and rebuilt by the applies during it - but a throw BEFORE
  compiling (currently-executing guard, unreadable file) left the
  object loaded with no records, blinding closure_changed() to
  include-file edits forever. Records are now restored when the
  recompile throws (pinned by a new watched-object-drives-the-pass
  scenario).

* docs: inheritance wording ("copies code" -> the child links against
  the exact parent program it was compiled with), the
  currently-executing guard also covers inheritors running inherited
  code, and the cooperative-pair opt-out triggers on
  hot_reload_state() alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* recompile_object: void mid-update replace_program; cover virtuals

Two additions from the C++ review round:

* A replace_program() registered DURING the update slipped past the
  pre-flight check: an earlier target's __INIT can call into a
  not-yet-swapped clone, whose OLD code registers a pending entry -
  computed against the very program the update is replacing. The
  backend sweep then ran that entry's variable-offset shuffle against
  the fresh program's differently-sized variable block (negative
  num_fewer, heap corruption; reproduced under ASan by a review
  agent's probe). recompile_object() now voids any pending entry for
  each target at its swap point - an entry registered AFTER the swap
  is computed against the new program and survives. Pinned in the
  efun test; the rest of the suite run doubles as the sweep detector.

* Virtual objects (materialized through master::compile_object) are
  covered and pinned: the virtual object carries the BACKING file's
  program, so the recompile targets that source and swaps it in with
  the virtual name, identity, flag and state untouched. The testsuite
  master gains a /data/hu/virt* fixture mapping; docs note the
  behavior and that the hot-reload daemon keys its records by
  compiled program name (watch virtuals via their backing file).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* docs: capture hot-reload/recompile_object knowledge in README and AGENTS

README: the hot-reload language bullet now describes what actually
ships (recompile_object with state carried by name, clones included),
and Features gains a Hot Reload section linking the guide.

AGENTS.md, for future agents working on this machinery: the object
variable block is a separate allocation (TAG_OBJ_VARS) and what that
enables; the new-DMALLOC-tag checklist (checkmemory walkers); the
destruct-sweeps-the-VM-stack rule for efun glue; testsuite harness
facts (fixtures outside tests/, unconditional teardown, master::flag
on the stack all run + the post-run call_out pattern, full -ftest
paths, suite side-effect files); the compile-time master applies; and
the recompile_object invariants (executing-frame guard, dispatch-table
rebuild before __INIT, voiding mid-update replace_program entries,
funptr generation staleness, FP_LOCAL func_ref symmetry).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* recompile_object: pin shadow/catch_tell/add_action/heart_beat survival

New test recompile_object2.lpc verifies the object-attached runtime
state that dispatches by name keeps working across the swap:
catch_tell routes into the new program while accumulated state stays;
a shadow chain survives updating the SHADOWED object (still
intercepted, new code underneath) and updating the SHADOW itself while
attached; add_action sentences registered by the old code still fire
their verb into the new program; the heart_beat registration persists.

Also two doc wording fixes from the docs review: the executing-guard
bullet now covers both halves of the guard (frames executing the
program's code AND frames belonging to an object of the program
running inherited code), and the guide's mode summary matches the
daemon (hot_reload_state alone selects the cooperative path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* recompile_object: fix simul_efun/__INIT edge cases; cover callback surface

Four defects from the C++ review round, each probe-verified under ASan:

* Recompiling the simul_efun object to a program that defines no simuls
  FREEd the live dispatch table (simul_names/simuls) while other
  compiled programs still carry F_SIMUL_EFUN opcodes and FP_SIMUL
  funptrs with baked indices -> use-after-free on the next simul call.
  Keep the tombstoned arrays instead (remove_simuls() already nulls
  every func, which yields the clean "no longer a simul_efun" error and
  preserves the name->index mapping for re-adds).

* The debug memory checker did not mark IHE_ORPHAN idents as permanent,
  so any run that removed a simul via an update tripped a spurious
  "orphan permanent identifier" leak and failed the testsuite gate.
  Add IHE_ORPHAN to the mark mask (it is part of IHE_PERMANENT).

* The disassembler dereferenced simuls[].func unguarded in two places;
  after a simul removal, dump_prog() on a program referencing it would
  null-deref. Guard both, matching the sprintf %O fix.

* An error() thrown from a target's __INIT during the swap leaked this
  loop's held references (the per-target snapshot ref, new_prog's
  compile ref, the old variable block) and left the update half-applied.
  Wrap call___INIT per target in save_context/try/restore: on error the
  object is left committed to the new program with fresh initializers
  (carried-over state dropped, like a create() that throws during load),
  sibling targets still update, and nothing leaks.

Test coverage:
* recompile_object.lpc: an __INIT that errors -- blueprint and clone
  both recompile, neither is immortalized, the object stays usable on
  the new program, no ref/variable leak (the per-file memory checker is
  the detector). (The simul zero-function / removal paths can't be
  exercised against the shared /single/simul_efun mid-suite; verified
  out-of-band with a throwaway ASan probe that reduces then restores the
  file.)
* recompile_object2.lpc: call_outs armed before the swap fire after it --
  a name-based call_out dispatches into the new program, a funptr
  call_out is stale and is refused cleanly (its target never runs, no
  crash), verified from a post-run call_out. Rounds out the by-name
  callback survivors already covered (catch_tell, add_action, heart_beat,
  shadows).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-11 11:24:30 -04:00
Yucong Sun
55956a24b7
Add inherit_program / include_file master applies; auto hot-reload demo (#1230)
* Add inherit_program / include_file master applies; auto hot-reload demo

New compile-time master applies, consulted for every inherit statement
and #include directive:

* mixed inherit_program(string from, string path, int priv)
  Called while compiling `from` for `inherit "path";` (priv nonzero for
  private inherits). A string return is an alternate path for the
  inherited file; an array-of-strings return is the inherited program's
  source itself (compiled via load_object_from_source under the inherit
  statement's name, through the existing load_object retry loop); any
  other return prevents the inheritance.

* mixed include_file(string compiled, string from, string path)
  Called when `from` is about to include `path` while compiling
  `compiled`. A string return is the translated path (resolved absolute
  from the mudlib root or relative to the includer; returning `path`
  unchanged keeps the "..."-vs-<...> search semantics); an
  array-of-strings return is the included text itself (pushed as an
  in-memory include buffer with the usual file-identity bookkeeping);
  any other return prevents the inclusion.

Both follow the valid_override/get_include_path precedent for calling
master LPC mid-compile (skipped without a VM context or master object),
and a missing apply keeps stock behavior.

The applies expose the full compile-time dependency graph, which the
testsuite uses to demonstrate mudlib auto hot-reload on file changes:
/single/hot_reload.lpc registers as the master's compile hooks, records
which source files each program's bytecode was built from (own source,
includes, inherited programs, transitively), and its call_out poller
destructs+reloads watched blueprints whose dependency closure changed
on disk - including reloading a stale parent when only the parent's
include changed.

Testsuite: single/tests/compiler/{inherit_program,include_file}.lpc pin
the apply semantics (redirect, inline source, deny, priv flag, argument
shapes on nested includes) via the scriptable /clone/compile_hook;
single/tests/applies/hot_reload.lpc demonstrates end-to-end hot reload
over a runtime-written inherit+include fixture chain. Docs added for
both applies.

Validated: full LPC suite (532 files) x2 on RelWithDebInfo, x2 on
Debug+ASan/UBSan, plus the 297 GTest unit tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* docs: add hot reload guide for the new compile-time master applies

New concepts page (concepts/general/hot_reload.md) explaining why
"file changed -> reload" needs the compile-time dependency graph, how
the inherit_program / include_file master applies expose it, and a
step-by-step mudlib implementation with examples: master delegation,
dependency recording, closure computation, change detection with
size+mtime snapshots, parent-first reload ordering, and the call_out
poller. Documents blueprint-reload semantics and caveats (clones keep
the old program, no compiles inside the applies, records only complete
for compiles observed by the daemon), pointing at the testsuite
reference implementation. Cross-linked from both apply reference pages
and the concepts indices.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* docs/testsuite: say "master copy", not "blueprint"

Align the hot-reload guide, apply reference, daemon, and test comments
with the project's terminology for the object loaded from a file (see
clonep(3): "the master copy").

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* testsuite: edge cases for the compile-time applies; docs review fixes

compile_hooks_edge.lpc pins that unusual inherit_program/include_file
return values produce clean LPC errors or the documented behavior,
never a driver crash: empty array, non-string elements, redirect to
self, empty-string redirect, inline source vs already-loaded object,
multiline inline content, the apply itself throwing mid-compile
(safe_apply falls back to default resolution), extension-spelled
redirects, and denying the auto-included global include file.
Fixtures in /clone/adv_*; /clone/adv_hook wraps the scriptable hook
with a throwing include_file.

Docs fixes from review: the apply-page examples now look the daemon up
with find_object() instead of a path call_other (which would load the
target and trigger a compile mid-compile -- the exact pattern the same
pages forbid), and the hot-reload guide's ancestors() snippet carries
the seen-mapping argument to match the reference daemon.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* hot_reload: fix multi-watch and failed-reload handling; harden tests

Three defects from the LPC review round, each now pinned by the
demonstration test:

* check_now() collected and reloaded in one pass, so the first reload's
  snapshot refresh erased the change evidence for every other watched
  program sharing the dependency (a common header, or a watched parent
  iterating before its watched child - which then stayed bound to the
  destructed old parent forever). The stale set is now collected before
  any reload runs.

* A reload whose recompile throws (a syntax error mid-edit - the most
  common event in a hot-reload workflow) unwound poll() before the
  re-arm, killing the poller forever and leaving the watched master
  copy destructed. poll() re-arms first, check_now() catches per
  program, reload_count only counts successes, and closure_changed()
  treats a watched-but-not-loaded program as stale so the retry
  self-heals once the file compiles again.

* The three apply tests registered master compile hooks (and the
  hot-reload test armed the poller and wrote /data/hot) with cleanup on
  the success path only; a thrown check would leave the hook routing
  every remaining compile of the randomized run. Each test now runs its
  checks under catch and unhooks/tears down unconditionally, re-raising
  the error afterward.

The demo test now also covers the shared-dependency pass (watch parent
and child, change the common include, both reload in one pass) and the
broken-edit recovery cycle. The hot-reload guide's snippets are updated
to match the daemon.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

* simulate: let inline inherit source resolve its own unloaded inherits

From the C++ review round: master::inherit_program returning inline
source whose text itself inherits a not-yet-loaded program failed the
whole load with "#inherit is not supported when compiling from
in-memory source" -- reachable in the feature's primary use case, since
synthesized programs routinely inherit ordinary on-disk library files.

load_object_from_source() now runs the same iterative dance as
load_object(): when the compile aborts on an unloaded parent, load that
parent (from disk, or from further master-supplied inline source, so
synthesized-inheriting-synthesized chains work), then recompile the
same source string -- which is in hand, unlike the historical
no-filename rationale for rejecting #inherit here. Mirrors
load_object()'s guards: illegal-to-inherit-self, the duplicate-name
check after the parent's arbitrary LPC ran, and an inherit-chain bound
on the retry loop as a backstop against a master that redirects to a
fresh unloaded name on every recompile.

The inherit_program test now covers both new shapes (inline inheriting
unloaded on-disk, and two levels of inline source); the apply doc drops
the already-loaded-only caveat.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018DGhzJfPhDGJA94EPh1gEK

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-10 10:27:27 -04:00
Yucong Sun
c914f03d66
Add local search and documentation guide for docs site (#1221)
* docs: add local full-text search and a contributor README

Add @easyops-cn/docusaurus-search-local to the Docusaurus site so the
docs get an offline search bar (index built at build time, no external
service). English and zh-CN pages are both indexed, and matched terms
are highlighted on the target page.

Add docs/README.md describing the Docusaurus setup, local dev/build
commands, search behavior, directory layout, and gotchas; exclude it
from the published site alongside CLAUDE.md. Point the root README's
docs/ entry at it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSzcESzU9947zkGzQ6SMmE

* docs: remove dead framework leftovers, fix index generation, complete the nav

Delete the VitePress (.vitepress/) and Jekyll (_layouts/, css/) leftovers,
the one-shot migration scripts (fix_md_header.py, fix_seealso.py), and the
stale keywords.json snapshot; prune the matching .gitignore entries and
docusaurus exclude patterns.

Rewrite gen_index.py for Docusaurus: it emitted dead .html links and
legacy 'layout: doc' frontmatter, choked on non-markdown entries, and
dropped nested categories — regenerating an index would have broken it.
It now emits the extension-less links the site actually uses, links
nested category indexes (restoring apply/* on the zh-CN index), and
refuses to run on the docs root. Fix update_index.sh's copy-paste titles
(zh-CN efun/build were titled 'APPLY'), stop it clobbering the
hand-written lpc/index.md, and cover cli/. Regenerated indexes pick up
the missing driver/ffi-plan entry. add_missing_efuns.py now takes the
keywords.json path as an argument instead of requiring a stale copy.

Move CNAME and the Google site-verification file into static/ so they
actually reach the published build output.

Complete the sidebar: link the CLI category to cli/index and add the
missing portbind/symbol/generate_keywords pages, and expose the
previously orphaned stdlib section under Reference.

Promote onBrokenLinks to 'throw' now the build is warning-free, and drop
the empty Demo section from the landing page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSzcESzU9947zkGzQ6SMmE

* docs: strip legacy 'layout: doc' frontmatter from all pages

Mechanical sweep removing the Jekyll-era 'layout: doc' line from every
doc page's frontmatter (Docusaurus ignores it), and the matching line
from the templates in docs/CLAUDE.md so new pages don't reintroduce it.
No content changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSzcESzU9947zkGzQ6SMmE

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-09 22:09:55 -04:00
Yucong Sun
48fe0e9b5a Grammar-driven lexical simplification; minimal token inventory
Lexical decisions move from lexer state into the grammar, where LALR
lookahead already disambiguates:
- Array/mapping opens ({ / ([ are ordinary '(' '{' / '(' '[' token
  pairs the grammar pairs (composite tokens deleted).
- The whole '(: name' first-class-function machinery (dedicated start
  condition, function_flag, one-byte peek, old_func()) becomes two
  grammar productions; %expect documents the intentional conflicts.
- Token diet: dead tokens deleted; single-char operators are plain char
  tokens ('!', '.'); same-precedence families share one value-carrying
  token (L_EQ_NE, L_SHIFT, L_INC_DEC -- the L_ORDER idiom). Release-
  build illegal-char diagnostics made unconditional; CRLF multi-line
  #define fold pinned (Windows).

Includes the merge of current master (docs-only advance).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 20:48:48 -04:00
Yucong Sun
51888b0740 Grammar modernization: top-down restructure, named references, split rule files
Restructure grammar.y top-down with descriptive nonterminal names, 100%
named references ($name over $N), type-safe Bison value declarations,
EBNF { } repetition folding for recursive list rules, and the grammar
rule actions extracted into grammar_rules*.cc by topic (decls, exprs,
loops, switch, types). No grammar-language changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 20:48:48 -04:00
gesslar
9e5a1f16dd
docs: modernize concepts/general and fix correctness (#1211)
* empty

* docs: modernize concepts/general and fix correctness

Overhaul the docs/concepts/general set: remove MudOS/LPmud/TMI-era
references, correct APIs and config options against the current source,
trim speculative/AI-generated content, and fix the driver overview.

- Rename MudOSdriver.md -> fluffos_driver.md and modernize its content
- lpc: FluffOS branding, note class/struct types, code formatting
- message_doc: correct message()/receive_message signatures and the
  `type` semantics; distinguish the message() path from the catch_tell
  output efuns; replace the speculative "smart client protocol" essay
  with pointers to GMCP/MSDP/MXP/MSP/ZMP
- preprocessor: correct the #pragma list and defaults, document
  #error/#warn; move @/@@ text blocks to lpc/constructs/text_blocks.md
- simul_efun: correct the call mechanism, config option name, and
  function-visibility rules
- socket_efuns: rewrite the 1992 tutorial into a concise, accurate guide
  and document MUD-mode save/restore serialization
- tls: fix fabricated client APIs (socket_connect arity/address, resolve),
  the TLS-version claims and cert-path resolution; de-emoji
- tracing: fix the default/cap, output format, build-gate and overhead
  claims
- websocket: fix config option names (websocket http dir), set_debug_level,
  and the receive_message input/output confusion; trim filler
- global_include_file, oop: minor correctness/typo fixes

Rebased onto the Docusaurus docs: internal links use .md, index files use
extensionless links, and code with braces is fenced. Not built locally;
please verify rendering. See PR notes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 11:12:31 -07:00
Yucong Sun
2063e95436
Fix Docusaurus sidebar, broken links, and gh-pages CI (#1209)
* Reorder sidebar: Driver > CLI > Reference (LPC Language, Apply, EFUN, Concepts)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix Docusaurus build: broken links, duplicate routes, and gh-pages CI

- Strip .html from all markdown link targets (51 files) for Docusaurus URL routing
- Add slug: frontmatter to 4 files whose names match their parent directory
  (interactive.md, objects.md, README.md, build.md) to prevent Docusaurus's
  category-index convention from creating duplicate routes
- Fix one missed .html link in zh-CN/build/index.md
- Move onBrokenMarkdownLinks to markdown.hooks (Docusaurus v4 deprecation)
- Update gh-pages.yml: rename to Docusaurus, use node 22, correct build path
  (docs/build instead of docs/.vitepress/dist)

Build now completes with [SUCCESS] and zero warnings or broken links.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 21:01:21 -07:00
Yucong Sun
46f381edf8
fix: Fix dead links in WebSocket documentation (#1140)
* fix: Add icu-data-full to Dockerfile for non-English encoding support

Fixes #1133

Starting with Alpine 3.16, icu-dev only installs icu-data-en (English only).
Applications requiring non-English character handling need icu-data-full
explicitly added to the runtime image to prevent crashes when processing
non-English text.

* fix: Fix dead links in WebSocket documentation

Fixes GitHub Pages build failure due to broken links in websocket.md:
- Changed gmcp.md to send_gmcp.md
- Changed query_gmcp.md to has_gmcp.md
- Updated code examples to use correct function names:
  - query_gmcp() -> has_gmcp()
  - gmcp() -> send_gmcp()

The efun files are named send_gmcp.md and has_gmcp.md, not gmcp.md
and query_gmcp.md as referenced in the documentation.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-31 19:42:21 -07:00
Yucong Sun
ddf8b9740d
more doc fixes. (#1137)
* docs: Fix multiple documentation issues

This commit addresses several documentation inconsistencies and gaps
identified by comparing docs with actual code implementations:

**Build Documentation Fixes:**
- Updated macOS build instructions to clarify Homebrew paths for both
  Apple Silicon and Intel Macs, emphasizing modern Homebrew defaults
- Added clarity to SQLite version options (=1 vs =2) explaining the
  differences and recommending version 2

**CLI Tool Documentation:**
- Added documentation for the `symbol` utility (docs/cli/symbol.md)
  - Tool for loading and analyzing LPC files
  - Usage: symbol <config> lpc_file
- Added documentation for the `portbind` utility (docs/cli/portbind.md)
  - Privilege-separated port binding for FluffOS
  - Allows binding to privileged ports then dropping privileges

**Apply Documentation:**
- Added mxp_enable apply (docs/apply/interactive/mxp_enable.md)
  - Called when MXP protocol is negotiated with client
- Added mxp_tag apply (docs/apply/interactive/mxp_tag.md)
  - Processes MXP tags from client
- Added zmp_command apply (docs/apply/interactive/zmp.md)
  - Handles ZMP (Zenith Mud Protocol) commands
- Added receive_ed apply (docs/apply/interactive/receive_ed.md)
  - Post-processes ed editor output
- Removed obsolete view_errors.md documentation
  - Apply not found in source code, appears to be deprecated

All new documentation follows existing format conventions and includes
cross-references to related efuns and applies where applicable.

* docs: Add missing apply and efun documentation

This commit adds documentation for previously undocumented applies and
efuns, completing the documentation coverage for recent FluffOS features.

**Apply Documentation:**
- terminal_colour_replace (interactive): Custom color token replacement
  callback for terminal_colour() efun preprocessing
- parser_error_message (master): Custom error message generation for
  parse_sentence() failures

**Efun Documentation:**
- hash() (crypto package): Complete documentation for cryptographic hash
  function with support for modern algorithms (SHA-3, BLAKE2, SM3)
  - Includes security recommendations and version compatibility notes
  - Documents all supported algorithms from legacy (MD5, SHA-1) to modern
    (SHA-3, BLAKE2b512)
  - Created new crypto package documentation directory

**Index Updates:**
- Updated docs/apply/interactive/index.md with new applies:
  mxp_enable, mxp_tag, receive_ed, terminal_colour_replace, zmp
- Updated docs/apply/master/index.md with parser_error_message
- Removed obsolete view_errors reference from master index
- Added crypto section to docs/efun/index.md

These additions address documentation gaps identified by comparing the
source code with existing documentation, particularly for the crypto
package enhancements from commit 33de35c (modern hash algorithms).

* docs: Add CLI tool, config guide, and documentation maintenance guide

This commit adds comprehensive documentation for additional FluffOS
features and creates a maintenance guide for the documentation itself.

**New CLI Documentation:**
- generate_keywords: Development tool for generating keywords.json for IDE
  integration and language server support. Extracts all efun metadata into
  structured JSON format.

**New Configuration Documentation:**
- config.md (driver/): Complete guide to driver configuration file format
  - Documents all configuration options with examples
  - Network setup (telnet, websocket, TLS)
  - Memory management and performance tuning
  - Protocol support (GMCP, MXP, ZMP, MSSP, MSP)
  - Security settings and limits
  - Includes practical examples for development and production

**Documentation Maintenance Guide:**
- CLAUDE.md (docs/): Comprehensive guide for maintaining FluffOS documentation
  - Documentation structure and organization
  - Templates for applies, efuns, and CLI tools
  - Workflow for finding and documenting undocumented features
  - Source code mapping (where to find implementations)
  - Verification and testing procedures
  - Common documentation issues and fixes
  - Package-specific notes and guidelines
  - Quick reference commands for contributors

**Index Updates:**
- Updated docs/driver/index.md to include config.md

These additions make it easier for contributors and AI assistants to
maintain accurate, complete documentation for FluffOS.

* docs: Add socket TLS options and LPC default arguments documentation

This commit documents important FluffOS features that were previously
undocumented, focusing on TLS socket options and LPC language enhancements.

**Socket TLS Options Documentation:**
- socket_set_option() efun - Configure socket TLS/SSL parameters
  - SO_TLS_VERIFY_PEER: Control peer certificate verification
  - SO_TLS_SNI_HOSTNAME: Set Server Name Indication hostname
  - Includes security notes and practical examples
  - Essential for HTTPS and secure socket connections

- socket_get_option() efun - Query socket option values
  - Retrieve TLS verification and SNI settings
  - Useful for validation and debugging
  - Examples for conditional logic and auditing

**LPC Language Feature:**
- Default Arguments documentation (prototypes.md)
  - Comprehensive guide to FluffOS default argument syntax
  - Feature added in commit bcb8e91 (2023) but not documented
  - Rules, examples, and use cases
  - Multiple practical examples showing API design patterns
  - Notes on compile-time behavior and limitations

**Index Updates:**
- Updated docs/efun/index.md with new socket functions
- Updated docs/efun/sockets/index.md with new functions

These features significantly enhance LPC programming capabilities:
1. TLS options enable secure network connections with certificate verification
2. Default arguments reduce code duplication and improve API usability

Both features are production-ready and widely used but were missing
from the documentation.

References:
- Socket options: commit 1fd7f61 (2023)
- Default arguments: commit bcb8e91 (2023)

* docs: Add comprehensive guides for tracing, TLS, and WebSocket support

Added three new concept documentation guides:

1. tracing.md - Complete guide to performance profiling with trace_start/trace_end
   - Chrome DevTools integration
   - Memory management warnings
   - Profiling scenarios (commands, combat, heartbeats)
   - Analysis techniques and best practices

2. tls.md - Comprehensive TLS/SSL support documentation
   - Server port TLS configuration
   - Certificate generation (self-signed and Let's Encrypt)
   - Client TLS socket connections with SO_TLS_VERIFY_PEER and SO_TLS_SNI_HOSTNAME
   - Security best practices
   - Troubleshooting guide

3. websocket.md - Complete WebSocket support guide
   - WebSocket server configuration (ws:// and wss://)
   - Multiple protocols (ASCII, Telnet, Binary, HTTP)
   - Built-in web client documentation and customization
   - GMCP over WebSocket
   - Telnet protocol over WebSocket
   - Security considerations and performance optimization
   - Troubleshooting and advanced usage

Updated concepts/general/index.md to include all three new guides.

* docs: Regenerate documentation indices

Ran update_index.sh to regenerate all documentation indices:

- docs/apply/index.md: Added new applies (mxp_enable, mxp_tag, receive_ed,
  terminal_colour_replace, zmp, parser_error_message), removed obsolete view_errors

- docs/concepts/index.md: Added new concept guides (tls, tracing, websocket)

- docs/driver/index.md: Added config documentation, updated title format

- docs/efun/crypto/index.md: Regenerated to standard format with hash function

- docs/cli/index.md: Generated index for CLI tools (driver, generate_keywords,
  json2o, lpcc, o2json, portbind, symbol)

All indices now correctly reference the new documentation added in previous commits.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-31 14:25:38 -07:00
Michael Programs
87e2059b11
update efun/apply/concept documentation related to message() (#1062) 2024-06-06 03:07:25 -07:00
Yucong Sun
6d8698a09d setup vitepress 2023-12-02 20:00:33 -08:00
Michael Programs
f7802e218d run docs update_index.sh 2023-08-21 23:38:33 -07:00
Yucong Sun
3bca73af50 EFUN: sys_reload_tls(int port_index) 2023-05-29 21:15:09 -07:00
Yucong Sun
3478cc2ed6 EFUN: time_ns() 2023-05-29 11:09:09 -07:00
噢哎哟喂
c0b196c0d6
更新说明文档 (#897)
* 更新说明文档

* update README.md

* update efun docs

* update efun docs, add parsing efun

* 修复network_stats()中文文档错误
2022-07-07 18:39:06 -07:00
Yucong Sun
3093d818e5 Update doc index 2022-05-07 14:04:12 -07:00
噢哎哟喂
44532e0228
add DB, update docs (#807)
* add DB

* update docs

* update DB

* add database code

* update docs
2021-05-09 06:35:59 -07:00
噢哎哟喂
2d2f3c94ee
update zh-CN docs (#801) 2021-04-23 02:35:04 -04:00
jalbright015
cb1faea2f5
Updated documentation for clone_object() and new() efuns (#794)
* Updated documentation for clone_object() and new() efuns

* Updated documentation index

* Updating documentation for new() and clone_object() efuns
2021-04-17 21:57:47 -04:00
jalbright015
b13f0ebd9d
Added perf_counter_ns() documentation (#792)
* Added documentation for defer() efun

* Updated index to reflect defer() documentation

* Added documentation for new efun perf_counter_ns()

* Updated index to reflect perf_counter_ns() documentation

* Added documentation for new efun perf_counter_ns()

* Updated index to reflect perf_counter_ns() documentation
2021-04-16 13:27:16 -04:00
jalbright015
69351d52e6
Added documentation for defer() efun (#791)
* Added documentation for defer() efun

* Updated index to reflect defer() documentation
2021-04-16 11:36:23 -04:00
Yucong Sun
c20ca9a15e Update doc index 2021-04-11 01:45:36 +08:00
Yucong Sun
5eafddf8bb
stdlib: base64encode/base64decode from Gesslar (#770)
* new sefuns base64encode, base64decode

* update docs

* stdlib: base64encode/base64decode

Co-authored-by: Brian Workman <bworkman@frogdice.com>
2021-03-25 05:43:16 +08:00
Yucong Sun
868d2db57b EFUN: strptime() and strftime() 2021-02-23 17:58:02 -08:00
Yucong Sun
f395a8884d fix build errors 2020-12-13 18:10:32 -08:00
Yucong Sun
42b286f067 Some cleanup on the docs 2020-12-10 18:35:31 -08:00
Yucong Sun
f9531c05cc cleanup doc index generation, upgrade to python3 2020-12-10 18:35:31 -08:00
oiuv
e836be493c update docs 2020-12-06 09:49:10 -08:00
oiuv
77d1033add update docs & http.c 2020-11-17 19:46:52 -08:00
Yucong Sun
0650d9e73b Adding EFUN pcre_match_all 2020-11-10 13:36:29 -08:00
Yucong Sun
53e789890f Update doc 2020-11-10 13:36:29 -08:00
oiuv
5023af8875 update docs 2020-10-31 23:38:58 +08:00
gesslar
c93349f5c0 Update simul_efun.md
Corrected typo and switched "static" to "protected".
2020-10-31 14:44:18 +08:00
Yucong Sun
1c622e5ba4 Upgrade backward-cpp 2020-10-11 18:46:33 -07:00
Yucong Sun
ae71e49c60 apply: virtual_start() for virtual objects 2020-08-25 20:46:10 -07:00
Yucong Sun
553e97ee97 Adding efun: telnet_nop() 2020-08-20 00:11:40 -07:00
Yucong Sun
6833890533 Implement secure_random() efun 2020-07-23 00:18:24 -07:00
oiuv
8b7baa7fb9 update docs 2020-05-09 09:35:19 -07:00
Yucong Sun
34f226a938 Adding an VMTracer that could output to chrome devtools 2020-04-13 23:25:27 -07:00
噢哎哟喂
294cf88049
update docs,fix lpcc (#615)
* update rouge.css

* update build.md

* fix lpcc

* update docs

* update index
2020-03-19 08:56:48 -07:00
oiuv
5d71ec806b update docs 2020-03-18 07:48:45 -07:00
Yucong Sun
0e00716be6 Fix issue in gen_index.py 2020-03-14 20:50:00 -07:00
Yucong Sun
0a5ebfd371 more doc website fix 2020-03-12 02:35:52 -07:00
Yucong Sun
84a088fcee Update docs to bootstrap 4.4 2020-03-12 02:31:31 -07:00
oiuv
9e12e9494b update docs index 2020-03-11 21:53:17 -07:00
oiuv
9d53b19dec add trim efun docs, format lpc docs 2020-03-11 21:53:17 -07:00
oiuv
8acd71f939 update docs index 2020-03-10 08:57:53 -07:00
Yucong Sun
1b05852a94 stdlib: break_string.c 2020-03-09 00:42:16 -07:00
Yucong Sun
465ae9cd66 Update docs 2020-01-13 23:40:37 -08:00