{"_id":"@alainux/wirestate","_rev":"2-fbb2437e986414bf71bde384fa1a1dff","name":"@alainux/wirestate","dist-tags":{"latest":"0.3.1"},"versions":{"0.3.0":{"name":"@alainux/wirestate","version":"0.3.0","keywords":["state-machine","fsm","statechart","wireframe","prototype","specification","testing","playwright","verification","visualization","ai","agent","cli"],"author":{"name":"alainux"},"license":"MIT","_id":"@alainux/wirestate@0.3.0","maintainers":[{"name":"alainux","email":"alain.jacomet.forte@gmail.com"}],"homepage":"https://alainux.github.io/wirestate","bugs":{"url":"https://github.com/alainux/wirestate/issues"},"bin":{"wirestate":"dist/cli.js"},"dist":{"shasum":"63adae12891e3c189bc6806debdb94c4cb6fe1fe","tarball":"https://registry.npmjs.org/@alainux/wirestate/-/wirestate-0.3.0.tgz","fileCount":91,"integrity":"sha512-+8wFaCLSEc58myijZkOQ6sY0pDJGDpQ8EbDxaAkxDBukz6Cf3CIGueVdUkwPdQDxprkLSq6tyu0avwLw522HpQ==","signatures":[{"sig":"MEQCIC5kzwcywojxnoYfxLvRVVNx1D0T2KhqGzTe/DEddNM8AiAJ8WQXbHxyCUqhL3zGs/7iISWmDu3S7HI6dXGHxRfW2A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":579449},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./playwright":{"types":"./dist/playwright.d.ts","import":"./dist/playwright.js"}},"gitHead":"4d08746d69ebacef5ee66e546b0a66749f489642","scripts":{"dev":"tsx src/cli.ts","lint":"tsc -p tsconfig.json --noEmit","test":"npm run build && npm run example:build && node --test tests/*.test.mjs","build":"rm -rf dist && tsc -p tsconfig.json && cp -R public dist/public && cp -R schema dist/schema","check":"npm run lint && npm run example:build && npm run test:coverage && npm run build","example:app":"npm run example:build && node examples/habit-tracker/scripts/serve.mjs","example:sync":"npm run example:build && node examples/habit-tracker/dist/sync-cli/index.js","example:build":"tsc -p examples/habit-tracker/tsconfig.json","example:check":"npm run build && node dist/cli.js check --cwd examples/habit-tracker","example:serve":"npm run build && node dist/cli.js serve --cwd examples/habit-tracker","example:smoke":"npm run build && node dist/cli.js smoke generate --cwd examples/habit-tracker --machine habits.app --out examples/habit-tracker/tests/generated.smoke.spec.ts","test:coverage":"npm run build && npm run example:build && node --experimental-test-coverage --test --test-coverage-include=dist/*.js --test-coverage-exclude=dist/cli.js --test-coverage-lines=90 --test-coverage-functions=90 --test-coverage-branches=75 tests/*.test.mjs"},"_npmUser":{"name":"alainux","email":"alain.jacomet.forte@gmail.com"},"repository":{"url":"git+https://github.com/alainux/wirestate.git","type":"git"},"_npmVersion":"10.9.2","description":"Visual executable specifications using hierarchical state machines, interactive wireframes, and runtime verification.","directories":{},"_nodeVersion":"23.11.0","dependencies":{"yaml":"^2.9.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.3","typescript":"^5.8.3","@types/node":"^22.15.30"},"_npmOperationalInternal":{"tmp":"tmp/wirestate_0.3.0_1785669437439_0.9214794634836512","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@alainux/wirestate","version":"0.3.1","description":"Visual executable specifications using hierarchical state machines, interactive wireframes, and runtime verification.","type":"module","bin":{"wirestate":"dist/cli.js"},"author":{"name":"alainux"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./playwright":{"types":"./dist/playwright.d.ts","import":"./dist/playwright.js"}},"scripts":{"build":"rm -rf dist && tsc -p tsconfig.json && cp -R public dist/public && cp -R schema dist/schema","dev":"tsx src/cli.ts","test":"npm run build && npm run example:build && node --test tests/*.test.mjs","test:coverage":"npm run build && npm run example:build && node --experimental-test-coverage --test --test-coverage-include=dist/*.js --test-coverage-exclude=dist/cli.js --test-coverage-lines=90 --test-coverage-functions=90 --test-coverage-branches=75 tests/*.test.mjs","lint":"tsc -p tsconfig.json --noEmit","check":"npm run lint && npm run example:build && npm run test:coverage && npm run build","example:serve":"npm run build && node dist/cli.js serve --cwd examples/habit-tracker","example:check":"npm run build && node dist/cli.js check --cwd examples/habit-tracker","example:smoke":"npm run build && node dist/cli.js smoke generate --cwd examples/habit-tracker --machine habits.app --out examples/habit-tracker/tests/generated.smoke.spec.ts","example:build":"tsc -p examples/habit-tracker/tsconfig.json","example:app":"npm run example:build && node examples/habit-tracker/scripts/serve.mjs","example:sync":"npm run example:build && node examples/habit-tracker/dist/sync-cli/index.js","prepack":"npm run build"},"engines":{"node":">=20"},"dependencies":{"yaml":"^2.9.0"},"devDependencies":{"@types/node":"^22.15.30","tsx":"^4.20.3","typescript":"^5.8.3"},"license":"MIT","homepage":"https://alainux.github.io/wirestate","repository":{"type":"git","url":"git+https://github.com/alainux/wirestate.git"},"bugs":{"url":"https://github.com/alainux/wirestate/issues"},"keywords":["state-machine","fsm","statechart","wireframe","prototype","specification","testing","playwright","verification","visualization","ai","agent","cli"],"_id":"@alainux/wirestate@0.3.1","gitHead":"684f005812f0fe062b5bc80591bb66098b8524b7","_nodeVersion":"23.11.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-BWyPjZjh6l7gVNSjwxWzu3gc+tNm92VdWGbQZmkgdccuJ4lw/hqo8M0yB0AW5rq4l/W6WfZj2D4ggSZX0YEFow==","shasum":"218f796d14599f653930cd885d8e49f731c11716","tarball":"https://registry.npmjs.org/@alainux/wirestate/-/wirestate-0.3.1.tgz","fileCount":91,"unpackedSize":579482,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFV0XPk7TSR4QuAiyW4/5uVHFIRPKLH97Caubqpu+0jSAiEAzkaZHeTJnxH18Ede/k/nD2tXDIdR1dzu3tUiZNZr27s="}]},"_npmUser":{"name":"alainux","email":"alain.jacomet.forte@gmail.com"},"directories":{},"maintainers":[{"name":"alainux","email":"alain.jacomet.forte@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wirestate_0.3.1_1785669850886_0.6215467080930854"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-02T11:17:17.271Z","modified":"2026-08-02T11:24:11.217Z","0.3.0":"2026-08-02T11:17:17.609Z","0.3.1":"2026-08-02T11:24:11.070Z"},"bugs":{"url":"https://github.com/alainux/wirestate/issues"},"author":{"name":"alainux"},"license":"MIT","homepage":"https://alainux.github.io/wirestate","keywords":["state-machine","fsm","statechart","wireframe","prototype","specification","testing","playwright","verification","visualization","ai","agent","cli"],"repository":{"type":"git","url":"git+https://github.com/alainux/wirestate.git"},"description":"Visual executable specifications using hierarchical state machines, interactive wireframes, and runtime verification.","maintainers":[{"name":"alainux","email":"alain.jacomet.forte@gmail.com"}],"readme":"<div align=\"center\">\n\n# Wirestate\n\n**Visual executable specifications for software.**\n\nDefine applications as composable state machines and lightweight interactive wireframes. Verify runtime behavior in CI, detect specification drift, and give coding agents a deterministic source of truth.\n\n[![npm version](https://img.shields.io/npm/v/wirestate?logo=npm&label=npm)](https://www.npmjs.com/package/wirestate)\n[![coverage](https://img.shields.io/badge/coverage-93%25-brightgreen)](#verification)\n[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n[![docs](https://img.shields.io/badge/docs-online-6f42c1)](https://alainux.github.io/wirestate/docs/)\n\n[**Website**][website] · [**Documentation**][documentation] · [npm](https://www.npmjs.com/package/wirestate) · [Example](./examples/habit-tracker)\n\n</div>\n\n[![Wirestate Studio](./site/assets/studio.png)][website]\n\n> **Treat specifications as code.**\n>\n> Wirestate keeps application behavior, interactive prototypes, tests, and implementations aligned through executable specifications. The same checked-in specification powers visualization, simulation, runtime verification, CI policy, and AI-assisted development.\n\n## Why Wirestate?\n\nRequirements, mockups, tests, and implementation code usually drift because they are separate artifacts with weak links between them. Wirestate connects them through a small, repository-native specification:\n\n```text\nSpecification → Interactive prototype → Application traces → Verification\n      │                    │                       │\n      └──────────── structured context for coding agents ────────────┘\n```\n\nWirestate helps teams:\n\n- Model application behavior with hierarchical, composable finite state machines.\n- Build clickable low-fidelity prototypes from a minimal screen DSL.\n- Keep specifications readable, diff-friendly, and colocated with implementation modules.\n- Check source bindings in both directions so missing and unknown references fail visibly.\n- Compare observed runtime traces with expected states and transitions.\n- Report modeled behavior that tests have not demonstrated.\n- Give AI coding agents structured intent instead of relying only on prose and screenshots.\n\nWirestate is not intended to replace application tests, a production state-management library, or a pixel-perfect design tool. It adds a behavioral contract above those tools.\n\n## Features\n\n- Hierarchical and composable state machines authored in YAML.\n- Optional Balsamiq-style screens made from eight primitives: `Container`, `Text`, `Button`, `TextInput`, `Image`, `List`, `Toggle`, and `Modal`.\n- A local IDE-style studio with a zoomable state graph and clickable wireframe shown side by side.\n- Explicit state inspection and runtime jumping without conflating the two.\n- Editable specification comments stored on the filesystem.\n- A CLI for validation, inspection, simulation, interactions, synchronization, coverage, comments, serving, and smoke-test generation.\n- Passive conformance through a language-neutral JSON/NDJSON trace protocol.\n- Source linking through `data-wirestate-id`, `data-wirestate-state`, `@wirestate(...)`, and `wirestate:` comments.\n- Project and global configuration files.\n- JSON Schema support for editor integration.\n- A colocated TypeScript habit-tracker example with browser and CLI entry points.\n- Playwright helpers and generated smoke-test scaffolds.\n\n## Quick start\n\nInstall the CLI globally:\n\n```bash\nnpm install --global wirestate\n```\n\nInitialize and serve a project:\n\n```bash\nwirestate init\nwirestate check\nwirestate serve --open\n```\n\nOr work from this repository:\n\n```bash\nnpm install\nnpm run build\nnode dist/cli.js check --cwd examples/habit-tracker\nnode dist/cli.js serve --cwd examples/habit-tracker --open\n```\n\nDuring development:\n\n```bash\nnpm run check\nnpm run example:build\nnpm run example:check\nnpm run example:serve\n```\n\nRun the actual example application or its related export CLI in another terminal:\n\n```bash\nnpm run example:app\nnpm run example:sync\n```\n\nThe studio defaults to `http://127.0.0.1:4177`.\n\n## A small specification\n\n```yaml\nwirestate: 1\nnamespace: checkout\n\nmachines:\n  app:\n    initial: cart\n    states:\n      cart:\n        screen: cart\n        bind: state:checkout.app.cart\n        on:\n          CHECK_OUT:\n            target: payment\n            interaction:\n              kind: click\n              component: checkout.submit\n\n      payment:\n        screen: payment\n        bind: state:checkout.app.payment\n\nscreens:\n  cart:\n    root:\n      type: Container\n      children:\n        - type: Text\n          props:\n            text: Your cart\n\n        - id: checkout.submit\n          type: Button\n          bind: component:checkout.submit\n          props:\n            label: Check out\n```\n\nApplication source can link to the specification without requiring a frontend framework:\n\n```html\n<main data-wirestate-state=\"checkout.app.cart\">\n  <button data-wirestate-id=\"checkout.submit\">Check out</button>\n</main>\n```\n\nBackend services and CLI applications can use decorators or comments through adapters:\n\n```python\n@wirestate(\"state:jobs.worker.running\")\ndef run_job():\n    ...\n```\n\n## Interactive prototype behavior\n\nTransition interaction metadata connects a wireframe component to machine behavior:\n\n```yaml\non:\n  OPEN_ADD:\n    target: adding\n    interaction:\n      kind: click\n      component: habit.addButton\n```\n\nClicking `habit.addButton` in the studio sends the interaction through the core resolver using the current machine state, component ID, and interaction kind. The browser does not implement a separate copy of the transition logic.\n\nThe same operation is available through the CLI:\n\n```bash\nwirestate interact \\\n  --machine habits.app \\\n  --state ready.dashboard \\\n  --component habit.addButton \\\n  --kind click\n```\n\nButtons, toggles, inputs, and other supported primitives can therefore drive the prototype naturally. Explicit event controls and state jumps remain available for inspection and debugging.\n\n## Runtime verification\n\nAny test runner or application can emit the language-neutral NDJSON protocol:\n\n```json\n{\"type\":\"state\",\"machine\":\"checkout.app\",\"state\":\"cart\"}\n{\"type\":\"transition\",\"machine\":\"checkout.app\",\"from\":\"cart\",\"event\":\"CHECK_OUT\",\"to\":\"payment\"}\n{\"type\":\"component\",\"id\":\"checkout.submit\",\"action\":\"click\"}\n```\n\nThen verify the recorded behavior:\n\n```bash\nwirestate coverage .wirestate/traces/*.ndjson\nwirestate check\n```\n\n`wirestate check`:\n\n1. Validates the DSL.\n2. Scans source and specification bindings in both directions.\n3. Reads configured runtime traces.\n4. Rejects unknown states and transitions.\n5. Enforces configured state and transition coverage.\n\n### Conformance and coverage\n\nWirestate treats these as separate signals:\n\n- **Conformance** asks whether the application demonstrated behavior that contradicts or falls outside the model.\n- **Coverage** asks which modeled states and transitions were actually demonstrated by tests.\n\nAn application can conform while still leaving much of the expected behavior uncovered. CI policies can enforce both independently.\n\n```yaml\nstrict:\n  bindings: true\n\ncoverage:\n  states: 90\n  transitions: 80\n```\n\n## CLI reference\n\n```text\nwirestate init\nwirestate validate [--json]\nwirestate inspect\nwirestate graph [MACHINE] [--dot]\nwirestate simulate --machine ID --events EVENT,EVENT\nwirestate jump --machine ID --state ID\nwirestate interact --machine ID --state ID --component ID --kind click|fill|toggle|submit|wait|custom\nwirestate sync [--json]\nwirestate coverage [TRACE...]\nwirestate check [--json]\nwirestate serve [--port PORT] [--open]\nwirestate comment list|add|update|remove ...\nwirestate smoke generate --machine ID --out FILE\n```\n\nEverything the studio can mutate maps to a core or CLI operation. The visual interface remains a replaceable surface over the same testable behavior.\n\n## Configuration\n\nA project can use `wirestate.config.yml`, `.wirestate.yml`, or their `.yaml` equivalents. Global configuration may be stored at `~/.config/wirestate/config.yml` or selected with `WIRESTATE_GLOBAL_CONFIG`.\n\n```yaml\nspecs:\n  - src/**/*.wire.yml\n\nsource:\n  - src/**/*.ts\n  - src/**/*.html\n  - tests/**/*\n\ntrace:\n  - .wirestate/traces/**/*.ndjson\n\nstrict:\n  bindings: true\n\ncoverage:\n  states: 90\n  transitions: 80\n\nserver:\n  port: 4177\n  open: false\n```\n\nProject values override global values. Nested configuration objects are merged.\n\n## Colocated TypeScript example\n\nThe included habit tracker is organized by implementation boundary rather than by a separate specification folder:\n\n```text\nexamples/habit-tracker/\n  src/\n    shell/       browser entry point and application machine\n    habits/      habit model, storage, screens, and component specs\n    goals/       period progress, calculations, and completion screen\n    sync-cli/    runnable export CLI and behavior-only machine\n    shared/      reusable wireframe templates\n```\n\nThe example supports:\n\n- Daily and weekly goals.\n- Progress recorded in measurable chunks.\n- Dashboard summaries.\n- Habit creation and archival.\n- Habit detail and activity-logging states.\n- Goal-completion behavior.\n- A related CLI export workflow using a behavior-only machine.\n\nThe browser application records traces in `globalThis.__WIRESTATE_TRACE__`. The export CLI emits the same state and transition events as NDJSON to stdout.\n\n```bash\nnpm run example:build\nnpm run example:app\nnpm run example:sync\n```\n\n## Detecting specification drift\n\nThe example test suite verifies both drift directions:\n\n1. **Code changes without a specification update.** Removing a required source binding causes synchronization to report the binding as missing in code.\n2. **Specification changes without an implementation update.** Renaming a specification binding causes synchronization to report the new binding as missing and the old source binding as unknown.\n\nThis does not make drift impossible. It makes drift observable, reviewable, and enforceable in CI.\n\n## Verification\n\nThe current release was checked with:\n\n- More than 90% line and function coverage in the core test suite.\n- Unit, integration, HTTP, CLI, trace, and drift tests.\n- Source/specification synchronization in both directions.\n- Full modeled state and transition coverage in the checked-in example trace.\n- Browser application and related TypeScript CLI builds.\n- npm package-content and extracted-package smoke checks.\n\nRun the complete local verification:\n\n```bash\nnpm run check\nnpm run example:check\n```\n\n## Architecture\n\n```text\nYAML specifications\n       │\n       ▼\nLoader → Validator → Normalized project\n                         │\n            ┌────────────┼────────────┐\n            ▼            ▼            ▼\n        Studio UI       CLI       Adapter API\n            │            │            │\n            └────────────┼────────────┘\n                         ▼\n               Runtime trace verifier\n                         │\n                         ▼\n              Conformance and coverage\n```\n\nThe core does not depend on a browser framework. Machines, screens, comments, traces, and reports normalize to JSON-compatible objects, allowing adapters in other languages to implement the same contracts without embedding the TypeScript runtime.\n\nPassive trace validation is the reliable default. Active traversal is intentionally limited to Playwright smoke-test generation while fixture generation, guarded path planning, loop limits, and application-specific recovery remain behind an adapter boundary.\n\n## Repository map\n\n```text\nsrc/                     core, CLI, server, and adapters\npublic/                  local split-view studio\nsite/                    GitHub Pages website and documentation\nschema/                  JSON Schema for the DSL\ndocs/                    architecture and adapter contracts\nexamples/habit-tracker/  functional TypeScript example and specs\ntests/                   unit, integration, drift, HTTP, and CLI tests\n```\n\nDetailed references:\n\n- [Architecture](./docs/architecture.md)\n- [DSL reference](./docs/dsl.md)\n- [Adapter contracts](./docs/adapters.md)\n- [Web documentation][documentation]\n\n## FAQ\n\n### Why are generated views and artifacts not manually editable?\n\nWirestate is designed for specification-first, agentic development. The checked-in specification is the source of truth. Graphs, previews, generated tests, scaffolds, and reports are derived projections that must be reproducible from it.\n\nDirectly editing derived output would create hidden state that cannot be regenerated reliably, may be overwritten, and leaves reviewers and coding agents unable to determine which representation expresses the intended behavior.\n\nHumans and agents instead edit machines, screens, comments, and constraints through the filesystem, CLI, or supported specification-focused UI operations. Derived artifacts are then regenerated and verified deterministically.\n\nThis boundary does **not** prohibit editing application code or authoring specifications. It prevents generated projections from becoming competing sources of truth.\n\n### Does Wirestate replace tests?\n\nNo. Tests still exercise the application and own fixtures, authentication, environment setup, and assertions. Wirestate adds a behavioral contract above them: conformance rejects behavior outside the model, while coverage reports modeled behavior that tests have not demonstrated.\n\n### Does Wirestate replace XState or another runtime state library?\n\nNo. Wirestate is a specification and verification layer. An application may use XState, Redux, a backend workflow engine, ordinary functions, or no explicit runtime state-machine library at all.\n\n### Does it verify pixel-perfect visual output?\n\nNot in the core. The screen DSL models behavior and barebones layout rather than CSS. Screenshot, accessibility-tree, and semantic DOM adapters can provide additional evidence without turning the specification into a second frontend implementation.\n\n### Why is passive verification the default?\n\nApplication-owned tests already know how to authenticate, create fixtures, and recover from environment-specific failures. Passive traces reuse that knowledge. Fully autonomous traversal additionally requires fixture providers, guard resolution, path planning, loop bounds, and recovery policies, so it remains an adapter concern.\n\n### Can state machines be defined without screens?\n\nYes. Screens are optional. Behavior-only machines can model backend services, workers, workflows, and CLI tools using the same verification protocol.\n\n### Is Wirestate language-specific?\n\nThe reference implementation and CLI use TypeScript, but the specification, bindings, and trace protocol are language-neutral. Other ecosystems can integrate through source scanners, decorators, comments, and trace adapters.\n\n## Near-term roadmap\n\n- Guard expressions and explicit nondeterministic transition selection.\n- Parallel state regions and history states.\n- Adapter SDKs for Java, Python, Go, Rust, and browser frameworks.\n- Packaged Playwright fixtures and reporters with trace attachments.\n- Path selection, fixture providers, and bounded active traversal.\n- Git-aware comment attribution and review status.\n- Precise source locations in normalized nodes and diagnostics.\n- Incremental indexes for very large specifications.\n- Deterministic code-generation contracts and agent manifests.\n\n## Documentation site\n\nThe static website lives in `site/`. The included GitHub Actions workflow publishes that directory through GitHub Pages.\n\nPreview it locally:\n\n```bash\npython3 -m http.server 8080 --directory site\n```\n\nThen open `http://localhost:8080`.\n\nTo deploy:\n\n1. Replace `alainux` in the link definitions at the bottom of this README.\n2. Push the repository to GitHub with `main` as the default branch.\n3. Open **Settings → Pages** and choose **GitHub Actions** as the source.\n4. Push a change under `site/` or manually run the **Deploy documentation site** workflow.\n\n## Publishing the package\n\nAuthenticate, verify, and publish:\n\n```bash\nnpm install\nnpm run check\nnpm pack --dry-run\nnpm login\nnpm publish --access public\n```\n\nnpm publishing requires an account configured for secure publishing, such as two-factor authentication or an appropriate granular access token. For a scoped public package, use a scoped `name` in `package.json` and retain `--access public`.\n\nFor later releases:\n\n```bash\nnpm version patch  # or minor / major\ngit push --follow-tags\nnpm publish --access public\n```\n\n## License\n\n[MIT](LICENSE)\n\n[website]: https://alainux.github.io/wirestate/\n[documentation]: https://alainux.github.io/wirestate/docs/\n","readmeFilename":"README.md"}