{"id":50640234,"url":"https://github.com/universe-coder/node-self-heallm","last_synced_at":"2026-06-07T07:30:47.787Z","repository":{"id":357116723,"uuid":"1235451218","full_name":"universe-coder/node-self-heallm","owner":"universe-coder","description":"Self-healing runtime for Node.js and TypeScript projects.","archived":false,"fork":false,"pushed_at":"2026-05-11T10:59:23.000Z","size":65,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T12:44:34.959Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/universe-coder.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T10:39:03.000Z","updated_at":"2026-05-11T10:59:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/universe-coder/node-self-heallm","commit_stats":null,"previous_names":["universe-coder/node-self-heallm"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/universe-coder/node-self-heallm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universe-coder%2Fnode-self-heallm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universe-coder%2Fnode-self-heallm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universe-coder%2Fnode-self-heallm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universe-coder%2Fnode-self-heallm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/universe-coder","download_url":"https://codeload.github.com/universe-coder/node-self-heallm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/universe-coder%2Fnode-self-heallm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34013240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-07T07:30:47.020Z","updated_at":"2026-06-07T07:30:47.780Z","avatar_url":"https://github.com/universe-coder.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# node-self-heallm\n\n[![npm version](https://img.shields.io/npm/v/node-self-heallm?style=flat)](https://www.npmjs.com/package/node-self-heallm)\n[![npm downloads](https://img.shields.io/npm/dm/node-self-heallm?style=flat)](https://www.npmjs.com/package/node-self-heallm)\n[![npm license](https://img.shields.io/npm/l/node-self-heallm?style=flat)](https://www.npmjs.com/package/node-self-heallm)\n[![Node.js](https://img.shields.io/node/v/node-self-heallm?style=flat)](https://www.npmjs.com/package/node-self-heallm)\n\n[![GitHub stars](https://img.shields.io/github/stars/universe-coder/node-self-heallm?style=flat)](https://github.com/universe-coder/node-self-heallm/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/universe-coder/node-self-heallm?style=flat)](https://github.com/universe-coder/node-self-heallm/network/members)\n[![GitHub issues](https://img.shields.io/github/issues/universe-coder/node-self-heallm?style=flat)](https://github.com/universe-coder/node-self-heallm/issues)\n[![GitHub last commit](https://img.shields.io/github/last-commit/universe-coder/node-self-heallm?style=flat)](https://github.com/universe-coder/node-self-heallm/commits)\n[![GitHub license](https://img.shields.io/github/license/universe-coder/node-self-heallm?style=flat)](https://github.com/universe-coder/node-self-heallm/blob/main/LICENSE)\n\nSelf-healing runtime for Node.js and TypeScript projects.\n\nThe package helps you:\n- capture runtime errors (stack traces),\n- retrieve relevant code context,\n- request a unified diff from an LLM,\n- validate patch safety policy,\n- optionally apply the patch,\n- write an audit trail and notifications.\n\n## Status\n\n`node-self-heallm` is in active development (`0.x`) and targets parity with the Python `self-heal` workflow.\n\nCurrent implemented areas:\n- CLI: `init`, `index`, `heal`, `run`, `status`\n- OpenAI-compatible and Anthropic chat support\n- Safe patch flow (diff-only, policy validation)\n- Audit log in `.self-heal/audit.jsonl`\n- Notifications: webhook/slack/telegram/sentry\n\n## Requirements\n\n- Node.js `\u003e= 20`\n- npm `\u003e= 9`\n- Git available in `PATH` (for `git apply`)\n\n## Install\n\n### As a dependency\n\n```bash\nnpm i node-self-heallm\n```\n\n### For local development\n\n```bash\ngit clone \u003cyour-repo-url\u003e\ncd node-self-heallm\nnpm ci\nnpm run build\n```\n\n## Quickstart\n\n### 1) Initialize config\n\n```bash\nself-heal init\n```\n\nThis creates `.self-heal.toml` in your project root.\n\n### 2) Set API key\n\nBy default config expects:\n\n```bash\nexport OPENAI_API_KEY=\"...\"\n```\n\nIf you use another env var, set `llm.apiKeyEnv` in config.\n\n### 3) Build code index\n\n```bash\nself-heal index\n```\n\n### 4) Generate fix from traceback file\n\n```bash\nnode your-app.js 2\u003e error.log\nself-heal heal --tb error.log\n```\n\n### 5) Supervised mode\n\n```bash\nself-heal run -- node your-app.js\n```\n\nWith auto-apply:\n\n```bash\nself-heal run --auto --no-dry-run -- node your-app.js\n```\n\n## CLI reference\n\n## `self-heal init`\n\nCreate config from built-in template.\n\n```bash\nself-heal init --project .\nself-heal init --force\n```\n\nOptions:\n- `-p, --project \u003cpath\u003e`: explicit project root\n- `-f, --force`: overwrite existing `.self-heal.toml`\n\n## `self-heal index`\n\nScan configured files and prepare embeddings context.\n\n```bash\nself-heal index\n```\n\nNotes:\n- For `llm.provider = \"anthropic\"` indexing is rejected (no embeddings route in current implementation).\n- Uses include/exclude globs from config.\n\n## `self-heal heal`\n\nGenerate a patch from traceback (`--tb` file or stdin).\n\n```bash\nself-heal heal --tb error.log\ncat error.log | self-heal heal\nself-heal heal --tb error.log --apply --no-dry-run\nself-heal heal --tb error.log --auto --no-dry-run\n```\n\nOptions:\n- `--tb \u003cpath\u003e`: traceback source file\n- `--apply`: allow patch apply mode\n- `--auto`: force auto-apply mode\n- `--dry-run / --no-dry-run`: write changes or only propose diff\n- `-p, --project \u003cpath\u003e`: explicit project root\n\n## `self-heal run`\n\nRun a command under supervision and attempt healing when traceback is detected.\n\n```bash\nself-heal run -- node your-app.js\nself-heal run --auto --no-dry-run -- node your-app.js\n```\n\nOptions:\n- `--auto`: auto-apply mode when patch is valid\n- `--dry-run / --no-dry-run`: apply behavior toggle\n- `-p, --project \u003cpath\u003e`: explicit project root\n\n## `self-heal status`\n\nShow recent audit events.\n\n```bash\nself-heal status\nself-heal status -n 50\n```\n\nOptions:\n- `-n, --limit \u003cnumber\u003e`: number of recent entries\n- `-p, --project \u003cpath\u003e`: explicit project root\n\n## Configuration\n\nPrimary file: `.self-heal.toml`\n\nExample:\n\n```toml\n[llm]\nprovider = \"openai\"\nbaseUrl = \"https://api.openai.com/v1\"\nmodel = \"gpt-4o-mini\"\nembeddingModel = \"text-embedding-3-small\"\napiKeyEnv = \"OPENAI_API_KEY\"\n\n[index]\nroots = [\"src\"]\ninclude = [\"**/*.ts\", \"**/*.js\"]\nexclude = [\"**/node_modules/**\", \"**/dist/**\"]\ntopK = 8\n\n[heal]\nmode = \"suggest\"\ndryRun = true\nallowedPaths = [\"src/**\", \"tests/**\"]\nforbiddenPaths = [\".git/**\", \".env*\", \"package-lock.json\"]\nmaxPatchLines = 1200\n\n[supervisor]\nmaxRestarts = 2\nretryExitCodes = [1]\n\n[notifications]\nenabled = false\nincludeTraceback = true\nincludeDiff = false\nmaxTracebackLines = 80\nallowInsecure = false\n```\n\n### `[heal]` — allowed values\n\n| Field | Allowed values | Purpose |\n|------|----------------|---------|\n| `mode` | string: `suggest` or `apply` | `suggest` — generate a diff and record audit only; `apply` — allow applying the patch (unless blocked by `dryRun`; see below). |\n| `dryRun` | `true` or `false` | When `true`, the patch is never applied to the working tree, even if `mode = \"apply\"`. |\n| `allowedPaths` | array of glob patterns | Paths in the diff that may be modified. |\n| `forbiddenPaths` | array of glob patterns | Paths that must not be modified. |\n| `maxPatchLines` | positive integer | Upper bound on patch size in lines. |\n\nRuntime behavior: if `dryRun = true` or `mode = \"suggest\"`, only a proposed diff is produced (audit event `heal_diff_proposed`). `git apply` runs only when `mode = \"apply\"` and `dryRun = false`.\n\nCLI mapping: `self-heal heal` currently chooses `suggest` vs `apply` from `--apply`, `--auto`, and `--dry-run` / `--no-dry-run`, not from the `[heal].mode` field in the file. The config `mode` mainly reflects intent for programmatic use (`selfHeal(\"apply\")`, etc.) and documents the contract; keep it aligned with how you invoke the CLI. `self-heal run` uses only `--auto` and the dry-run flags. The `selfHeal(mode)` decorator passes the chosen `mode` into the pipeline and uses `dryRun` from `config.heal.dryRun`.\n\n### `[llm].provider` — allowed values\n\n| Value | Description |\n|-------|-------------|\n| `\"openai\"` | Chat and embeddings via an OpenAI-compatible API (default). |\n| `\"huggingface\"` | Same protocol, different `baseUrl` (e.g. inference routers). |\n| `\"ollama\"` | Local OpenAI-compatible endpoint. |\n| `\"anthropic\"` | Native Messages API; `index` is not available in this setup (no embeddings path). |\n\nFor `[index]`, `[supervisor]`, and `[notifications]`, see the template from `self-heal init` and the example above; booleans are `true` / `false`, lists are TOML arrays of strings or numbers.\n\n## LLM providers\n\nSupported chat providers:\n- `openai` (default)\n- `huggingface` (OpenAI-compatible endpoint)\n- `ollama` (OpenAI-compatible local endpoint)\n- `anthropic` (native messages API path)\n\nImportant:\n- Embeddings path in current code is OpenAI-compatible only.\n- With `anthropic`, `self-heal index` intentionally fails fast.\n\n## Choosing LLM models\n\nThe workflow sends a traceback plus retrieved code to the chat model and expects a **valid unified diff** back. Pick models that follow instructions reliably; cheap general chat models may omit diff headers, break hunks, or hallucinate paths.\n\n### Chat model (`llm.model`)\n\n| Goal | Suggestion |\n|------|------------|\n| Everyday fixes, CI noise, tight budget | Stay on the default or similar small multimodal/coding model (e.g. `gpt-4o-mini`). Often enough when the bug is localized and retrieval surfaces the right files. |\n| Hard logic, cross-file refactors, unclear stacks | Use a stronger tier on the same API (e.g. `gpt-4o` or the vendor’s latest strong coding model, or a top Claude model). Quality of the diff usually matters more than raw speed. |\n| Local / air-gapped (`ollama`, self-hosted OpenAI-compatible) | Prefer **coding-oriented** weights with a **context window** that fits your prompt (traceback + several file chunks). Smoke-test: run `heal` on a known small error and confirm the model returns a clean `diff --git` block. |\n| Anthropic (`anthropic`) | Use a current Claude model your key can access. Note: the Anthropic path uses a bounded `max_tokens` for the reply; very large patches may truncate—if that happens, narrow retrieval (`index.topK`, globs) or split the fix manually. |\n\n**Practical tips**\n\n- Keep **one provider** for `index` + `heal` when possible so base URLs and keys stay simple. If you index with OpenAI-compatible and heal with Anthropic, that works, but you maintain two stacks.\n- **Temperature** in this package is fixed at `0` for OpenAI-compatible chat—favor models that behave well at low temperature (deterministic, format-following).\n- If the model often returns prose instead of a patch, switch up a tier or add a guard in your process (human review, `dryRun`) rather than fighting the same model repeatedly.\n\n### Embedding model (`llm.embeddingModel`)\n\nOnly used on **OpenAI-compatible** providers for `self-heal index`.\n\n| Situation | Suggestion |\n|-----------|------------|\n| Small repos, few languages | Smaller embedding models (e.g. `text-embedding-3-small`) are usually sufficient and cheaper. |\n| Large monorepos, similar symbol names, noisy tracebacks | Consider a larger / higher-quality embedding model if your host offers one, so retrieval ranks the right snippets more often. |\n| Third-party routers | Use whatever embedding id your `baseUrl` documents; mismatched model names fail at runtime, not at config parse time. |\n\n### Cost, latency, and safety\n\n- **Cost**: Most spend is chat tokens (long prompts + diff output). Embeddings are paid per index rebuild, not per heal.\n- **Latency**: Stronger models can be slower; supervised `run` waits on the heal step—budget accordingly for interactive dev.\n- **Safety**: A stronger model does not replace policy checks. Combine a capable model with narrow `heal.allowedPaths`, `dryRun` until you trust the flow, and review diffs before `--no-dry-run`.\n\n## Notifications\n\nChannels:\n- Webhook\n- Slack webhook\n- Telegram bot API\n- Sentry\n\nSecurity defaults:\n- only http/https URLs\n- https required unless `allowInsecure = true`\n- localhost/private addresses rejected for webhook/slack URL targets\n- redirects disabled in HTTP transport\n- request timeout is bounded\n- optional webhook HMAC signature in headers\n\n## Audit log\n\nAudit file path:\n\n```text\n.self-heal/audit.jsonl\n```\n\nExamples of event types:\n- `error_captured`\n- `heal_diff_proposed`\n- `heal_applied`\n- `heal_apply_failed`\n- `notification_sent`\n- `notification_failed`\n\nUse:\n\n```bash\nself-heal status\n```\n\n## Security model\n\nCore constraints:\n- model output is treated as text, not executable code\n- only unified diffs are accepted for patch flow\n- changed paths must pass allow/deny policy\n- secrets should be loaded from environment variables\n- traceback/error text is sanitized before outbound usage\n\nRecommended production defaults:\n- keep `dryRun = true` until you trust the workflow\n- keep narrow `allowedPaths`\n- keep strict `forbiddenPaths` for credentials/config files\n\n## Programmatic usage\n\nCurrent public exports:\n\n```ts\nimport { install, selfHeal } from \"node-self-heallm\";\n```\n\nExample:\n\n```ts\nimport { install, selfHeal } from \"node-self-heallm\";\n\nawait install();\n\nconst wrapped = selfHeal(\"suggest\")(async () =\u003e {\n  // your risky logic\n});\n\nawait wrapped();\n```\n\n## Development\n\n```bash\nnpm ci\nnpm run lint\nnpm run typecheck\nnpm run test\nnpm run build\n```\n\nPackage validation:\n\n```bash\nnpm run pack:check\nnpm publish --dry-run\n```\n\n## Troubleshooting\n\n### `Missing required environment variable`\n\n- Check `llm.apiKeyEnv` and exported env var name.\n\n### `Anthropic provider does not support embeddings for index command`\n\n- Use OpenAI-compatible provider for indexing.\n- Then switch provider for heal stage if needed.\n\n### `Path not allowed by policy`\n\n- Expand `heal.allowedPaths` carefully.\n- Ensure target file is not in `heal.forbiddenPaths`.\n\n### `git apply failed`\n\n- Ensure repository state is valid and patch cleanly applies.\n- Retry in `dry-run`, inspect diff, then apply manually if needed.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funiverse-coder%2Fnode-self-heallm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funiverse-coder%2Fnode-self-heallm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funiverse-coder%2Fnode-self-heallm/lists"}