Repository navigation
Releases
v8.2.0
[8.2.0] - 2026-11-05
Changed
- MCP negotiation now includes
2025-11-25, retaining2025-06-18,2024-11-05, initialization, ping, and once-per-session roots discovery with its five-second fallback. - Optional
mcpServer.validateOutputschecks typed MCP results without coercion, defaults, or key stripping. Opted-in typed results and JSON text match the advertised object-rooted schema; default string envelopes and scalar/array wrappers remain compatible. CLI and REST output validation is unchanged. - MCP handlers receive cooperative cancellation and opted-in progress through
ctx.mcp. Cancelled queued work is skipped, active abortable children can stop, and tools remain serialized. - Explicit standard tool annotations are emitted without inferred safety claims. Parse/envelope/metadata failures now return recoverable protocol errors.
- Non-serializable MCP results return tool errors without ending the session. Updated docs and npm examples for a compatible minor; the modern-only rewrite, native media, and Streamable HTTP remain deferred.
v8.1.0
[8.1.0] - 2026-11-05
Added
- MCP stdio servers automatically select workspace cwd once after client initialization when exactly one usable local root is reported. Child CLIs inherit it without consumer changes. Unsupported, ambiguous, unusable, or failed roots retain launch cwd; unanswered client requests fall back after five seconds.
- Separate MCP follow-up plan covering protocol compatibility, JSON-RPC validation, structured results, cancellation/progress, tool annotations, native content, and optional Streamable HTTP. Future features remain unimplemented.
Fixed
- MCP stdin keeps reading and routes client responses independently while application requests remain serialized. Wire writes bypass tool output capture, and pending workspace discovery settles on disconnect or write failure.
v8.0.3
[8.0.3] - 2026-11-02
Added
mcp_resource_readMCP tool: whenmcpServer.resourcesis non-empty,tools/listgains a tool that returns any resource body by URI (uriis an enum of the registered URIs), so hosts that only expose tools to the model (e.g. Copilot) can still read resources.initialize.instructionsgets a one-line pointer to it when instructions are set, and.mcpbmanifests list it. A command that already maps tomcp_resource_readkeeps the name and the built-in is skipped.
Changed
agent-plugintemplate:just releaseno longer asks for confirmation and has no--dry-run; it tests, bumps, builds, commits all changes, tags, pushes and creates the GitHub release in one go.- Templates (
api,agent-plugin) define each command's Zod schemas at the top of itscommand.tsinstead of a per-commandtypes.ts; docs and templateAGENTS.mdnow recommend a siblingschemas.tsonly when a schema is shared or large.
v8.0.2
[8.0.2] - 2026-09-30
Removed (breaking)
- The
not_readyInvokeFailureKindis gone (nothing produced it once the config readiness checks were removed), and OpenAPI no longer lists a 503 response on user routes./health/readinessstill answers 503. - App settings are no longer argsbarg's concern.
appConfig(config file, env bindings, precedence, setup wizard) and theconfigurebuilt-in (configure,get,set,install,uninstall,status) are removed, along withctx.appConfig,App.appConfig,App.exportAppConfigSchema(),appConfigonInvokeHookContext/ReadinessContext, and themissing_configfailure kind. SettingappConfigorconfigureon the app root now fails at startup with a pointer here. Migration: keep settings in app code (env vars, or your own JSON file) and add your own command if users edit them.configureis an ordinary command name again. - No MCP or skill install. argsbarg no longer writes
~/.agents/mcp.jsonor Codex / OpenCode / OpenClaw configs, and no longer detects or cleans up~/.agents/skills/<app>/. Agent plugins and.mcpbbundles (mcp bundle) are the supported MCP install path;docs mcpnow generates plugin and manual client setup (Cursor, Claude Code, Claude Desktop, Codex, OpenCode). Plugin and bundle manifests no longer carryuserConfig/variables/ env mappings derived fromappConfig. - No
docsbuilt-in or docgen. Thedocscommand and config (docs.topics,docs.enabled), the generatedcli/cli-schema/mcp/http/openapidocs and--save, the<key>://docs/<topic>and<key>://schemaMCP resources, andmcpServer.schemaResourceUriare removed; settingdocson the app root fails at startup. OpenAPI is still served atGET /openapi.jsonand/swagger, andgenerateOpenApi/schemaJsonremain library helpers.docsis an ordinary command name again. Removed exports:DocsConfig,DocsTopic,defaultDocsTopicResourceUri,resolveDocsTopicResourceUri. - No generated agent skill.
mcp bundleplugins ship the repository skill (skills/<key>/ormcpServer.bundle.skillsDir) when present and no skill otherwise; the generated MCP pointer-skill fallback is gone. - No managed
AGENTS.md.scripts/merge-agents-md.tsand the<!-- argsbarg:managed -->markers are removed; templateAGENTS.mdfiles are plain starting points that projects own. Theconsumers-*justfile recipes are removed. - No self-update or binary placement (
configure install --update, Homebrew/~/.local/bindetection). Update through the package manager (brew upgrade, npm). GET /health/readinessreports only thecustomcheck (config_fileandconfig_requiredare gone).- A relative
log.fileresolves against the working directory instead of the app config directory. - YAML input is gone. Document-mode arguments, document stdin, and HTTP request bodies accept JSON only (
invalid JSON/Invalid JSON bodyotherwise). The YAML-style schema sections in help are unchanged. OptionKind,ValueFormat,FallbackMode, andParseKindareas constobjects plus same-named union types, not TypeScript enums (so argsbarg runs under Node type stripping).OptionKind.Stringetc. still work and the values are unchanged; code that used them as types (kind: OptionKind.Presencein a type position) needstypeof OptionKind.Presence.- The package no longer ships
src/or thebunexport condition. Every runtime, Bun included, loads the compileddist/. Types aretsc-emitteddist/**/*.d.ts(with declaration maps) instead of a bundled rootindex.d.ts; dts-bundle-generator is gone, and argsbarg and all four templates use TypeScript 7. argsbarg create:--class-name,--tap, and--homepageare removed. The identity file moved tosrc/create-identity.tsand holdskey,releaseRepo,desc, andtemplate; the Homebrew template derives the formula class and homepage itself.- Removed exports:
userHome,displayAppConfigPath,resolveAppConfigPath,AnyAppConfigSnapshot,ResolvedConfig,AppConfig,AppConfigEntry,AppConfigResolveContext,AppConfigResolveFn,ConfigureConfig,ConfigureHookContext,ConfigureTargets,InstallTargetSpec,ResolvedInstallTarget.
Added
- npm templates.
cli(the default),api, andagent-pluginare npm projects:npx <key>/npm install -g, justfile tasks,tscbuild,node --test, a gatedjust release→npm publish, and docs read from the package at runtime.apiusesnode:sqlite.createrunsnpm install/npm testfor them.agent-pluginbundles with esbuild and gains a CHANGELOG and a release confirmation prompt. homebrewtemplate: a minimal Bun-compiled binary with a Homebrew formula, tap, and gated GitHub release. It is the only template that uses Bun.- Runs on Node ≥ 20 as well as Bun. The package ships compiled JS in
dist/, which every runtime loads, and theargsbargbin is a Node script (dist/cli-tool/main.js). The HTTP server usesnode:http; stdin and subprocesses usenode:APIs. See "Runtime" indocs/decisions.md.
Fixed
- HTTP and MCP servers now honor
log.enrichandlog.serialize(the serve config dropped them, so only directLogEmitteruse applied them), and alog.filestarting with~/expands to the home directory instead of creating a literal~directory. cli.completions(enabled: false/hidden: true) now removes a command from bash, zsh, and fish completions; it was declared but never read.- With
httpServer,mcpServer, orcompletionoff, a root command of that name is an ordinary app command, as documented: it runs (with hooks) instead of failing with "not available for this app". Apps without such a command still get that message. app.run()now runs apphooksfor user commands on the CLI (beforeInvoke,afterInvoke, andformatError/onErroron failure), matchingapp.invoke()on HTTP/MCP. Previouslyrun()skipped them, sobeforeInvoke-attached state (e.g. the template DB) was missing on the CLI.
Changed
- Internal source reorganized after the removals:
help.tsand invoke hooks live undersrc/runtime/, completion scripts undersrc/builtins/completion/, and MCP plugin/bundle packing undersrc/mcp/pack/. The hook skip-list no longer treatsconfigure/docsas built-ins, so hooks now run for app commands with those names. Theargsbargbin (src/cli-tool/) uses only the public API; the template capability test moved tosrc/runtime/. Unused internals were deleted (runCreateCommand,parseCreateArgv,templateDir,ecsLevel,CliPresentationNode). Public exports are unchanged. - Help is plain text on every output: no box borders and no color; sections start with a
── Title ───rule sized to the terminal (80 columns when piped). TTY and piped help are identical except that schema sections show by default only when piped. completion <shell> --helpgives generic setup instructions (current session and shell rc) instead of Homebrew-specific notes.- Error messages on stderr are no longer colored red.
- The top-level
examples/*.tsscripts are now type-checked with argsbarg (Node types only, so Bun APIs fail) (examples/nested.tsusedBun.file; it now usesnode:fs/promises).
v8.0.1
v8.0.0
[8.0.0] - 2026-09-30
Changed (breaking)
-
New naming: an app is built with
argsbarg({ … })from a spec ofcommands, and theCliprefix is gone.argsbarg({ … })validates the spec and returns the app (export const app = argsbarg({ … })insrc/app.ts, thenawait app.run());Appis exported as a type only. Commands either run (handler) or group subcommands (commands), and both are declared withcommand({ … }). The definition is the spec:app.spec,ctx.spec, andspecon hook/runtime contexts; spec helpers (generateOpenApi,schemaStrictnessWarnings,mcpSizeReport,packMcpBundle, …) takeapp.spec. Public types dropClibecause argsbarg serves HTTP and MCP too; it stays only where it means the CLI surface (CliExposureConfig,cliErrWithHelp, the"cli"invocation). Key renames:7.x 8.0 const program = { … } satisfies CliProgram; new Cli(program).run()export const app = argsbarg({ … }); await app.run()src/program.tssrc/app.tscli.program/ctx.program/ hookctx.programapp.spec/ctx.spec/ hookctx.specCliProgram/CliProgramHooksAppSpec/AppHooks{ … } satisfies CliLeaf/CliRoutercommand({ … })CliNode/CliLeaf/CliRouterCommand/RunnableCommand/CommandGroupCliOption/CliPositional/CliContextCommandOption/CommandPositional/CommandContextCliOptionKind/CliValueFormat/CliFallbackModeOptionKind/ValueFormat/FallbackModeCliSchemaValidationError/LeafInputError/CliJsonSchema/CliLeafInputsSchemaValidationError/InputError/JsonSchema/CommandInputsCliAppConfig/CliLocals/CliInvocationAppConfig/Locals/InvocationCliMcpServerConfig/CliHttpServerConfig/CliDocsConfig…McpServerConfig/HttpServerConfig/DocsConfig…CliCliExposureConfigCliExposureConfigisDocumentLeaf/buildLeafInputSchema/leafWireOptionsisDocumentCommand/buildCommandInputSchema/commandWireOptionscliSchemaExport/cliSchemaJsonschemaExport/schemaJsonValidation now happens when
argsbarg()runs (at import ofsrc/app.ts). The docs name the app's own config schemaSettingsso it doesn't clash with argsbarg'sAppConfigtype.declare module "argsbarg"augmentations useLocals/ServerState. User-facing messages say "command" / "command group" / "app root" instead of leaf / router / program root. -
Schemas are authored in Zod 4 (
zodis now a peer dependency).inputSchema,outputSchema,httpServer.errors.errorSchema, andmcpServer.errors.errorSchematake Zod schemas; argsbarg validates with Zod and emits JSON Schema (draft 2020-12) for MCPtools/list, OpenAPI, non-TTY help, anddocs cli-schema. Passing a JSON Schema object fails at startup with a migration error. -
program.appConfig.jsonSchemais replaced byprogram.appConfig.schema, which takes a Zod object schema (z.strictObjectrecommended). Without it, argsbarg still synthesizes an all-string schema fromentries. -
ctx.inputsfor a leaf withinputSchemais now the schema's parsed output: defaults and transforms are applied, and strict schemas reject unknown keys as before. -
Schema validation errors are Zod's messages prefixed by path, polished for agents: missing fields read
name: required, unknown keys list what is allowed ($: Unrecognized key: "titel" (allowed: action, doc, title)), and union/enum mismatches echo the rejected value (steps.0.kind: Invalid discriminator value. Expected 'alpha' | 'beta' (got "alfa")). This replaces argsbarg's union-narrowing rewrites. -
Partial config validation (
configure set, bootstrap) makes top-level keys optional via.partial(); nestedrequiredfields are no longer relaxed.
Removed (breaking)
argsbarg schemagen, the/** @sg */markers, and__generated__/artifacts: define schemas in Zod instead. Thets-json-schema-generatorand@cfworker/json-schemadependencies are gone (argsbarg has no runtime dependencies;zodis the only peer).- Subpath exports
argsbarg/cli,argsbarg/headless,argsbarg/http,argsbarg/mcp, andargsbarg/schemagen: import from"argsbarg"(everything they exported is on the root). - JSON Schema draft selection via
$schema(argsbarg emits draft 2020-12) and thecomma-listJSON Schema format registration. - The
consumers-schemagenrecipe;sqsp-i18n-tools-pocis no longer a tracked consumer.consumers-devnow forces the install, addszod, and removes the nested dev copy of zod; the newexamples-installrecipe reinstalls the in-repo examples. ctx.inputsAs<T>(): usectx.inputswithcommand.- The
CliHandlertype export (unused since handlers are typed throughcommand/program). kind: "json"leaves,isJsonLeaf, andJSON_LEAF_BODY_KEY: usekind: "document",isDocumentCommand, andDOCUMENT_LEAF_BODY_KEY.kind: "json"now fails at startup with a migration error.CliSkillConfig/program.skill(it had no effect since skill generation was removed).- The dedicated startup errors for long-removed
configuresettings (prefix,agentIntegration, and per-host skill/MCP targets). Unknown target keys still fail withconfigure.targets.<key> is not a valid target key.
Migration (7 → 8)
- Add
zod@^4to your dependencies. - Convert each
/** @sg */type toexport const X = z.strictObject({…})plusexport type X = z.infer<typeof X>, copying every JSDoc into.describe("…"). Agents read these descriptions, and Zod does not read JSDoc. - Pass the Zod schemas to
inputSchema/outputSchema/errorSchema, renameappConfig.jsonSchema→appConfig.schema, build the app withexport const app = argsbarg({…})insrc/app.ts(await app.run()inindex.ts), wrap every command incommand({…}), usectx.spec/app.specwhere you usedctx.program/cli.program, replacectx.inputsAs<T>()withctx.inputs(path params:ctx.pathParams), changekind: "json"tokind: "document", and dropskill: { … }. - Replace subpath imports with
"argsbarg", delete__generated__/, and remove theschemagenrecipes and gitignore rules. - Diff
docs cli-schemaoutput before and after to confirm every description survived. Seedocs/developing.md→ "Upgrading consumer apps to 8.0".
Added
command()infersctx.inputsfrominputSchemaand types the handler return fromoutputSchema. It is now the way to declare leaves;{ … } satisfies RunnableCommandis no longer documented or used in the templates (it still compiles, but its handler gets untypedctx.inputs).program()declares the program root: router roots keep their literal type, and a leaf root (one-command CLI) gets the samectx.inputsinference ascommand. It replacessatisfies Programin the docs and templates.command()also typesctx.inputsfor leaves without aninputSchema, from their ownoptions/positionalsliterals: presence flags areboolean, numbersnumber, enums theirchoicesunion, durationsnumber(ms), comma-listsstring[], and required or defaulted options are non-optional. Types only; runtime parsing is unchanged.CommandBase.options,positionals, andCommandOption.choicesaccept readonly arrays.- Leaves can declare
pathParams: z.strictObject({ id: z.string().describe(…) })for the:paramsegments above them: values are validated before the handler, typed asctx.pathParamswithcommand, and described in MCP tool schemas and OpenAPI path parameters. Startup checks that the keys match the route and are not also declared byinputSchema. The raw segments stay available asctx.rawPathParams. - Startup validation emits every schema eagerly, so schemas JSON Schema cannot represent (transforms,
z.date(), …) fail at startup with the leaf named. schemaStrictnessWarnings(program)(exported) lists input and config objects that accept unknown keys (z.objectinstead ofz.strictObject). The schema templates assert it is empty insrc/program.test.ts, and MCP and HTTP servers log each warning at startup (schema.strictness).- JSON Schema authoring guide rewritten for Zod (
docs/json-schema-subset.md), and ADR 4 (Zod as the schema layer) supersedes ADR 2. - The root export now includes every public type that was previously only reachable through the bundled
index.d.ts(RunnableCommand,CommandGroup,Command,JsonSchema, …), plus the HTTP server and Claude/Cursor plugin helpers.
Fixed
PUT/PATCHon:paramroutes (e.g./workspaces/:id) no longer fail withunknown property "id"when the leaf'sinputSchemais strict: path parameters the schema does not declare are left out of validation and merged intoctx.inputs(also available asctx.pathParams).- MCP tools under
:paramrouters (e.g.workspaces :id get) now list each path parameter as a required argument and route calls to the given value. Previously their input schemas omitted the parameter and calls routed the literal:idsegment, so agents could not address these routes. - Document leaves under
:paramroutes accept HTTP and MCP calls whose body carries the path parameters (they are validated as path parameters, not body fields). - OpenAPI request and response schemas no longer embed a root
$schema. - Copy templates are renamed and keyed by their directory:
examples/cli(default; wasfull-example),examples/api(wasfull-example-json), andexamples/agent-plugin(wasmcp-plugin).argsbarg create --template cli|api|agent-plugin(wascli/json/plugin);create-identity.tsstores the same key. The example apps inside areexample-cli,example-api, andexample-agent-plugin. The interactive picker now lists every template (it only offered two), and `create --chec...
v7.1.4
[7.1.4] - 2026-09-30
Changed
- The MCP plugin example now ships a committed, self-contained Node bundle (
dist/mcp-plugin.mjs) that both plugin manifests run withnode, replacing source-onlybun start. Plugin users need Node >=20 instead of Bun, and startup installs nothing.just checkrebuilds the bundle, the release script rebuilds it after the version bump, and the optionaldocs/node-distro.mdguide is removed.
v7.1.3
[7.1.3] - 2026-09-29
Added
- MCP tools whose
inputSchemaoroutputSchemaroot is nottype: "object"(e.g. a discriminated-unionanyOffromexport type Input = A | B) are now wrapped for MCP as{ input: <schema> }/{ result: <schema> }, withdefinitionsmoved to the new root. MCP requires an object root, and the TypeScript SDK rejects anything else; previously these tools shipped schemas clients refused or showed no fields for.tools/callunwrapsinputbefore invoke (handlers andinputSchemavalidation still see the exact union) and wrapsstructuredContentunderresultto match. CLI and HTTP are unchanged. Seedocs/mcp.md. - Startup validation (MCP enabled only): every exposed MCP tool's served schemas must have resolvable local
$refs, and wrapped schemas must not use$ref: "#". full-example-jsongains ashape-areaunion-input leaf demonstrating the MCP wrap.argsbarg createdrops template lines marked# argsbarg-dev-onlyfrom new projects. The in-repo examples use it for thejust setupstep that repairsnode_modules/.bin/argsbargforfile:../..installs (now in all three templates); scaffolded projects never see it.
Changed
- Docs now use
bun xinstead ofbunx, andcreateexamples usebun x argsbarg@latest createso scaffolding never runs a stale cached argsbarg (old templates, old^version inpackage.json).create --checkexamples keepbun x argsbargso they check against the project's installed version. - The MCP plugin example now defaults to source-only Bun startup with inline Claude and Cursor MCP configuration, updated plugin recipes, unit/integration/agent-E2E guidance, and an optional Node distribution guide.
Fixed
- schemagen now hoists a root
$ref(fromexport type Input = Inner, generic aliases likeBox<string>, or alias chains) to the object definition it names. Previously these roots had notype: "object"orproperties, so MCP rejected the tool schema,--helpshowed no input rows, and Json-option/propertieschecks were skipped. - schemagen no longer adds
additionalProperties: falseto non-object roots. On a union root it rejected every property, so union-typed inputs never validated. - JSON Pointer
$refresolution (discriminated-union error reporting, OpenAPI dereferencing) now decodes percent-escaped segments such as#/definitions/Box%3Cstring%3E. - The
full-exampleandfull-example-jsonjustfiles derivetap_parent/tap_pathfrom a literaltap := "org/repo"instead of raw{tapOrg}/{tapRepo}placeholders, which onlycreatefilled in. Run in-repo, the Homebrew recipes targetedTaps/{tapOrg}/homebrew-{tapRepo}, andcreate --checkreported drift. A new test runscreate --checkon every in-repo template as part ofjust test. - The MCP plugin example's release
--dry-runnow prints the planned actions without running checks, changing files, or publishing.
v7.1.2
[7.1.2] - 2026-09-25
Added
mcpServer.instructions— an optional string returned asinitialize.result.instructions. Claude Code adds it to the system prompt of every session; Cursor writes it tomcps/<server>/INSTRUCTIONS.md.- MCP protocol version negotiation:
initializenow echoes a client's2025-06-18or2024-11-05protocolVersion, and answers2025-06-18(the newest) when the request omits it or asks for an unsupported version. Previously the server always claimed2024-11-05regardless of what the client sent or what fields it actually returned.tools/list'soutputSchemaandtools/call'sstructuredContent— both defined starting in2025-06-18— are now only sent for sessions that negotiated that version or later; a2024-11-05session no longer receives fields from a spec revision it never agreed to. mcpSizeReport(root)andmcpServer.sizeLimits— measures every MCP tool'sdescriptionlength and pretty-printed definition (bytes and lines) against configurable limits approximating two real client behaviors (Claude Code truncates long tool descriptions; Cursor reads each tool's synced definition file in bounded chunks), and returns warnings for anything over.serveMcpruns this at startup and writes warnings to stderr before the "MCP ready" line;docs mcpnow includes a## Tool sizestable. Set any limit tofalseto disable that check.mcpTool.notes(string | false) — overrides a leaf'snotesin the MCP tool description only; CLI--helpcontinues to show the leaf's ownnotesunchanged. Useful for a note that only makes sense with--helpin front of it, or to keep a tool's definition under a size limit.
Changed
- Discriminated
anyOf/oneOfunions (every branch has apropertieskey with a stringconstor all-stringenum, and the value sets are disjoint) now report only the branch matching the instance's discriminator value, instead of every branch's unrelated errors at once. A missing, non-string, or unmapped discriminator value collapses to one synthetic message naming the valid choices. Non-discriminated unions are unaffected. Along the way, two cfworker@cfworker/json-schemaquirks are also cleaned up for every validated schema (not just discriminated unions): a spuriousadditionalProperties+"False boolean schema."pair it emits even for a property that's genuinely declared inproperties, and dropping now-redundant wrapper errors ($ref,properties,items,anyOf,oneOf, …) once a more specific error survives underneath them. Discriminator detection also resolves each branch through$refbefore inspecting itsproperties— schema generators such asts-json-schema-generatorwrite everyanyOfbranch as a bare{ $ref }intodefinitionsrather than inlining it, which previously made every branch look property-less and silently fell back to the noisy full-error listing.
v7.1.1
[7.1.1] - 2026-09-25
Added
argsbarg create --template plugin— support"plugin"choice for scaffolding agent MCP plugins with in-repo Cursor and Claude manifests.
Changed
- AGENTS.md — updated Memory section to use
thread-memoryMCP plugin (recall/feedback) backed by centralized SQLite store.
Fixed
- Headless tool failures (MCP
tools/calland HTTP JSON{ "error" }) now return the full error message (ANSI stripped, newlines preserved) instead of collapsing to the first line. packClaudePlugin,packCursorPlugin, andpackMcpBundlestaged the compiled binary viacpSync(src, dest, { mode: 0o755 })— butcpSync'smodeoption is a bitmask of copy-behavior flags (COPYFILE_EXCL/FICLONE/FICLONE_FORCE, valid range 0–7), not a POSIX file permission mode.0o755(493) was always out of range; a stricter Bunfs.cpSyncvalidation now throws on it instead of silently ignoring it. Fixed by dropping the bogusmodeoption and callingchmodSync(dest, 0o755)after the copy, which is what the code actually intended.