npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

placitum-lsp

v0.1.0

Published

Language server for Placitum — static analysis only, never executes code.

Readme

placitum-lsp

Language Server Protocol (LSP) server for Placitum, a capability-secure shell language where every effectful operation is syntactically visible (name!(...)), statically enumerable, and runtime-enforced.

The server is a pure static analyzer: it never executes Placitum code. It reuses the core language implementation (placitum, lexer/parser/extractor/explain) verbatim and exposes it over JSON-RPC on stdio, so any spec-compliant editor works.

Status

Phases 0–6 complete. The repository scaffold is in place (strict TypeScript, ESLint import boundaries, dependency allow-list, core placitum from npm), and the server runs over stdio: lifecycle, incremental document sync, per-version analysis cache, debounced push diagnostics, workspace/configuration + initializationOptions settings, and stderr-only logging. Diagnostics cover the core pipeline (E1xx–E3xx, tolerant multi-error lexing) plus the LSP analysis engine: binder E500/E506, #!strict E505, and definitely-certain literal checks E501–E504, each with exact UTF-16 ranges and config gates. Navigation is live: definition / type definition (LocationLink or Location per client), references, scope-aware rename, document symbols (hierarchical or flat), and capped on-demand workspace symbols with an mtime cache, watched-file invalidation and multi-root folder changes. Intelligence is live too: context-aware completion, hover (bindings, builtins, members, bang coverage, capability tokens, keywords), signature help (with pipe prepend), semantic tokens (full and deltas), folding, selection ranges and document highlights — all with fallbacks that keep working on half-typed files. Diagnostics can be pulled (textDocument/diagnostic) by clients that support it, with push for the rest. Capability UX is live: deterministic quick fixes (add needs, insert }, declare with let, rename redeclarations), code lens over needs clauses, optional inlay hints, the custom placitum/manifest request whose markdown is the core explain output byte for byte, and the commands placitum.showManifest / placitum.reanalyze / placitum.addNeeds. Compatibility is hardened and documented: every feature degrades per client capability, copy-paste recipes ship in editors/ for Neovim, Helix, Emacs, Zed, Sublime, Vim and Kate, and docs/COMPATIBILITY.md holds the capability-by-capability matrix. Packaging is release-ready: npm pack contents are snapshotted and npm run smoke:pack installs the tarball in a fresh temp project and runs a raw stdio E2E against the installed binary; the VS Code handoff spec is complete in docs/VSCODE-HANDOFF.md. npm run ci is green (typecheck, lint, build, 274 unit/protocol/e2e tests, a stdout-purity check, Neovim E2E driving the shipped recipe for rename, completion, hover, diagnostics and the manifest, and the packaging smoke).

Features

| Feature | Details | |---|---| | Diagnostics | Core error codes (E1xx–E5xx) with exact ranges; push plus pull (textDocument/diagnostic) for clients that declare support; syntax errors never crash the server | | Completion | Context-aware: capabilities after needs, fs.read/fs.write, pipe stages, member access, snippets | | Hover | Bindings, bang calls, capability tokens, deferred (runtime) capability checks | | Navigation | Definition, type definition, references, rename (prepareRename), document/workspace symbols (multi-root) | | Intelligence | Signature help, semantic tokens (full + delta), folding, selection ranges, document highlights | | Capability UX | Quick fixes (add needs, insert }, rename), code lens, inlay hints, placitum/manifest | | Configuration | workspace/configuration + initializationOptions.placitum, defensive parsing |

Capabilities advertised at initialize: positionEncoding: utf-16, incremental sync, completion (" ", ".", "|" triggers), hover, signature help, definition, type definition, references, rename, symbols, highlights, folding, selection ranges, quick fixes, code lens, inlay hints, semantic tokens (full + delta), pull diagnostics (when the client declares textDocument.diagnostic), and the commands placitum.showManifest, placitum.reanalyze, placitum.addNeeds.

Requirements

  • Node.js >= 20 (Node 22 recommended; the dev shell pins nodejs_22).
  • npm (the core placitum package comes from the registry).
  • Optional: Nix with flakes + direnv for a reproducible dev shell.

Install

Development (this repository)

# Option A: Nix dev shell (Node 22)
nix develop          # or: direnv allow

# Install dependencies (core `placitum` from npm)
npm install

# Build once the server sources land
npm run build

# Put `placitum-lsp` on PATH for local editors
npm link

Per project

npm install --save-dev placitum-lsp
npx placitum-lsp --stdio

Global

npm install -g placitum-lsp
placitum-lsp --stdio

Publishing to npm is not enabled yet; until then use npm link / a packed tarball (npm pack). The server must always be reachable as placitum-lsp on PATH.

CLI

placitum-lsp [--stdio] [--version] [--help]
             [--log-level=<error|info|debug|trace>] [--log-file=<path>]
  • --stdio — transport (default). Only stdio is supported; --node-ipc / --socket are rejected loudly with exit code 2.
  • --version, --help — print and exit.
  • --log-level, --log-file — logging. stdout carries only JSON-RPC frames; all logs go to stderr (or the log file).

Editor setup

Minimal client contract: initialize + didOpen/didChange/didClose + publishDiagnostics are enough. Everything else degrades gracefully.

Neovim (>= 0.11)

vim.filetype.add({ extension = { placitum = "placitum" } })

vim.lsp.config("placitum", {
  cmd = { "placitum-lsp", "--stdio" },
  filetypes = { "placitum" },
  root_markers = { ".git" },
})

vim.lsp.enable("placitum")

