| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Norn is a portable runtime for reusable agent-driven and code-driven TypeScript workflows. Author them with the SDK, then discover, run, inspect, and recover them through the CLI from any harness. Agents run on the bundled Pi coding agent; code-only workflows need no model.
Install Norn, including agent authentication.
Draft → review → save. Save this as summarize.ts in a new directory. An agent drafts a summary; a second workflow pauses for approval before code writes the reviewed text to a file.
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { workflow } from "@vimhead.dev/norn";
import { Type } from "typebox";
const draftSummary = workflow({
name: "draftSummary",
entrypoint: {
instructions: "Use when you need a reviewed summary saved to a file.",
},
args: Type.Object({ text: Type.String({ minLength: 1 }) }),
async execute({ args, paths, agents }) {
const draft = await agents.prompt({
label: "draft",
cwd: paths.workspace,
models: [{ provider: "anthropic", id: "claude-sonnet-4-5" }],
tools: [],
systemPrompt: "Summarize the supplied text concisely.",
prompt: args.text,
response: Type.Object({ summary: Type.String() }),
});
return saveSummary({ summary: draft.summary, isApproved: false });
},
});
const saveSummary = workflow({
name: "saveSummary",
entrypoint: false,
args: Type.Object({ summary: Type.String(), isApproved: Type.Boolean() }),
gate: { enabled: true, fields: ["summary", "isApproved"] },
async execute({ args, paths, run }) {
if (!args.isApproved) return run.fail({ summary: "Summary rejected." });
const summaryPath = "summary.txt";
await writeFile(join(paths.workspace, summaryPath), args.summary);
return run.complete({ summary: args.summary, data: { summaryPath } });
},
});
export default [draftSummary, saveSummary];return saveSummary(...) selects the next workflow, rather than executing it inline. Norn checkpoints the draft and pauses at the gate before writing.
Register and run it. Create norn.project.json alongside the workflow:
{
"version": 1,
"workflows": ["./summarize.ts"]
}From that directory:
printf '%s\n' '{"args":{"text":"The launch moved to Friday."}}' \
| norn runs start draftSummary
norn runs wait <run-id>
norn runs inspect <run-id>Replace <run-id> with the ID returned by start. The run should be interrupted at saveSummary; inspect the saved draft before approving it.
Edit and approve. Resume with the reviewed summary:
printf '%s\n' \
'{"args":{"summary":"Launch is now Friday.","isApproved":true}}' \
| norn runs resume <run-id>
norn runs wait <run-id>Resume uses the saved draft boundary without calling the agent again. On completion, summary.txt is in run.paths.workspace. See gates and recovery for rejecting, retrying, and restoring earlier checkpoints.
For another example combining a Git command, an agent, and a saved file, see the Git summary workflow.
See the documentation index for focused references and the SDK types for API details.
Install the runtime, authenticate for workflows that use Norn agents, and optionally connect your harness with an adapter. Direct CLI use needs no adapter.
Install the rolling npm tip release (Node >=22.19.0):
npm install -g @vimhead.dev/norn-cli@tip
norn versionAlternatively, install into the package that owns your workflows, without a global Norn installation:
npm install --save-dev --save-exact @vimhead.dev/norn-cli@tip
./node_modules/.bin/norn versionUse that local executable in place of norn in the commands below. Connect harnesses with project-local runtime selection.
Releases are prereleases, not stable latest releases. For a standalone binary without Node, use the matching GitHub tip release:
curl -fsSL https://github.com/vimhead/norn/releases/download/tip/install.sh | shSet NORN_INSTALL_DIR to select a different binary installation directory.
Runtime selection covers source checkout invocation and keeping examples/docs matched to the executable. Upgrade discovery:
norn upgrade --dry-runOpen the bundled Pi interface; no separate Pi installation is required:
norn piInside the interactive session:
Model-free workflows need no provider authentication. For other credential methods, custom providers, and Norn's configuration directory, see providers and authentication.
The shipped Pi, Cursor, and Claude Code adapters deliver Norn documentation context and available workflow introductions to your harness at session start. Installing Norn alone does not register an adapter. Codex and other harnesses can invoke the CLI directly.
To use a CLI dependency from a harness launched elsewhere in your workspace, put .nornrc.json in the harness's working directory or an ancestor:
{
"runtime": {
"packageRoot": "./packages/workflows"
}
}packageRoot is relative to this configuration file (absolute paths also work). It names a package whose package.json declares @vimhead.dev/norn-cli in dependencies, devDependencies, or optionalDependencies. Install that package's dependencies first; its manifest and lockfile own the version. npm hoisting and pnpm's linked node_modules installations are supported. No download occurs at harness startup. Node >=22.19.0 is required for the npm runtime.
The Pi, Cursor, and Claude Code adapters select an explicit executable override first, then the nearest .nornrc.json, then norn on PATH only when no configuration exists. Configuration files do not merge. Invalid configuration or a missing/broken selected installation fails without falling back. Pi ignores repository runtime configuration in untrusted projects; Cursor and Claude Code use their host's hook trust/approval boundary. Only enable adapters and runtime selection in workspaces you trust: the selected dependency executes code.
Both introductions come from the selected runtime, and its documentation introduction supplies concrete argv for subsequent agent calls. The session's working directory is preserved; runtime selection does not select a workflow project or workspace. Restart the session (or /reload in Pi) after changing selection or dependencies.
This is adapter configuration, not CLI delegation: globally installed Norn and direct CLI invocations do not read .nornrc.json or proxy commands. For terminal use, invoke the dependency directly, preserving your working directory:
./packages/workflows/node_modules/.bin/norn versionWith Pi already installed and a runtime selected as above or available on PATH, install the adapter and start a new session:
pi install npm:@vimhead.dev/pi-norn@tip
piTo select a CLI executable outside PATH:
pi --norn-executable /absolute/path/to/nornUse project-local runtime selection, or override it by starting Cursor with an executable path:
NORN_EXECUTABLE=/absolute/path/to/norn cursor .With Node and a selected runtime, run in your terminal:
claude plugin marketplace add vimhead/norn
claude plugin install norn@norn-adapters
claudeTo select a different runtime, launch Claude Code with NORN_EXECUTABLE=/absolute/path/to/norn claude. The plugin uses that runtime's documentation and the workflows in the session's working directory; it does not install Norn or configure authentication for Norn agents.
Context is added on startup, /clear, and compaction, not again on resume or fork. Named-agent sessions (--agent) and subagent hook calls are excluded. Existing instructions and prompts are preserved. Introduction failures appear as hook errors without falling back to another runtime.
To test a checkout without installing the marketplace:
claude --plugin-dir /absolute/path/to/nornNeed an adapter for another harness? Open an issue with the harness name.
Install SDK types and helpers for TypeScript/editor support:
npm install -D @vimhead.dev/norn@tipUse the SDK version reported by norn version for an exact runtime match. Runtime execution also supplies virtual SDK imports, so standalone examples need no local SDK installation.
pnpm install --frozen-lockfile
pnpm format:check
pnpm check
pnpm test
pnpm pack:dryRun pnpm format to format source, examples, and supported fenced code in Markdown. Prettier targets 80 columns and preserves Markdown prose wrapping. Generated files, build output, dependencies, and the lockfile are excluded.
pnpm install enables the Husky pre-commit hook. Commits run lint-staged to format staged files with Prettier and stage the formatting changes, preserving unstaged edits. CI checks formatting across the repository.
Use the pnpm version pinned in package.json. The private root coordinates three published workspaces: packages/sdk, packages/cli, and packages/pi-norn. packages/core is private source shared through consumer builds, not a fourth published dependency. No separate core build is needed.
Checks cover package builds, TypeScript (including examples, adapters, scripts, and tests), runtime regressions, isolated npm installations, and standalone binaries. pack:dry creates local tarballs without publishing.
| Back | FazBrowse Home | New Git URL |