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

@camunda/linting-autofix

v0.1.0

Published

Autofix and autofill affordances for Camunda linting, shared by Camunda Desktop and Web Modeler

Readme

@camunda/linting-autofix

Autofix and autofill affordances for linting, shared by Camunda Desktop and Web Modeler.

The module decorates the properties panel of elements inside an agentic ad-hoc sub-process with one-click affordances that wire up both sides of an AI Agent tool contract: the fromAi() inputs the agent supplies, and the toolCallResult output it reads back. One rule governs every affordance: seed a blank field, never overwrite a value.

Both modelers register the same module, so the two stay in lockstep by construction rather than by builders remembering to change both.

Usage

Register the module:

import { agentConfigAutofillModule } from '@camunda/linting-autofix';

import '@camunda/linting-autofix/assets/linting-autofix.css';

const modeler = new BpmnModeler({
  additionalModules: [
    agentConfigAutofillModule
  ]
});

The module is editor-only (it mutates the model) and needs the properties panel to be registered too. Host integration is a single line.

Peer dependencies

bpmn-js, diagram-js, bpmn-js-properties-panel and @bpmn-io/properties-panel are peer dependencies, so the module always renders through the host's own instances. In particular, its entries are authored with htm bound to @bpmn-io/properties-panel's vendored preact copy — the panel renders its tree through that copy, and hooks from a second preact instance track a different currentComponent than the panel sets during render.

Affordances

  1. Input autofill (fromAi()), on the tool flow's entry element only — blank io-mapping inputs and blank FEEL-capable element-template fields bound to zeebe:input get an Input from agent pill, in its own entry directly below the field, seeding =fromAi(toolCall.<key>, "<description>", "<type>"). No offer when the derived key collides with a fromAi() key already declared on the element.

  2. Result autofill (toolCallResult), an Output to agent pill on any tool-flow element that does not already produce a contract-readable result upstream on its own execution path, writing into the element's native result field — a templated connector's result expression, a FEEL script task's result variable, or a new output parameter on a plain task.

    Withdrawn where clicking could not help: on an output row already targeting toolCallResult with no source to fill in, the click would write the value already there; on a row targeting a sub-path such as toolCallResult.statusCode, it would collapse a deliberate partial contribution back to the root.

  3. Autofix actions, offered on populated fields: malformed fromAi() keys (wrong prefix, bracket notation, quoted, over-long path, wrong casing, missing entirely) and near-miss result-channel names are detected by re-parsing the element's own fields. A well-formed fromAi() call sitting on a non-entry element is offered as Move to "<entry element>", which declares it on the actual entry element and rewrites only the fromAi(...) span, leaving the rest of that field's expression intact.

    A correction that resolves a validation message is painted onto that message rather than taking a row of its own, and carries one of two labels:

    | What the field holds | What accepting gives you | Label | | --- | --- | --- | | A description or type you wrote | Your text kept exactly; only the key is corrected, and anything you left out is filled in | Fix | | Nothing but a broken key (fromAi(), fromAi(42)) | A complete call: key, description, type | Autofill | | A call that will not parse at all | A reset to a working default; what you wrote is replaced, and the message says so | Autofill |

    Three rules govern this, stated canonically in agent-tool-corrections.ts: keep every decision you made that is still readable; reset only when nothing can be salvaged; and say which of the two just happened, because the button previews nothing. A type is written from a template's declared property but never from a keyword guess into a call you already had.

Fixes are span-scoped, never whole-field replacement, so an expression like =concat("prefix-", fromAi(), "-suffix") is never discarded. Every applied fix, including a multi-element move, is a single undo unit.

The seeded fromAi() type is a guess, not a fact

Every seeded call carries a type argument computed by inferFromAiType in from-ai-autofill.ts. Only propertyType === 'Boolean' on an element-template field is a confident fact; everything else is a keyword heuristic over the field's own description/label text, defaulting to 'string'.

If you hit a runtime type mismatch on a tool call, check this before assuming the connector or the model is at fault: the third argument of a seeded call is exactly what inferFromAiType returned, never hand-authored. The fix is a one-word edit to the seeded "<type>" argument in the field itself, not a change to that function.

Eligibility

An ad-hoc sub-process counts as agentic once it carries the io.camunda.agenticai.toolContainer zeebe:Properties boolean, or the io.camunda.connectors.agenticai.aiagent.jobworker.v1 element template id — matching isAgenticAdHocSubProcess in bpmnlint-plugin-camunda-compat. A bare zeebe:AdHoc extension is deliberately not treated as a fallback: plain ad-hoc sub-processes using output collection carry it too.

The shared predicates (isAgenticAdHocSubProcess, isToolFlowElement, isToolEntryElement) are exported so every host surface agrees on where the affordances belong.

Development

npm install
npm start     # playground for testing library code in isolation
npm run all   # lint + build + test, the same as CI

Local development against a host modeler

Build the library and link it into the host:

npm run build && npm link
cd ../camunda-modeler/client && npm link @camunda/linting-autofix

Re-run npm run build after each change; the host picks up dist/ directly.

License

MIT