-- Optional: show the capability manifest in a floating window
vim.api.nvim_create_user_command("PlacitumManifest", function()
  local bufnr = vim.api.nvim_get_current_buf()
  local uri = vim.uri_from_bufnr(bufnr)
  vim.lsp.buf_request(bufnr, "placitum/manifest", { textDocument = { uri = uri } },
    function(_, result)
      if not result then return end
      local lines = vim.split(result.markdown, "\n")
      local win = vim.api.nvim_open_win(vim.api.nvim_create_buf(false, true), true, {
        relative = "editor", width = math.min(80, vim.o.columns - 4),
        height = math.min(#lines, vim.o.lines - 4), row = 2, col = 2,
        style = "minimal", border = "rounded", title = " Placitum manifest ",
      })
      vim.api.nvim_buf_set_lines(vim.api.nvim_win_get_buf(win), 0, -1, false, lines)
      vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = vim.api.nvim_win_get_buf(win) })
    end)
end, {})

A ready-to-copy version (plus an nvim-lspconfig 0.10 variant) is shipped in editors/neovim/.

Helix

editors/helix/languages.toml:

[language-server.placitum]
command = "placitum-lsp"
args = ["--stdio"]

[[language]]
name = "placitum"
scope = "source.placitum"
file-types = ["placitum"]
language-servers = ["placitum"]
comment-token = "#"
indent = { tab-width = 4, unit = "    " }

Check detection with hx --health placitum. A tree-sitter grammar is required for syntax highlighting; diagnostics, completion, and hover work without one.

VS Code

The thin extension is built in a separate (teammate) repository. The server is extension-ready: stdio transport, no client-specific code, and the full handoff spec lives in docs/VSCODE-HANDOFF.md. The extension bundles the server, so no global install is needed.

Emacs (eglot / lsp-mode), Zed, Sublime, Vim, Kate

Copy-paste recipes live in editors/emacs/, editors/zed/, editors/sublime/, editors/vim/, and editors/kate/. Zed example:

{
  "lsp": {
    "placitum-lsp": {
      "binary": { "path": "placitum-lsp", "arguments": ["--stdio"] }
    }
  },
  "languages": {
    "Placitum": {
      "language_servers": ["placitum-lsp"],
      "file_types": ["placitum"]
    }
  }
}

Configuration

Served under the placitum section via workspace/configuration; initializationOptions.placitum overrides defaults at startup. Unknown keys and wrong types fall back to defaults.

{
  "placitum.diagnostics.enable": true,
  "placitum.diagnostics.scope": true,          // E500/E506 binder checks
  "placitum.diagnostics.strictChecks": true,   // E505 + literal-type checks
  "placitum.completion.enable": true,
  "placitum.completion.snippets": true,
  "placitum.codeLens.enable": true,
  "placitum.inlayHints.enable": false,
  "placitum.inlayHints.capabilities": false,
  "placitum.workspaceSymbols.enable": true,
  "placitum.workspaceSymbols.maxFiles": 2000,
  "placitum.trace.server": "off"
}

Changing configuration triggers re-analysis and republished diagnostics.

Development

npm install
npm run ci         # check-deps -> tsc --noEmit -> eslint -> build -> vitest -> pack smoke
npm test           # vitest run (no packaging smoke; works offline)
npm run smoke:pack # npm pack -> temp install -> --version/--help -> raw stdio E2E

For manual testing there is a git-ignored playground/ (Zed project settings that redirect a built-in language server to placitum-lsp, an isolated Neovim launcher, and demo files for clean/error/syntax cases); see playground/README.md.

Layout (target, per directive):

src/
  bin.ts              entry point (shebang, CLI flags, startServer)
  server.ts           connection, capabilities, handler wiring
  documents.ts        document map, analysis cache, debounce
  config.ts  log.ts   settings, stderr/file logging
  workspace/files.ts  the only fs reader (workspace symbol scan)
  analysis/           core-adapter, positions, comments, binder, types,
                      checks, capabilities, model
  features/           diagnostics, hover, completion, signature, definition,
                      references, rename, symbols, semantic-tokens, folding,
                      selection, highlights, code-actions, code-lens,
                      inlay-hints, manifest-command
editors/              ready-to-copy client recipes (see editors/README.md)
tests/                unit/ , protocol/ , fixtures/ , e2e/
docs/                 PHASES.md (bitácora por fase), VSCODE-HANDOFF.md,
                      CORE-VERSION.md, COMPATIBILITY.md, EDITOR-CHECKLIST.md

Rules that make the server safe and portable:

  • Never any, @ts-ignore, or @ts-expect-error; TypeScript strict mode.
  • Only the core barrel (placitum) may be imported, and only through src/analysis/core-adapter.ts; no evaluator/guard/stdlib/host-bindings.
  • No child_process, network, or OS modules in feature code; user files are untrusted text and are never written directly (edits go through WorkspaceEdit).
  • Logs never touch stdout; failures are contained, never crash the server.
  • Dependencies are restricted to the allow-list in the directive (Section 4.3).

Troubleshooting

| Symptom | Check | |---|---| | Server not starting | placitum-lsp --version; ensure node >= 20 and placitum-lsp is on PATH | | No diagnostics | Confirm the buffer filetype is placitum and the file is open (push diagnostics need didOpen) | | Want logs | --log-level=debug (or trace) and optionally --log-file=<path>; logs go to stderr only | | Helix missing features | hx --health placitum; highlighting needs a tree-sitter grammar | | Manifest view | Call placitum/manifest (Neovim command above) or run npx placitum explain <file> |

License

MIT © The Placitum Authors (AUTHORS). You may use, modify, and redistribute this software, including bundling it in an editor extension, as long as the copyright notice and the license text are kept. Release history lives in CHANGELOG.md.