Reference for metadata, inference rules, bindings, output modes, and runtime behavior in the JavaScript verb prototype.
This page is a compact reference for the JavaScript verb subsystem. Use it after you already understand the main flow and need exact rules instead of a tutorial narrative.
Think of this page as the answer key for the developer guide. The guide explains the shape of the system and why it exists. This page tells you the exact supported inputs and behaviors the current implementation promises. When you change behavior, this is one of the places that should move with the code so future readers can distinguish deliberate design from accidental current behavior.
Library entrypoints:
ScanDir(root, ...)ScanFS(fsys, root, ...)ScanSource(path, source, ...)ScanSources(files, ...)Command-compilation entrypoints:
registry.Commands()registry.CommandsWithInvoker(invoker)registry.CommandForVerb(verb)registry.CommandForVerbWithInvoker(verb, invoker)registry.CommandDescriptionForVerb(verb)Runtime entrypoints:
registry.invoke(...) via Commands() / CommandForVerb(...)registry.InvokeInRuntime(ctx, runtime, verb, parsedValues) for caller-owned runtimesregistry.RequireLoader() for composing the scanned-source loader into a host runtimeThe example runner uses ScanDir(...) plus the default registry.Commands() path, but the package itself is no longer limited to disk directories or to runtime-owning command wrappers.
Supported function declarations:
function name(...) {}const name = (...) => {}const name = function(...) {}Ignored for command discovery:
_Public functions are auto-exposed unless an explicit __verb__ definition overrides them.
This rule gives the subsystem a useful default: simple files can become command trees without much ceremony. At the same time, explicit __verb__ metadata remains the escape hatch when naming, grouping, or output semantics need to be different from the inferred default.
__package__({...})__section__("slug", {...})__verb__("functionName", {...})doc\...``The sentinels are statically extracted at scan time and installed as runtime no-ops during execution.
That means the same token can matter in two different ways: at scan time it carries meaning for command construction, and at runtime it only needs to exist so requiring the source does not fail. New developers sometimes conflate those roles, so it is worth being explicit that most sentinel behavior is compile-time metadata, not dynamic runtime logic.
Metadata values are parsed as a strict literal subset. Supported metadata values are:
true, false, nullUnsupported metadata values include:
__package__ fieldsCurrently used package metadata:
nameshortlongparentstagsPackage metadata mainly affects default command grouping.
In other words, package metadata shapes where commands live in the tree more than how the function itself is called. If you are debugging command hierarchy or unexpectedly nested verbs, package metadata is one of the first places to inspect.
__section__ fieldsSupported section fields:
titlenamedescriptionfieldsSection field definitions support the same field keys used under __verb__.
Sections are the main mechanism for sharing schema across multiple verbs in one file. They are especially useful when several commands conceptually operate over the same group of filters or options and you want the command line shape to reflect that shared structure.
Scope rule:
__section__ defines file-local sections only.Registry.AddSharedSection(...) or Registry.AddSharedSections(...).require() does not import metadata from another file. It only affects runtime code loading.
__verb__ fieldsSupported verb-level fields:
commandnameshortlongparentstagssectionsuseSectionsfieldsoutputoutputModemodeOutput aliases:
glazetablestructuredtextrawwriterplainMultiple aliases exist mostly for ergonomics while the subsystem is still evolving. In practice, using one canonical spelling per codebase is easier to read. For now, output: "text" and the default structured mode are the clearest choices.
Supported field metadata keys:
typehelpshortbindsectiondefaultchoicesrequiredargumentargThese keys are intentionally close to Glazed concepts. The subsystem is not inventing a separate CLI schema language; it is translating a small JavaScript-friendly metadata format into existing Glazed schema structures.
Supported field types currently map to Glazed like this:
string -> string fieldbool or boolean -> bool fieldint or integer -> integer fieldfloat or number -> float fieldstringList, list, []string -> string-list fieldchoice -> choice fieldchoiceList -> choice-list fieldobjectFromFile -> load one JSON/YAML object from a file and pass it to JavaScript as an objectobjectListFromFile -> load a list of objects from one fileobjectListFromFiles -> load object lists from multiple filesstringFromFile / stringFromFiles -> load string content from one or more filesstringListFromFile / stringListFromFiles -> load string lists from one or more filesfile / fileList -> load Glazed file data valueskeyValue -> parse key-value datadate -> date fieldintList / integerList -> integer-list fieldfloatList / numberList -> float-list fieldIf choices is set and no type is provided, the system treats the field as choice.
This is another example of the system preferring useful defaults over forcing constant ceremony. When the metadata already expresses a closed set of valid values, treating the field as a choice is usually what the author intended anyway.
If a parameter has no explicit field metadata:
Requiredness rule:
That requiredness rule is one of the most visible user-facing defaults in the subsystem. It is there to make the generated CLI behave like a serious command, not like an unconstrained JavaScript function call.
Parameters using object or array patterns are not treated as normal inferred positional values. They require an explicit bind, because the package now prefers one explicit binding contract over guesswork.
No bind:
bind: "all":
bind: "context":
verbfunctionmodulesourceFilerootDirvaluessectionsbind: "<section>":
Bindings are where a lot of expressiveness comes from. They let the generated CLI remain idiomatic on the Go side while still letting JavaScript authors think in terms of cohesive objects instead of only flat parameter lists.
Internally, bindings are resolved through a shared binding plan that is consumed by both command compilation and runtime invocation. The user-visible implication is simple: invalid binds should now fail consistently instead of becoming mismatched behavior between those two phases.
glaze mode:
GlazeCommand{value: ...}text mode:
WriterCommand[]byte is written directlyThat JSON fallback is a guardrail rather than a recommendation. If a text verb consistently returns structured objects, it is usually a sign that the command should probably be a structured verb instead.
If a JS function returns a Promise, the runtime polls promise state through the runtime owner and waits until the promise is fulfilled or rejected.
Behavior:
Promise support matters because it allows the runtime path to remain usable for more realistic JavaScript helpers instead of only synchronous utility functions. At the same time, the waiting logic is intentionally simple and explicit so developers can reason about how long-running or failing async code surfaces back into the CLI.
The current polling implementation is deliberately retained as version-1 behavior. It is documented as simple and temporary rather than as the final async design.
Execution uses a source loader that serves the source already stored in the registry and injects an overlay around it. The overlay captures top-level functions while preserving normal relative require() behavior.
Resolution currently tries:
require() resolver against that scanned module pathThis means relative helpers still work for directory scans, fs.FS scans, and raw in-memory source sets, as long as the referenced helper module is part of the scanned source set.
The scanner records diagnostics on the registry and, by default, fails with ScanError when error diagnostics are present.
Practical implications:
registry.Diagnosticsregistry.ErrorDiagnostics()ScanOptions.FailOnErrorDiagnostics controls whether error diagnostics become a returned scan errorThis is one of the most important behavioral changes from the original prototype because it turns missing-command debugging into an explicit scanner contract.
Preferred testing structure:
examples/jsverbs/basic for fixturesScanDir(...), ScanFS(...), or ScanSource(...) depending on what source origin you want to validateregistry.Commands() for default runtime-owning command compilation, or registry.CommandsWithInvoker(...) when you need to verify host-owned execution hooksstrings.BuilderThat split in test style mirrors the split in command interfaces. If you add a new output behavior and the tests no longer read naturally, it is worth checking whether the command abstraction itself is still clean.
The examples/jsverbs/basic/fswatch.js fixture demonstrates a connected EventEmitter helper rather than a default JavaScript module. It scans like any other jsverb, but it only runs in a runtime that installs the helper explicitly.
Use Registry.InvokeInRuntime(...) when a fixture needs host-specific runtime composition:
factory, err := engine.NewRuntimeFactoryBuilder().
WithRequireOptions(require.WithLoader(registry.RequireLoader())).
Build().
WithRuntimeInitializers(
jsevents.Install(),
jsevents.FSWatchHelper(jsevents.FSWatchOptions{
Root: dir,
AllowRecursive: true,
MaxDebounce: time.Second,
}),
).
Build()
This pattern keeps the fixture useful as JavaScript documentation without making host filesystem watching a default capability of every jsverbs command.
The example runner loads the shared pkg/doc help pages into its help system.
That means:
*.md file in pkg/doc makes it reusable for other commandsjsverbs-example automatically benefits from the shared doc packageThis is a good pattern to preserve because it keeps reusable developer documentation in a package-level location instead of hiding it under one command. A new contributor should be able to discover implementation and help content close to the reusable library code, not only inside one example binary.
glaze help jsverbs-example-overviewglaze help jsverbs-example-developer-guideglaze help jsverbs-example-fixture-formatglaze help connected-eventemitters-developer-guide