Overview Modules cli cli::AddOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD AddOpts url : string tag : string rev : string branch : string path : string name : string cli::Args Parses argv with clap-derive into the chosen subcommand and its options, then
dispatches to the matching command handler.
Sequence Sequence — dispatch scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE dispatch PERSON caller COMPONENT Args Pseudoscript::Cli Parses argv with clap-derive into the 1 dispatch(command: cli::Command) ↩ return number component CheckCmd # private cli::CheckCmd `pds check` — parse and statically check one file, print each diagnostic as
`path:line:col: severity: message`, and exit non-zero on any error-severity
diagnostic. Emits no diagram.
Scenarios CheckExitCode
`pds check` exits non-zero when any error diagnostic is produced.
given a .pds source file when the developer runs `pds check` on it then every diagnostic is printed as path:line:col: severity: message but the command exits non-zero if any diagnostic is error-severity and a well-formed model prints nothing and exits zero Flow Flow — CheckExitCode scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE CheckExitCode for CheckCmd GIVEN a .pds source file WHEN the developer runs `pds check` on it THEN every diagnostic is printed as path:line:col: severity: message BUT the command exits non-zero if any diagnostic is error-severity AND a well-formed model prints nothing and exits zero Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run alt [found.isErr] [else] alt [else self.isDirectory()] alt [root.isErr] [else] COMPONENT CheckCmd Pseudoscript::Cli `pds check` — parse and statically check COMPONENT Loader Pseudoscript::Cli The CLI loader: resolves the project CONTAINER Project Pseudoscript `crates/pseudoscript-project`. The disk-facing COMPONENT Loader Pseudoscript::Project Resolves and reads a workspace off disk: 1 findRoot(start: string) 2 findRoot(start: string) 3 findRoot(start: string) ↩ return Result<string, project::IoError> ↩ return Result<string, project::IoError> 4 ioError ↩ Err<cli::IoError> ↩ Ok<string> 5 isDirectory 6 checkRootless 7 checkWorkspace Sequence Sequence — runAll scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE runAll alt [else roots.isErr] COMPONENT CheckCmd Pseudoscript::Cli `pds check` — parse and statically check COMPONENT Loader Pseudoscript::Cli The CLI loader: resolves the project 1 discoverWorkspaces(root: string) ↩ return Result<string[], cli::IoError> 2 checkEach cli::CheckOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD CheckOpts file : string all : bool cli::Cli `crates/pseudoscript` — the binary crate (`pds`). The composition root and
only I/O edge; a thin frontend that wires the pure library crates to disk,
HTTP, and a filesystem watcher.
Scenarios CompositionRoot
The CLI is the composition root and the only I/O edge.
given the library crates that are pure over in-memory modules when the CLI runs any subcommand then all file reading, writing, HTTP serving, and watching happen in the CLI and the pure core receives module text and returns values but I/O and load failures are the only things that fail a command, via the exit code Flow Flow — CompositionRoot scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE CompositionRoot for Cli GIVEN the library crates that are pure over in-memory modules WHEN the CLI runs any subcommand THEN all file reading, writing, HTTP serving, and watching happen in the CLI AND the pure core receives module text and returns values BUT I/O and load failures are the only things that fail a command, via the exit code ParseSubcommand
argv is parsed into one subcommand and dispatched.
given a command line for one of init, doc, check, eval, fmt, tokens, outline, svg, lsp, lang, skill, add, install, update, remove, list, or upgrade when the CLI starts then clap parses argv into the chosen subcommand and its options and the matching command handler is invoked but an unrecognised command or bad option is rejected with a usage error Flow Flow — ParseSubcommand scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE ParseSubcommand for Cli GIVEN a command line for one of init, doc, check, eval, fmt, tokens, outline, svg, lsp, lang, skill, add, install, update, remove, list, or upgrade WHEN the CLI starts THEN clap parses argv into the chosen subcommand and its options AND the matching command handler is invoked BUT an unrecognised command or bad option is rejected with a usage error Components Component diagram scroll to zoom · drag to pan + − ⟲ ⤢ Pseudoscript Cli COMPONENT InitCmd `pds init` — bootstrap a workspace: write `pds.toml` and a starter `main.pds`. Refuse… COMPONENT Args Parses argv with clap-derive into the chosen subcommand and its options, then dispatches… COMPONENT Loader The CLI loader: resolves the project root and reads its modules through the `project`… COMPONENT DocCmd `pds doc` — the headline command (ADR-017). Load the workspace, check it per module… COMPONENT CheckCmd `pds check` — parse and statically check one file, print each diagnostic as… COMPONENT EvalCmd `pds eval` — read a model from stdin and statically check it, printing each… COMPONENT FmtCmd `pds fmt` — format to canonical PseudoScript; `--write` overwrites the file… COMPONENT TokensCmd `pds tokens` — print the conformance token stream (`KIND@line:col "lexeme"`) to stdout… COMPONENT LspHost `pds lsp` — boot a Tokio runtime and launch the language server over stdio. Spawned as … COMPONENT ReferenceCmd `pds lang` (alias `spec`) and `pds skill` — print the bundled, version-pinned language… COMPONENT OutlineCmd `pds outline` — walk the workspace's modules, build its graph, and print the… COMPONENT SvgCmd `pds svg` — render a single diagram to a self-contained SVG on stdout. With… COMPONENT Deps `pds add`/`install`/`update`/`remove`/`list` — git workspace dependency management… COMPONENT UpgradeCmd `pds upgrade` — download a release and install it over the running binary. COMPONENT HttpServer HTTP host for the generated site (`--serve`/`--watch`): `tiny_http` on… COMPONENT Watcher Filesystem watcher (`--watch`, via `notify`): watches the project root… CONTAINER Doc `crates/pseudoscript-doc`. Turns a resolved graph into a Svelte-rendered,… CONTAINER Format `crates/pseudoscript-format`. The canonical formatter: parse, then pretty-print the tre… CONTAINER Lsp `crates/pseudoscript-lsp`. The stdio language server (tower-lsp): workspace… CONTAINER Model `crates/pseudoscript-model`. AST to one resolved graph; static checks (resolution,… CONTAINER Project `crates/pseudoscript-project`. The disk-facing loader: resolves the workspace… CONTAINER Syntax `crates/pseudoscript-syntax`. The foundation crate: source text to tokens and a typed… discoverWorkspaces findRoot load check checkWorkspace serve discoverWorkspaces findRoot load watch prepareDiagnostics render renderMarkdown checkWorkspaceModules graph check format findRoot load runStdio findRoot loadModules graph findRoot loadModules graph renderTokens parse parse cli::Command The subcommand clap parsed from argv, with its resolved options.
Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ UNION Command InitCmd DocOpts CheckOpts EvalOpts FmtOpts TokensOpts OutlineOpts SvgOpts LspOpts LangOpts SkillOpts AddOpts InstallOpts UpdateOpts RemoveOpts ListOpts UpgradeOpts RECORD DocOpts path : string serve : bool watch : bool port : number all : bool format : string RECORD CheckOpts file : string all : bool RECORD FmtOpts file : string write : bool RECORD TokensOpts file : string RECORD OutlineOpts path : string RECORD SvgOpts path : string symbol : string view : string target : string theme : string RECORD AddOpts url : string tag : string rev : string branch : string path : string name : string RECORD RemoveOpts name : string RECORD ListOpts root : string RECORD UpgradeOpts version : string cli::Deps `pds add`/`install`/`update`/`remove`/`list` — git workspace dependency
management (§8.3). `add` resolves a git URL into `pds.toml` + `pds.lock` and
vendors it; `install` restores `pds_modules/` from the lock; `update`
re-pins; `remove` drops one; `list` discovers every workspace under a root.
Resolution delegates to `project`; fetching is the CLI's I/O.
Scenarios ManageDependencies
Dependency commands manage git workspaces via pds.toml and pds.lock (§8.3).
given a workspace declaring git dependencies when the developer runs add, install, update, remove, or list then add pins and vendors a dependency, install restores from the lock, update re-pins, remove drops one and resolution delegates to the project crate while fetching is the CLI's I/O Flow Flow — ManageDependencies scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE ManageDependencies for Deps GIVEN a workspace declaring git dependencies WHEN the developer runs add, install, update, remove, or list THEN add pins and vendors a dependency, install restores from the lock, update re-pins, remove drops one AND resolution delegates to the project crate while fetching is the CLI's I/O Sequence Sequence — add scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE add PERSON caller COMPONENT Deps Pseudoscript::Cli `pds add`/`install`/`updat… 1 add(url: string, tag: string, rev: string, branch: string, path: string, name: string) ↩ return Result<void, cli::IoError> Sequence Sequence — install scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE install PERSON caller COMPONENT Deps Pseudoscript::Cli `pds add`/`install`/`updat… 1 install() ↩ return Result<void, cli::IoError> Sequence Sequence — list scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE list PERSON caller COMPONENT Deps Pseudoscript::Cli `pds add`/`install`/`updat… 1 list(root: string) ↩ return Result<void, cli::IoError> Sequence Sequence — remove scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE remove PERSON caller COMPONENT Deps Pseudoscript::Cli `pds add`/`install`/`updat… 1 remove(name: string) ↩ return Result<void, cli::IoError> Sequence Sequence — update scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE update PERSON caller COMPONENT Deps Pseudoscript::Cli `pds add`/`install`/`updat… 1 update() ↩ return Result<void, cli::IoError> component DocCmd # private cli::DocCmd `pds doc` — the headline command (ADR-017). Load the workspace, check it per
module (reported but non-fatal, like `cargo doc` — the same findings feed the
site's health page), project the resolved graph, and render a static doc
site. The output format is resolved by precedence — an explicit `--format`
over the manifest `[doc].format`, else HTML — then a fork renders the SSR
HTML site (every diagram as server SVG, logo copied) or a flat Markdown site
(SVG assets, no logo). `--serve` hosts the HTML site over HTTP; `--watch`
adds a filesystem watcher and browser live reload; both are skipped for
Markdown output, which only writes.
#headline
Scenarios DocPipeline
`pds doc` runs the headline pipeline end to end.
given a project rooted at a pds.toml with one or more .pds modules and no --format override, so the HTML default applies when the developer runs `pds doc` then the workspace is loaded and checked and the resolved graph is built and rendered to the HTML site and every site file is written under the output directory and the configured logo is copied beside the site Flow Flow — DocPipeline scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE DocPipeline for DocCmd GIVEN a project rooted at a pds.toml with one or more .pds modules AND no --format override, so the HTML default applies WHEN the developer runs `pds doc` THEN the workspace is loaded and checked AND the resolved graph is built and rendered to the HTML site AND every site file is written under the output directory AND the configured logo is copied beside the site ResolveDocFormat
The output format is resolved by precedence and forks the renderer.
given a workspace whose `[doc].format` and the `--format` flag may each set a format when the developer runs `pds doc` then an explicit `--format` wins over the manifest `[doc].format`, else HTML and HTML renders the SSR site and copies the logo but Markdown renders the flat site with its SVG inlined and copies no logo Flow Flow — ResolveDocFormat scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE ResolveDocFormat for DocCmd GIVEN a workspace whose `[doc].format` and the `--format` flag may each set a format WHEN the developer runs `pds doc` THEN an explicit `--format` wins over the manifest `[doc].format`, else HTML AND HTML renders the SSR site and copies the logo BUT Markdown renders the flat site with its SVG inlined and copies no logo MarkdownSkipsServing
Markdown output writes but never serves or watches.
given the resolved format is Markdown when the developer runs `pds doc --serve` or `--watch` then the Markdown site is written to the output directory but serving and watching are skipped, so the command returns after writing Flow Flow — MarkdownSkipsServing scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE MarkdownSkipsServing for DocCmd GIVEN the resolved format is Markdown WHEN the developer runs `pds doc --serve` or `--watch` THEN the Markdown site is written to the output directory BUT serving and watching are skipped, so the command returns after writing CheckIsNonFatal
The workspace check is reported but never aborts generation.
given a workspace whose model has warnings or errors when the developer runs `pds doc` then every diagnostic is printed to stderr but generation continues like `cargo doc`, so a partial model still documents and only an I/O or load failure exits non-zero Flow Flow — CheckIsNonFatal scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE CheckIsNonFatal for DocCmd GIVEN a workspace whose model has warnings or errors WHEN the developer runs `pds doc` THEN every diagnostic is printed to stderr BUT generation continues like `cargo doc`, so a partial model still documents AND only an I/O or load failure exits non-zero Sequence Sequence — runAll scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE runAll alt [else roots.isErr] COMPONENT DocCmd Pseudoscript::Cli `pds doc` — the headline command COMPONENT Loader Pseudoscript::Cli The CLI loader: resolves the project 1 discoverWorkspaces(root: string) ↩ return Result<string[], cli::IoError> 2 buildEach Sequence Sequence — serve scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE serve alt [watch] alt [else !self.shouldServe()] alt [else !self.isHtml()] alt [else built.isErr] COMPONENT DocCmd Pseudoscript::Cli `pds doc` — the headline command COMPONENT Watcher Pseudoscript::Cli Filesystem watcher (`--watch`, via COMPONENT HttpServer Pseudoscript::Cli HTTP host for the generated site 1 run 2 isHtml 3 shouldServe 4 watch(root: string, port: number) ↩ return Result<void, cli::IoError> 5 serve(path: string, port: number, reload: bool) ↩ return Result<void, cli::IoError> cli::DocOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD DocOpts path : string serve : bool watch : bool port : number all : bool format : string component EvalCmd # private cli::EvalCmd `pds eval` — read a model from stdin and statically check it, printing each
diagnostic as `<stdin>:line:col: severity: message` and exiting non-zero on
any error. The fileless path: an agent pipes a snippet to check it without
writing a file.
Scenarios EvalExitCode
`pds eval` reads stdin and exits non-zero when any error diagnostic is produced.
given a model piped to stdin when the developer or an agent runs `pds eval` then every diagnostic is printed as <stdin>:line:col: severity: message but the command exits non-zero if any diagnostic is error-severity and a well-formed model prints nothing and exits zero Flow Flow — EvalExitCode scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE EvalExitCode for EvalCmd GIVEN a model piped to stdin WHEN the developer or an agent runs `pds eval` THEN every diagnostic is printed as <stdin>:line:col: severity: message BUT the command exits non-zero if any diagnostic is error-severity AND a well-formed model prints nothing and exits zero Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run COMPONENT EvalCmd Pseudoscript::Cli `pds eval` — read a model from stdin and CONTAINER Model Pseudoscript `crates/pseudoscript-model`. AST to one resolved COMPONENT Checks Pseudoscript::Model Static analysis (LANG.md §2.2, §2.3, CONTAINER Syntax Pseudoscript `crates/pseudoscript-syntax`. The foundation crate: COMPONENT Parser Pseudoscript::Syntax Recursive-descent parser for the §10 COMPONENT Lexer Pseudoscript::Syntax Hand-written lexer for LANG.md §2. One pass 1 check(text: string) 2 check(text: string) 3 parse(text: string) 4 parse(text: string) 5 lex(text: string) ↩ return syntax::Lexed 6 parseModule 7 diagnostics ↩ return syntax::Parsed ↩ return syntax::Parsed 8 analyze ↩ return syntax::Diagnostic[] ↩ return syntax::Diagnostic[] 9 anyError component FmtCmd # private cli::FmtCmd `pds fmt` — format to canonical PseudoScript; `--write` overwrites the file in
place, otherwise prints to stdout. A parse error is reported and the file is
left untouched.
Scenarios FormatInPlaceOrStdout
`pds fmt --write` overwrites in place; otherwise it prints.
given a .pds source file when the developer runs `pds fmt` then the source is parsed and pretty-printed to canonical PseudoScript and with `--write` the file is overwritten in place but without `--write` the canonical text is printed to stdout and unparseable source is reported and the file is left untouched Flow Flow — FormatInPlaceOrStdout scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE FormatInPlaceOrStdout for FmtCmd GIVEN a .pds source file WHEN the developer runs `pds fmt` THEN the source is parsed and pretty-printed to canonical PseudoScript AND with `--write` the file is overwritten in place BUT without `--write` the canonical text is printed to stdout AND unparseable source is reported and the file is left untouched Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run alt [self.hasErrors()] [else] alt [write] [else] alt [else out.isErr] COMPONENT FmtCmd Pseudoscript::Cli `pds fmt` — format to canonical CONTAINER Format Pseudoscript `crates/pseudoscript-format`. The canonical COMPONENT Formatter Pseudoscript::Format Drives the headline flow: parse the CONTAINER Syntax Pseudoscript `crates/pseudoscript-syntax`. The foundation crate: COMPONENT Parser Pseudoscript::Syntax Recursive-descent parser for the §10 COMPONENT Lexer Pseudoscript::Syntax Hand-written lexer for LANG.md §2. One pass COMPONENT Printer Pseudoscript::Format The canonical pretty-printer: walks 1 format(text: string) 2 format(text: string) 3 parse(text: string) 4 parse(text: string) 5 lex(text: string) ↩ return syntax::Lexed 6 parseModule 7 diagnostics ↩ return syntax::Parsed ↩ return syntax::Parsed 8 hasErrors 9 collectErrors ↩ Err<format::FormatError> 10 print(ast: syntax::Module) 11 writeModule 12 finish ↩ return string ↩ Ok<string> ↩ return Result<string, format::FormatError> 13 overwrite 14 print cli::FmtOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD FmtOpts file : string write : bool component HttpServer # private cli::HttpServer HTTP host for the generated site (`--serve`/`--watch`): `tiny_http` on
`127.0.0.1:port`, maps `/` to `index.html`, rejects paths escaping the output
dir, and on watch injects a live-reload poll and answers `/__livereload` with
the current version. Blocks until the process is stopped.
Scenarios ServeOverHttp
`pds doc --serve` hosts the generated site over HTTP on localhost.
given a generated documentation site when the developer runs `pds doc --serve` then the site is hosted over HTTP on 127.0.0.1 at the chosen port and `/` maps to index.html but a request path that escapes the output directory yields 404 Flow Flow — ServeOverHttp scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE ServeOverHttp for HttpServer GIVEN a generated documentation site WHEN the developer runs `pds doc --serve` THEN the site is hosted over HTTP on 127.0.0.1 at the chosen port AND `/` maps to index.html BUT a request path that escapes the output directory yields 404 Sequence Sequence — serve scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE serve PERSON client COMPONENT HttpServer Pseudoscript::Cli HTTP host for the generated site 1 serve(path: string, port: number, reload: bool) ↩ return Result<void, cli::IoError> component InitCmd # private cli::InitCmd `pds init` — bootstrap a workspace: write `pds.toml` and a starter `main.pds`.
Refuses to overwrite an existing manifest; the starter is written only when
absent.
Scenarios InitWorkspace
`pds init` bootstraps a workspace and refuses to clobber an existing one.
given a target directory with no pds.toml when the developer runs `pds init` then the directory is created if absent and a pds.toml carrying a [doc] table is written and a starter main.pds is written when none exists but an existing pds.toml aborts the command without overwriting it Flow Flow — InitWorkspace scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE InitWorkspace for InitCmd GIVEN a target directory with no pds.toml WHEN the developer runs `pds init` THEN the directory is created if absent AND a pds.toml carrying a [doc] table is written AND a starter main.pds is written when none exists BUT an existing pds.toml aborts the command without overwriting it Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run alt [else exists.isErr] COMPONENT InitCmd Pseudoscript::Cli `pds init` — bootstrap a workspace: write 1 manifestExists 2 writeFiles cli::IoError A filesystem, parse-config, or serving failure surfaced to the CLI exit code.
Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD IoError message : string cli::ListOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD ListOpts root : string component Loader # private cli::Loader The CLI loader: resolves the project root and reads its modules through the
`project` crate (the shared filesystem edge), then parses the cli-specific
`[doc]` table on top. Root-finding and module-walking are `project`'s job;
the manifest's doc config is the CLI's.
Outbound call → project::Project · findRoot from → cli::Result from → cli::Result from → cli::Result call → project::Project · load from → cli::Result from → cli::Result from → cli::Result from → cli::Result from → cli::Result from → cli::Result from → cli::Result from → cli::Result from → cli::Result from → cli::Result Scenarios ResolveProjectRoot
The project root is found by walking up to the nearest pds.toml.
given a path somewhere inside a project tree when the CLI loads the workspace then it walks ancestor directories to the nearest pds.toml and the [doc] config and every .pds module beneath it load, sorted by FQN but a tree with no pds.toml is an error Flow Flow — ResolveProjectRoot scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE ResolveProjectRoot for Loader GIVEN a path somewhere inside a project tree WHEN the CLI loads the workspace THEN it walks ancestor directories to the nearest pds.toml AND the [doc] config and every .pds module beneath it load, sorted by FQN BUT a tree with no pds.toml is an error component LspHost # private cli::LspHost `pds lsp` — boot a Tokio runtime and launch the language server over stdio.
Spawned as a child process by an editor (`context::Editor.openDocument`).
Scenarios LaunchLanguageServer
`pds lsp` launches the language server over stdio.
given an editor that speaks the Language Server Protocol when the editor spawns `pds lsp` as a child process then a Tokio runtime boots and the server runs over stdio and the editor drives it with document changes and renders its diagnostics Flow Flow — LaunchLanguageServer scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE LaunchLanguageServer for LspHost GIVEN an editor that speaks the Language Server Protocol WHEN the editor spawns `pds lsp` as a child process THEN a Tokio runtime boots and the server runs over stdio AND the editor drives it with document changes and renders its diagnostics component OutlineCmd # private cli::OutlineCmd `pds outline` — walk the workspace's modules, build its graph, and print the
symbol outline as JSON: each node's `fqn`, `name`, `kind`, `parent`, whether it
is a triggered flow entry, and its declaration site. The structure tree an
editor draws. Outlining reads the walked modules straight, skipping the manifest
`[doc]` parse and dependency resolution: the structure tree never depends on
presentation config or external modules.
Scenarios OutlineAsJson
`pds outline` prints the workspace symbol tree as JSON.
given a workspace under the path when the developer runs `pds outline` then the workspace's modules are walked and its graph is built and each node's fqn, name, kind, parent, triggered flag, and declaration site is printed as JSON but the manifest [doc] config and dependency modules are not loaded Flow Flow — OutlineAsJson scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE OutlineAsJson for OutlineCmd GIVEN a workspace under the path WHEN the developer runs `pds outline` THEN the workspace's modules are walked and its graph is built AND each node's fqn, name, kind, parent, triggered flag, and declaration site is printed as JSON BUT the manifest [doc] config and dependency modules are not loaded Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run alt [found.isErr] [else] alt [modules.isErr] [else] alt [files.isErr] [else] alt [loaded.isErr] [else] alt [else modules.isErr] alt [else root.isErr] COMPONENT OutlineCmd Pseudoscript::Cli `pds outline` — walk the workspace's COMPONENT Loader Pseudoscript::Cli The CLI loader: resolves the project CONTAINER Project Pseudoscript `crates/pseudoscript-project`. The disk-facing COMPONENT Loader Pseudoscript::Project Resolves and reads a workspace off disk: CONTAINER Model Pseudoscript `crates/pseudoscript-model`. AST to one resolved COMPONENT Builder Pseudoscript::Model Projects the parsed, resolved workspace COMPONENT Workspace Pseudoscript::Model The resolved set of modules keyed by FQN 1 findRoot(start: string) 2 findRoot(start: string) 3 findRoot(start: string) ↩ return Result<string, project::IoError> ↩ return Result<string, project::IoError> 4 ioError ↩ Err<cli::IoError> ↩ Ok<string> 5 loadModules(root: string) 6 load(root: string) 7 load(root: string) 8 findModules ↩ Err<project::IoError> 9 readEach ↩ Err<project::IoError> ↩ Ok<model::WorkspaceModule[]> ↩ return Result<model::WorkspaceModule[], project::IoError> 10 ioError ↩ Err<cli::IoError> ↩ Ok<model::WorkspaceModule[]> 11 graph(modules: model::WorkspaceModule[]) 12 graph(modules: model::WorkspaceModule[]) 13 build(modules: model::WorkspaceModule[]) 14 noExternals 15 buildWithExternals ↩ return model::ModuleEntry[] 16 graphOf ↩ return model::Graph ↩ return model::Graph 17 render 18 print data OutlineOpts # public cli::OutlineOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD OutlineOpts path : string component ReferenceCmd # private cli::ReferenceCmd `pds lang` (alias `spec`) and `pds skill` — print the bundled, version-pinned
language reference and the authoring skill to stdout. Fed to an LLM to author
`.pds`; no workspace needed.
Scenarios PrintReference
`pds lang`/`pds skill` print the bundled reference and authoring skill.
given no workspace is needed when the developer runs `pds lang` or `pds skill` then the version-pinned language reference or the authoring skill is printed to stdout Flow Flow — PrintReference scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE PrintReference for ReferenceCmd GIVEN no workspace is needed WHEN the developer runs `pds lang` or `pds skill` THEN the version-pinned language reference or the authoring skill is printed to stdout Sequence Sequence — lang scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE lang PERSON caller COMPONENT ReferenceCmd Pseudoscript::Cli `pds lang` (alias `spec`) and `pds 1 lang() ↩ return Sequence Sequence — skill scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE skill PERSON caller COMPONENT ReferenceCmd Pseudoscript::Cli `pds lang` (alias `spec`) and `pds 1 skill() ↩ return cli::RemoveOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD RemoveOpts name : string component SvgCmd # private cli::SvgCmd `pds svg` — render a single diagram to a self-contained SVG on stdout. With
`--symbol`, draws that symbol's fitting view; otherwise draws `--view` (paired
with `--target`) over the whole workspace. The static counterpart of the IDE
canvas. Like `pds outline`, it reads the walked modules straight, skipping the
manifest `[doc]` parse and dependency resolution: a diagram never depends on
presentation config or external modules.
Scenarios RenderOneSvg
`pds svg` renders one diagram to a self-contained SVG.
given a workspace and either a --symbol or a --view/--target selection when the developer runs `pds svg` then the chosen view is projected and rendered to a standalone SVG on stdout but a missing or wrong-kind target fails non-zero with the projection error Flow Flow — RenderOneSvg scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE RenderOneSvg for SvgCmd GIVEN a workspace and either a --symbol or a --view/--target selection WHEN the developer runs `pds svg` THEN the chosen view is projected and rendered to a standalone SVG on stdout BUT a missing or wrong-kind target fails non-zero with the projection error Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run alt [found.isErr] [else] alt [modules.isErr] [else] alt [files.isErr] [else] alt [loaded.isErr] [else] alt [scene.isErr] [else] alt [else modules.isErr] alt [else root.isErr] alt [!self.isKnownTheme()] [else] COMPONENT SvgCmd Pseudoscript::Cli `pds svg` — render a single diagram to a COMPONENT Loader Pseudoscript::Cli The CLI loader: resolves the project CONTAINER Project Pseudoscript `crates/pseudoscript-project`. The disk-facing COMPONENT Loader Pseudoscript::Project Resolves and reads a workspace off disk: CONTAINER Model Pseudoscript `crates/pseudoscript-model`. AST to one resolved COMPONENT Builder Pseudoscript::Model Projects the parsed, resolved workspace COMPONENT Workspace Pseudoscript::Model The resolved set of modules keyed by FQN 1 isKnownTheme 2 unknownTheme 3 findRoot(start: string) 4 findRoot(start: string) 5 findRoot(start: string) ↩ return Result<string, project::IoError> ↩ return Result<string, project::IoError> 6 ioError ↩ Err<cli::IoError> ↩ Ok<string> 7 loadModules(root: string) 8 load(root: string) 9 load(root: string) 10 findModules ↩ Err<project::IoError> 11 readEach ↩ Err<project::IoError> ↩ Ok<model::WorkspaceModule[]> ↩ return Result<model::WorkspaceModule[], project::IoError> 12 ioError ↩ Err<cli::IoError> ↩ Ok<model::WorkspaceModule[]> 13 graph(modules: model::WorkspaceModule[]) 14 graph(modules: model::WorkspaceModule[]) 15 build(modules: model::WorkspaceModule[]) 16 noExternals 17 buildWithExternals ↩ return model::ModuleEntry[] 18 graphOf ↩ return model::Graph ↩ return model::Graph 19 projectChosen 20 emitError 21 renderThemed 22 print cli::SvgOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD SvgOpts path : string symbol : string view : string target : string theme : string component TokensCmd # private cli::TokensCmd `pds tokens` — print the conformance token stream (`KIND@line:col "lexeme"`)
to stdout, for debugging the lexer.
Scenarios PrintTokenStream
`pds tokens` prints the conformance token stream.
given a .pds source file when the developer runs `pds tokens` then the lexical token stream is printed as KIND@line:col \"lexeme\" Flow Flow — PrintTokenStream scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE PrintTokenStream for TokensCmd GIVEN a .pds source file WHEN the developer runs `pds tokens` THEN the lexical token stream is printed as KIND@line:col \"lexeme\" Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run COMPONENT TokensCmd Pseudoscript::Cli `pds tokens` — print the conformance token CONTAINER Syntax Pseudoscript `crates/pseudoscript-syntax`. The foundation crate: COMPONENT Lexer Pseudoscript::Syntax Hand-written lexer for LANG.md §2. One pass COMPONENT LineIndex Pseudoscript::Syntax Precomputed newline offsets turning a byt… 1 renderTokens(text: string) 2 renderTokens(text: string) 3 tokenize 4 build(src: string) ↩ return syntax::LineIndex 5 renderStream ↩ return string ↩ return string 6 print cli::TokensOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD TokensOpts file : string component UpgradeCmd # private cli::UpgradeCmd `pds upgrade` — download a release and install it over the running binary.
Sequence Sequence — run scroll to zoom · drag to pan + − ⟲ ⤢ SEQUENCE run PERSON caller COMPONENT UpgradeCmd Pseudoscript::Cli `pds upgrade` — download a release an… 1 run(version: string) ↩ return Result<void, cli::IoError> data UpgradeOpts # public cli::UpgradeOpts Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD UpgradeOpts version : string component Watcher # private cli::Watcher Filesystem watcher (`--watch`, via `notify`): watches the project root
recursively, debounces each save burst, and on a relevant change rebuilds the
site and bumps the version the browser's live-reload poll reads. Events under
the output dir are ignored so writing the site never re-triggers a build.
Scenarios WatchAndLiveReload
`pds doc --watch` rebuilds on change and live-reloads the browser.
given a site served with `--watch` when a .pds file or pds.toml under the root changes then the watcher debounces the save burst and rebuilds the site and the live-reload version is bumped and the browser, polling /__livereload, reloads to the new version but writes under the output directory are ignored so the build does not loop Flow Flow — WatchAndLiveReload scroll to zoom · drag to pan + − ⟲ ⤢ FEATURE WatchAndLiveReload for Watcher GIVEN a site served with `--watch` WHEN a .pds file or pds.toml under the root changes THEN the watcher debounces the save burst and rebuilds the site AND the live-reload version is bumped AND the browser, polling /__livereload, reloads to the new version BUT writes under the output directory are ignored so the build does not loop cli::Workspace The loaded project: the `[doc]` config, the resolved output directory
(`<root>/<out>`, default `target/doc`), every module sorted by FQN, the
dependency-name-prefixed dependency modules (§8.3; empty without a `pds.lock`),
and the preferred doc output format. Produced from the nearest `pds.toml`.
Entities Entity diagram scroll to zoom · drag to pan + − ⟲ ⤢ RECORD Workspace config : doc::DocConfig outDir : string modules : model::WorkspaceModule[] dependencies : model::WorkspaceModule[] format : string RECORD DocConfig name : string theme : doc::Theme logo : string docs : doc::DocGroup[] RECORD WorkspaceModule fqn : string source : string