nodal-agents 0.5.5 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/README.md +191 -310
  2. package/cli.js +9 -1
  3. package/migrations/0049_skill_assignment_files_writable.sql +1 -0
  4. package/migrations/meta/_journal.json +7 -0
  5. package/package.json +1 -1
  6. package/runner.js +571 -108
  7. package/web/.next/BUILD_ID +1 -1
  8. package/web/.next/app-path-routes-manifest.json +3 -3
  9. package/web/.next/build-manifest.json +2 -2
  10. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +6 -4
  11. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js.nft.json +1 -1
  12. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
  13. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +2 -2
  14. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
  15. package/web/.next/server/app/(dashboard)/agents/page.js +2 -2
  16. package/web/.next/server/app/(dashboard)/agents/page.js.nft.json +1 -1
  17. package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
  18. package/web/.next/server/app/(dashboard)/approvals/page.js +2 -2
  19. package/web/.next/server/app/(dashboard)/approvals/page.js.nft.json +1 -1
  20. package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
  21. package/web/.next/server/app/(dashboard)/automations/page.js +2 -2
  22. package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/billing/page.js +1 -1
  24. package/web/.next/server/app/(dashboard)/billing/page_client-reference-manifest.js +1 -1
  25. package/web/.next/server/app/(dashboard)/chat/page.js +2 -2
  26. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  27. package/web/.next/server/app/(dashboard)/connectors/page.js +2 -2
  28. package/web/.next/server/app/(dashboard)/connectors/page.js.nft.json +1 -1
  29. package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/credentials/page.js +2 -2
  31. package/web/.next/server/app/(dashboard)/credentials/page.js.nft.json +1 -1
  32. package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +2 -2
  34. package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/jobs/page.js +2 -2
  36. package/web/.next/server/app/(dashboard)/jobs/page.js.nft.json +1 -1
  37. package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/(dashboard)/learned-skills/page.js +1 -1
  39. package/web/.next/server/app/(dashboard)/learned-skills/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/llm-providers/page.js +2 -2
  41. package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/logs/page.js +1 -1
  43. package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
  44. package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
  45. package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/memories/page.js +2 -2
  47. package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/page.js +3 -3
  49. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  50. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/settings/page.js +2 -2
  52. package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  53. package/web/.next/server/app/(dashboard)/settings/root-context/page.js +1 -1
  54. package/web/.next/server/app/(dashboard)/settings/root-context/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +2 -2
  56. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js.nft.json +1 -1
  57. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/app/(dashboard)/skills/new/page.js +2 -2
  59. package/web/.next/server/app/(dashboard)/skills/new/page.js.nft.json +1 -1
  60. package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
  62. package/web/.next/server/app/(dashboard)/skills/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/_global-error/page.js +1 -1
  65. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/_global-error.html +1 -1
  67. package/web/.next/server/app/_global-error.rsc +3 -3
  68. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
  69. package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  70. package/web/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  71. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  72. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  73. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  74. package/web/.next/server/app/_not-found/page.js +1 -1
  75. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/_not-found.html +1 -1
  77. package/web/.next/server/app/_not-found.rsc +4 -4
  78. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  79. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  80. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  81. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  82. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  83. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  84. package/web/.next/server/app/login/page.js +1 -1
  85. package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
  86. package/web/.next/server/app/onboarding/page.js +1 -1
  87. package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/onboarding.html +1 -1
  89. package/web/.next/server/app/onboarding.rsc +4 -4
  90. package/web/.next/server/app/onboarding.segments/_full.segment.rsc +4 -4
  91. package/web/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
  92. package/web/.next/server/app/onboarding.segments/_index.segment.rsc +4 -4
  93. package/web/.next/server/app/onboarding.segments/_tree.segment.rsc +2 -2
  94. package/web/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
  95. package/web/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
  96. package/web/.next/server/app-paths-manifest.json +3 -3
  97. package/web/.next/server/chunks/1445.js +1 -0
  98. package/web/.next/server/chunks/3024.js +1 -0
  99. package/web/.next/server/chunks/3966.js +1 -1
  100. package/web/.next/server/chunks/3971.js +1 -0
  101. package/web/.next/server/chunks/4370.js +59 -20
  102. package/web/.next/server/chunks/4574.js +1 -1
  103. package/web/.next/server/chunks/6012.js +1 -0
  104. package/web/.next/server/chunks/7928.js +1 -0
  105. package/web/.next/server/chunks/8909.js +1 -0
  106. package/web/.next/server/middleware-build-manifest.js +1 -1
  107. package/web/.next/server/pages/404.html +1 -1
  108. package/web/.next/server/pages/500.html +1 -1
  109. package/web/.next/server/server-reference-manifest.js +1 -1
  110. package/web/.next/server/server-reference-manifest.json +1 -1
  111. package/web/.next/static/chunks/2787-b32c92cd300d8dc6.js +1 -0
  112. package/web/.next/static/chunks/4414-4e856db2be92b231.js +1 -0
  113. package/web/.next/static/chunks/6097-d568d74074f2dad0.js +1 -0
  114. package/web/.next/static/chunks/8370-18663baebcb57ea1.js +1 -0
  115. package/web/.next/static/chunks/8502-10b8c3517f2f6c63.js +1 -0
  116. package/web/.next/static/chunks/{8666-2e66ac2d8f9b71a3.js → 8666-ee79795cd5f52e9c.js} +1 -1
  117. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-e3522f5beaa39d00.js +6 -0
  118. package/web/.next/static/chunks/app/(dashboard)/agents/page-fa24d21f3dd81779.js +1 -0
  119. package/web/.next/static/chunks/app/(dashboard)/automations/{page-3b724d8f6e8c957f.js → page-54d3b31e9f8319ba.js} +1 -1
  120. package/web/.next/static/chunks/app/(dashboard)/chat/page-0756eef0efe47d26.js +1 -0
  121. package/web/.next/static/chunks/app/(dashboard)/connectors/page-e155c796daf03636.js +1 -0
  122. package/web/.next/static/chunks/app/(dashboard)/credentials/{page-ef2666c5ac3ede9b.js → page-38a4707132e529ba.js} +1 -1
  123. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/{page-7e9af908ef12f252.js → page-d24cf11cba87c25c.js} +1 -1
  124. package/web/.next/static/chunks/app/(dashboard)/jobs/page-addbc7ca9fd29056.js +1 -0
  125. package/web/.next/static/chunks/app/(dashboard)/layout-74abd51f1d4f4847.js +1 -0
  126. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-596febd5d9d3130e.js +1 -0
  127. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-3e569fa57980ef9b.js +1 -0
  128. package/web/.next/static/chunks/app/(dashboard)/logs/{page-21d587049e8a6ccb.js → page-c9543d1a5b387378.js} +1 -1
  129. package/web/.next/static/chunks/app/(dashboard)/mcp/page-cc885192e6efce48.js +1 -0
  130. package/web/.next/static/chunks/app/(dashboard)/memories/page-2bc309d3e59fb48d.js +1 -0
  131. package/web/.next/static/chunks/app/(dashboard)/page-b6ce64251f732896.js +1 -0
  132. package/web/.next/static/chunks/app/(dashboard)/settings/page-b73e0e200ee4d9fa.js +1 -0
  133. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-af7ccec522050199.js +1 -0
  134. package/web/.next/static/chunks/app/(dashboard)/skills/new/{page-6246f9236b209e76.js → page-95280e7f506e3443.js} +1 -1
  135. package/web/.next/static/chunks/app/(dashboard)/skills/page-8e381563f665bb68.js +1 -0
  136. package/web/.next/static/chunks/app/{error-f106e9e65e16edb3.js → error-dc3b2db3bdb5b34e.js} +1 -1
  137. package/web/.next/static/css/ef13c0ab64dcfa86.css +3 -0
  138. package/web/.next/server/chunks/234.js +0 -1
  139. package/web/.next/server/chunks/473.js +0 -1
  140. package/web/.next/server/chunks/6200.js +0 -1
  141. package/web/.next/server/chunks/6778.js +0 -1
  142. package/web/.next/server/chunks/7415.js +0 -1
  143. package/web/.next/static/chunks/269-dc034ed29e6c72ee.js +0 -1
  144. package/web/.next/static/chunks/3233-e6efb7fb1fa24591.js +0 -1
  145. package/web/.next/static/chunks/5436-c1006a40e59853ed.js +0 -1
  146. package/web/.next/static/chunks/6078-abdc3955397924b3.js +0 -1
  147. package/web/.next/static/chunks/6097-12165ea99c077896.js +0 -1
  148. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-113e915a8d6bc208.js +0 -4
  149. package/web/.next/static/chunks/app/(dashboard)/agents/page-4796ad5efe8f9d82.js +0 -1
  150. package/web/.next/static/chunks/app/(dashboard)/chat/page-b98de38c17f2cd96.js +0 -1
  151. package/web/.next/static/chunks/app/(dashboard)/connectors/page-ca2e5aabaadd7588.js +0 -1
  152. package/web/.next/static/chunks/app/(dashboard)/jobs/page-9b09d95cc1a8053c.js +0 -1
  153. package/web/.next/static/chunks/app/(dashboard)/layout-a34502d1a8386a62.js +0 -1
  154. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-447ba18bc6af3c57.js +0 -1
  155. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-c0c5aa806b9b47d4.js +0 -1
  156. package/web/.next/static/chunks/app/(dashboard)/mcp/page-d53d13942bd635a4.js +0 -1
  157. package/web/.next/static/chunks/app/(dashboard)/memories/page-ebcc28ea081ae566.js +0 -1
  158. package/web/.next/static/chunks/app/(dashboard)/page-2a69294b49293833.js +0 -1
  159. package/web/.next/static/chunks/app/(dashboard)/settings/page-8b16269593b01037.js +0 -1
  160. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-6830a271484d97d5.js +0 -1
  161. package/web/.next/static/chunks/app/(dashboard)/skills/page-9375adacecc0d76b.js +0 -1
  162. package/web/.next/static/css/f93e519b745ac2de.css +0 -3
  163. /package/web/.next/static/{KOOaOEQcp6DLMYS1kFfRL → kbJ7RnqJJkxulS2bJpJy2}/_buildManifest.js +0 -0
  164. /package/web/.next/static/{KOOaOEQcp6DLMYS1kFfRL → kbJ7RnqJJkxulS2bJpJy2}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -1,310 +1,191 @@
1
- # Nodal-Agents
2
-
3
- > **Your AI agents. Your data. Your machine.**
4
- > Self-hosted, local-first AI agent platform — install in two commands.
5
-
6
- [![npm](https://img.shields.io/npm/v/nodal-agents?color=cb3837&label=npm&logo=npm)](https://www.npmjs.com/package/nodal-agents)
7
- [![Node](https://img.shields.io/badge/node-22%2B-339933?logo=node.js&logoColor=white)](https://nodejs.org)
8
- [![TypeScript](https://img.shields.io/badge/typescript-strict-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
9
-
10
- Build and orchestrate a **team of AI agents** on your own hardware —
11
- each with its own personality, tools, memory, and model. Talk to them in
12
- the dashboard or on Telegram; they research, write files, call your
13
- connectors, and delegate to each other to get the job done.
14
-
15
- **No SaaS lock-in. No per-token markup. No cloud roundtrip.** Two commands
16
- to install, runs on any machine with Node 22+ (Mac, PC, Linux), and works
17
- with **any LLM** — frontier or local, paid or free.
18
-
19
- ---
20
-
21
- ## Why Nodal-Agents
22
-
23
- | | |
24
- | --- | --- |
25
- | 🏠  **Local-first** | Single binary, embedded Postgres, zero cloud dependency. Your conversations, memory, and credentials stay on your machine. |
26
- | 🔌  **Any model, per agent** | Anthropic, OpenAI, Google, Groq, Mistral, OpenRouter, **native DeepSeek** (`api.deepseek.com`) and **native MiniMax** (`api.minimax.io`), or any local model (LM Studio, Ollama). Setup is just an API key per provider — **each agent picks its own model**, so you can run Claude for the orchestrator and **DeepSeek V4** for the workers. The quirks of OSS frontier models (DeepSeek's non-spec tool args, Kimi/Qwen/GLM XML tool formats, and round-tripping a reasoning model's chain-of-thought across tool calls so MiniMax M3 / DeepSeek / Gemini 3 don't degrade mid-task) are handled automatically. |
27
- | 🛟  **Provider failover** | Give an agent a backup key chain if its provider 5xx's, times out, or hits quota mid-job, the runner fails over to the next one and keeps going (and fails loud only when the whole chain is down). |
28
- | 🧠  **Memory that compounds** | Persistent facts (entity-scoped, auto-injected into every job) and chat-thread continuity (your agent remembers what it said 30 seconds ago — and what it said yesterday). |
29
- | 🤝  **Orchestrators that finish** | Every orchestrator picks the delegation style per request route to one specialist and resume on its result, or fan out independent work to many sub-agents in parallel and compile their results — then wraps up the answer. |
30
- | 🌱  **Self-improving agents** | Opt-in learning loop: after a substantial job, an agent reflects on the transcript and writes itself a reusable skill; a weekly curator consolidates and prunes them. Every learned skill is reviewable, assignable, and revocable from the dashboard (off by default, per workspace). |
31
- | 📥  **Install any community skill** | Point it at any open `SKILL.md` — a GitHub repo, a skills.sh slug, or a ClawHub package — and it fetches, unpacks, and installs it as a first-class skill. Pure HTTPS fetch with SSRF allow-listing and zip-slip guards; bundled scripts are flagged, never executed. |
32
- | 🛡️  **Agents that don't lie, loop, or die** | Generic runtime guards: a per-job **real-dollar cost cap** (from the provider's actual billed cost) and a no-progress detector kill runaway loops; a no-false-success guard refuses to report "done" when an action actually failed; an atomic job claim prevents the same job running twice; and every failed or blocked job hands you a short, specific reason — never a silent stop. Turn/chain/delegation caps bound everything. |
33
- | 🔧  **Multi-instance connectors** | Gmail perso *and* Gmail boulot on the same install. OAuth *and* API-key supported. Active list + Marketplace UI in the dashboard. |
34
- | 🗂️  **Workspaces** | Multiple isolated workspaces on one install (personal vs work) — each with its own agents, skills, connectors, jobs and memory. Switch from the sidebar. |
35
- | 🤖  **Self-extending (ROOT agent)** | Designate an orchestrator as ROOT and let it create skills/agents and assign them on your behalf gated by per-grant toggles and an autonomy level (propose-confirm fully-autonomous). |
36
- | 📄  **Office files** | Read + edit Excel in place, create Word & PowerPoint, inside the agent's workspace gated behind the office-editing skill. |
37
- | 📡  **MCP support** | Connect MCP servers over Streamable HTTP *and* stdio (local subprocess) a growing catalogue (Stripe, n8n, Supabase, Airtable, Notion…) plus add *and edit* your own custom servers from the UI. Per-job tool discovery, tool whitelisting, multi-instance. |
38
- | 💬 &nbsp;**Telegram out of the box** | Long-polling, multi-agent routing (`/ask <slug>`), group-chat filters, conversation continuity, delegation gracefulness on Telegram. |
39
- | ⚙️ &nbsp;**Real engineering** | TypeScript strict, dependency-cruiser-enforced architecture, full unit + integration suite, Playwright e2e, idempotent migrations, encryption at rest for keys. |
40
-
41
- ---
42
-
43
- ## Screenshots
44
-
45
- | Home dashboard light theme | Agent detail — dark theme |
46
- | :---: | :---: |
47
- | ![Home dashboard, light theme](docs/screenshots/home_lightheme.png) | ![Agent detail page, dark theme](docs/screenshots/agent_darktheme.png) |
48
-
49
- ---
50
-
51
- ## Install
52
-
53
- ```bash
54
- npm install -g nodal-agents
55
- nodal-agents up
56
- ```
57
-
58
- Open <http://localhost:3000>. The CLI spawns an embedded Postgres on a
59
- free port, applies migrations, seeds the system skills, and starts the
60
- runner (`:3001`) and dashboard (`:3000`). Connect an LLM provider from
61
- **LLM Providers** in the dashboard — paste an API key and you're running.
62
-
63
- > Requires Node 22+. No external Postgres, no Redis, no cloud config.
64
- > Data lives at `~/.nodalai/` wipe with `rm -rf ~/.nodalai`.
65
-
66
- To stop the stack: `nodal-agents down`.
67
-
68
- ## Update
69
-
70
- ```bash
71
- nodal-agents update
72
- ```
73
-
74
- Checks the npm registry for the latest version, stops the running stack,
75
- installs `nodal-agents@latest` globally, and restarts services automatically.
76
- No data is touched the embedded Postgres data directory is preserved.
77
-
78
- ```bash
79
- nodal-agents update --no-restart
80
- ```
81
-
82
- Installs the update but skips the automatic restart. Run `nodal-agents up`
83
- manually when ready.
84
-
85
- When a newer version is available, `nodal-agents up` also prints a one-line
86
- notice:
87
-
88
- ```
89
- v0.5.1 available — run `nodal-agents update`
90
- ```
91
-
92
- ### Build from source
93
-
94
- ```bash
95
- git clone https://github.com/Kwintspiracy/nodal-agents.git
96
- cd nodal-agents
97
- pnpm install
98
- pnpm --filter nodal-agents exec tsx src/index.ts --dev
99
- ```
100
-
101
- Dev mode runs `next dev` so the dashboard hot-reloads on file changes.
102
-
103
- ---
104
-
105
- ## How it works
106
-
107
- ```
108
- ┌─────────────┐ Telegram / ┌────────────────────────────────┐
109
- │ Channel │ Dashboard ───▶ │ Runner (Hono) │
110
- │ (telegram, │ POST /api ◀── │ • Job queue + executor │
111
- │ web …) │ │ • Anti-runaway guards │
112
- └─────────────┘ │ • Per-agent tool whitelist │
113
- │ • Memory auto-injection │
114
- │ • Session-thread continuity │
115
- └─────────┬──────────┬────────────┘
116
- │ │
117
- ┌───────▼───┐ ┌───▼─────────────┐
118
- │ LLM │ │ Connectors / │
119
- │ client │ │ MCP servers
120
- (multi- │ │ (Gmail, Drive,
121
- provider) │ │ Notion, Cogni
122
- └───────────┘ │ Cortex )
123
- └─────────────────┘
124
- ```
125
-
126
- Every agent is a row in Postgrespersonality, skills, connectors,
127
- memory budget, team assignments live in the database. The runtime is
128
- generic: **zero hardcoded agent metadata.** Adding capabilities means
129
- inserting rows, not editing code.
130
-
131
- A user message via Telegram becomes an `agent_jobs` row. The runner
132
- loads the agent's prior chat-thread history, injects relevant
133
- persistent memories, dispatches to the LLM, executes any tool calls
134
- emitted, and finalizes via `telegram_send_message` + `return_result`.
135
- Delegations create child jobs that resume the parent on completion.
136
-
137
- ---
138
-
139
- ## Dashboard
140
-
141
- | Route | Purpose |
142
- | --- | --- |
143
- | `/agents` | Create, edit, assign skills + connectors + MCP servers to agents — and pick each agent's provider + model (with an optional failover chain). |
144
- | `/llm-providers` | Connect each LLM provider with a single API key — enable/disable inline. Models are chosen per-agent, not here. |
145
- | `/jobs` | Live job stream — task, agent, status, full transcript, tool I/O. |
146
- | `/connectors` | Active connector instances + Marketplace (multi-instance, OAuth or API-key). |
147
- | `/mcp` | Active MCP servers + Marketplace — HTTP & stdio, a growing catalogue, plus add/edit your own custom servers. |
148
- | `/memories` | Persistent facts per entity search, edit, archive. |
149
- | `/skills` | Assigned / Custom / Built-in Library tabs reusable instructions appended to an agent's prompt; create your own, customise built-ins, or install any community `SKILL.md` from GitHub / skills.sh / ClawHub. |
150
- | `/learned-skills` | Skills the agents wrote themselves (learning loop) — review, assign, archive, restore; toggle reflection + auto-assign per workspace. |
151
- | `/logs` | Tool-call audit — input/output JSON per call, filterable by tool name. |
152
- | `/approvals` | Human-in-the-loop gates for risky tools (and the ROOT agent's meta-tools under propose-confirm). |
153
- | `/automations` | Cron-scheduled agent triggers. |
154
- | `/settings` | Auth mode, network (loopback / LAN), bot tokens, workspace management, ROOT-agent grants + autonomy. |
155
-
156
- ---
157
-
158
- ## Stack
159
-
160
- | Layer | Tech |
161
- | --- | --- |
162
- | Runtime | Node 22+, TypeScript strict (no `any`, no `@ts-ignore` without comment) |
163
- | Monorepo | pnpm workspaces + Turborepo |
164
- | Database | embedded-postgres (Win / Mac / Linux), Drizzle ORM, idempotent migrations |
165
- | Validation | Zod everywhere |
166
- | HTTP server | Hono (runner), Next.js 16 (dashboard) |
167
- | LLM | Vercel AI SDK multi-provider with retry + timeout + tolerant parsing |
168
- | Auth | local-trust (single-user loopback) / better-auth (multi-user LAN) / bearer-token |
169
- | Encryption | AES-256-GCM at rest for API keys, master key in `~/.nodalai/secrets.key` |
170
- | Tests | Vitest (unit + integration), Playwright (e2e), dependency-cruiser (architecture) |
171
-
172
- ---
173
-
174
- ## Monorepo
175
-
176
- ```
177
- apps/
178
- ├── cli nodal-agents CLI: install, up, down, ops
179
- ├── runner Hono server: job execution, cron, channel pollers
180
- └── web Next.js dashboard
181
-
182
- packages/
183
- ├── db Drizzle schema + migrations + client (only postgres importer)
184
- ├── shared Zod types + constants shared across web + runner
185
- ├── llm Vercel AI SDK wrapper, retry, timeout, native tool-call parsers
186
- ├── tools Tool registration + execution + approval gates
187
- ├── memory Persistent memory CRUD + sanitation + dedup + auto-injection
188
- ├── orchestration Router / Planner patterns, delegation, chain counters
189
- ├── adapters Connector packages (gmail, drive, sheets, docs, notion,
190
- │ airtable, apify, firecrawl, tavily, MCP)
191
- ├── runner-adapters Adapter registry, agent ↔ tool wiring
192
- ├── delivery Telegram, email
193
- ├── auth Pluggable auth provider
194
- ├── catalog Shipped system skills (office-editing, telegram-responder,
195
- │ obsidian, task-planning, markdown-output, language-mirror …)
196
- └── secrets AES-256-GCM key vault
197
- ```
198
-
199
- ---
200
-
201
- ## Architecture rules (enforced by `dependency-cruiser`)
202
-
203
- - `apps/*` may import `packages/*` — never the reverse.
204
- - `apps/web` and `apps/runner` cannot import each other (DB or HTTP only).
205
- - Only `packages/db` may import `postgres` / `drizzle-orm` / `pg`.
206
- - `packages/runner-adapters/*` may only import from `packages/tools` and
207
- `packages/shared`.
208
- - No circular dependencies.
209
-
210
- ```bash
211
- pnpm deps:check # runs locally and in CI before every release
212
- ```
213
-
214
- ---
215
-
216
- ## Status
217
-
218
- **Current release:** `0.5.2` on npm `latest`. Used daily by the
219
- maintainer, stable enough for personal production. Pre-1.0 — breaking
220
- changes are still possible between minors.
221
-
222
- ### Shipped and working
223
-
224
- - Multi-LLM, **per-agent model selection** — provider setup is just an API key
225
- (one per provider); each agent chooses its own model on top. Frontier and
226
- local providers, plus **native DeepSeek** (`api.deepseek.com`) and **native
227
- MiniMax** (`api.minimax.io`) endpoints alongside OpenRouter — pick the route
228
- per key. **DeepSeek V4** non-spec tool-call args are normalized automatically
229
- and **reasoning models like MiniMax M3** have their hidden chain-of-thought
230
- round-tripped across tool calls so they keep reasoning on multi-turn tasks,
231
- plus native tool-call parsing for Kimi K2 / Qwen3-Coder / GLM
232
- - **Provider failover** — an opt-in ordered key chain per agent; on a 5xx /
233
- timeout / quota mid-job the runner fails over to the next key, and fails loud
234
- (`all_providers_failed`) only when the whole chain is exhausted
235
- - **Reliability guards (generic, model-agnostic)** — a per-job **real-dollar
236
- cost cap** (read from the provider's actually-billed cost, `cost_budget_exceeded`)
237
- + token budget + no-progress / no-delivery detectors (kill runaway loops), an
238
- **atomic job claim** so the same job never executes twice, a no-false-success
239
- guard that refuses to complete a job as "success" when a tool action failed and
240
- was never resolved (fail loud, never fake it), a **recoverable** path for a
241
- mis-named tool call (a bounded "did you mean…" nudge, not an instant kill), and
242
- context compaction that evicts stale tool output before the context window overflows
243
- - **Never a silent stop** — every failed *or blocked* job hands the user a short,
244
- specific reason (in the agent's own words when it blocks), propagated up through
245
- delegation; a blocked job is honestly `failed`, never a fake "completed"
246
- - **Diagnosable failures** — every failed job persists its full transcript, the
247
- real upstream provider error (not an opaque "provider returned error"), and the
248
- actual upstream that served each turn, so you can see exactly what the agent did
249
- and why it stopped
250
- - **Self-improving agents (opt-in learning loop)** — after a substantial job, an
251
- agent reflects on its transcript and writes itself a reusable skill (sandboxed
252
- provenance); a weekly curator consolidates and prunes them. Review, assign,
253
- archive or revoke every learned skill from `/learned-skills` (off by default,
254
- per workspace; auto-assign or require approval)
255
- - **Install any community skill** — fetch any open `SKILL.md` from a GitHub repo,
256
- a skills.sh slug, or a ClawHub package and install it as a first-class skill
257
- (pure HTTPS, SSRF allow-list, zip-slip guard; bundled scripts flagged, never run)
258
- - Persistent memory (sanitation, dedup, importance ranking, auto-injection,
259
- feedback loop)
260
- - Session-thread continuity on chat channels (Telegram today)
261
- - **Unified orchestrator** — every orchestrator gets both delegation styles and
262
- picks per request: route to one specialist and resume on its result (router),
263
- or fan out independent tasks to a parallel task board that compiles + delivers
264
- the combined result (planner). One commits to a single style per job
265
- - Multi-instance connectors with OAuth (Gmail, Drive, Sheets, Docs, Notion,
266
- Airtable) and API-key (Notion, Airtable, Apify, Firecrawl, Tavily)
267
- - MCP catalog — Streamable HTTP *and* stdio (local subprocess) servers, API-key auth; a growing catalogue (Stripe, n8n, Supabase, Airtable, Notion…) with a "test pending" badge on entries not yet verified live, plus add *and edit* your own custom HTTP/stdio servers from the dashboard
268
- - Top-level workspaces — multiple isolated entities (agents/skills/connectors/jobs/memory per workspace), switch in the sidebar
269
- - In-app ROOT chat — talk to your workspace ROOT right in the dashboard: conversation-first (pure chat never creates a job — recall is free, the agent's memory is auto-loaded), multiple conversations with searchable history, and inline "dispatched to N agents" cards when it escalates a real action into a tracked job
270
- - ROOT agent — your first orchestrator automatically becomes the workspace ROOT (the single top-level agent; later orchestrators slot under it). It can create *and update* skills, create agents and assign them, and create MCP servers + API connectors — each gated by per-grant toggles + an autonomy/approval level (powers start off, opt in per grant). Provisioning verifies before it writes (an MCP server is connected and its tools listed first); skill authoring is grounded in the workspace's real tools (a linter rejects skills referencing tools the agent doesn't have)
271
- - Office file editing — Excel in-place edit, Word/PowerPoint create, in the agent workspace (office-editing skill)
272
- - Multiple filesystem folders per agent (sandboxed `file_*` tools)
273
- - **Shell execution** — agents can run shell commands in their workspace
274
- (`run_command`: install deps, run scripts, build steps) via an opt-in
275
- `command-execution` skill. Safe-by-default: every command pauses for your
276
- approval, with an optional per-agent auto-run ("Yolo"). On a shared / LAN
277
- install auto-run is gated behind an explicit workspace-owner opt-in and
278
- **enforced at execution time** — flip the workspace switch off and even an
279
- already-trusted agent drops back to requiring approval. A live bell surfaces
280
- pending approvals from anywhere in the dashboard
281
- - Telegram delivery (long-poll, group filters, multi-agent routing,
282
- delegation gracefulness) — exactly-once delivery contract: anti-spam guard
283
- against runaway message loops + a guard that re-prompts (then fails loud)
284
- rather than completing a job without ever replying
285
- - Approval gates for risky tools (execute-the-approved-action on resume) — on a chat channel, the agent sends a heads-up before the job pauses so the user knows an approval is waiting
286
- - Cron scheduling — trigger any automation out-of-band ("Run now") + opt-in Telegram confirmation when a scheduled job succeeds
287
- - Duplicate any automation in one click; opt-in retention to purge old terminal jobs
288
- - `nodal-agents update` — one-command upgrade + boot version notice
289
- - Encryption at rest for LLM keys + MCP keys; in LAN / multi-user modes the
290
- runner requires a shared `WORKER_SECRET` on every mutating route (no
291
- unauthenticated job/LLM spend from other devices on the network)
292
- - Embedded Postgres distribution via npm (no external DB to install)
293
-
294
- ### On the roadmap (genuine, not vaporware)
295
-
296
- - **MCP OAuth flow** → unlocks Linear, Notion remote, GitHub remote,
297
- Atlassian, Sentry, and the rest of the SaaS-as-MCP ecosystem.
298
- - **Dry-run mode + a test-workflow meta-tool** → preview what the ROOT would
299
- do before it runs, and let it validate an automation end-to-end.
300
- - **pgvector binaries bundled in the npm pack** → semantic memory search
301
- active out-of-the-box. Today, installs without pgvector fall back to
302
- keyword search (which works, just less smart for cross-vocabulary
303
- recall).
304
- - Data migration tools from the legacy Python stack.
305
-
306
- ---
307
-
308
- ## License
309
-
310
- TBD.
1
+ # Nodal-Agents
2
+
3
+ > **Your AI agents. Your data. Your machine.**
4
+
5
+ A self-hosted platform for building and orchestrating a **team of AI agents** on your own hardware — each with its own personality, tools, memory, and model. Talk to them in the dashboard or on Telegram; they research, write files, call your connectors, and delegate to each other to get the job done.
6
+
7
+ **No SaaS lock-in. No per-token markup. No cloud roundtrip.** Two commands to install, runs on any machine with Node 22+ (Mac, Windows, Linux), and works with **any LLM** — frontier or local, paid or free.
8
+
9
+ [![npm](https://img.shields.io/npm/v/nodal-agents?color=cb3837&label=npm&logo=npm)](https://www.npmjs.com/package/nodal-agents)
10
+ [![Node](https://img.shields.io/badge/node-22%2B-339933?logo=node.js&logoColor=white)](https://nodejs.org)
11
+ [![TypeScript](https://img.shields.io/badge/typescript-strict-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
12
+ [![Docs](https://img.shields.io/badge/docs-online-3565ff)](https://kwintspiracy.github.io/nodal-agents/)
13
+
14
+ | Home dashboard — light theme | Agent detail — dark theme |
15
+ | :---: | :---: |
16
+ | ![Home dashboard, light theme](docs/screenshots/home_lightheme.png) | ![Agent detail page, dark theme](docs/screenshots/agent_darktheme.png) |
17
+
18
+ ---
19
+
20
+ ## Quickstart
21
+
22
+ ```bash
23
+ npm install -g nodal-agents
24
+ nodal-agents up
25
+ ```
26
+
27
+ Open <http://localhost:3000>, paste an LLM API key under **LLM Providers**, and you have a working agent. The CLI spawns an embedded Postgres on a free port, applies migrations, seeds the system skills, and starts the runner (`:3001`) and dashboard (`:3000`).
28
+
29
+ > Node 22+ · no external Postgres, no Redis, no cloud config · data lives in `~/.nodalai/` · stop with `nodal-agents down`
30
+
31
+ ---
32
+
33
+ ## What you can build
34
+
35
+ - **A research desk** an orchestrator fans a question out to specialists (web search, your Notion, your Drive), each writes a section, then it compiles the brief and emails it to you.
36
+ - **A Telegram concierge** message a bot; it routes to the right agent, remembers the conversation, runs shell commands or calls your APIs, and asks for approval before anything risky.
37
+ - **An automation crew** — cron-scheduled agents that run every morning, hit your connectors and MCP servers, and ping you on Telegram when they're done.
38
+
39
+ Every agent runs on the model **you** choose, with the tools **you** grant, in a workspace **you** own.
40
+
41
+ ---
42
+
43
+ ## Why Nodal-Agents
44
+
45
+ ### 🏠 Own your whole stack
46
+
47
+ - **Local-first** single command, embedded Postgres, zero cloud dependency.
48
+ - **Your data & keys** — conversations, memory, and credentials never leave your machine; API keys are AES-256-GCM encrypted at rest.
49
+ - **Workspaces** — multiple isolated workspaces on one install (personal vs work), each with its own agents, skills, connectors, jobs, and memory.
50
+ - **No markup** — bring your own API keys; you pay the provider directly, nothing on top.
51
+
52
+ ### 🔌 Any model — and it stays reliable
53
+
54
+ - **A model per agent** — run Claude for the orchestrator and a cheap OSS model for the workers; setup is just one API key per provider.
55
+ - **OSS frontier models, handled** — DeepSeek's non-spec tool args, Kimi/Qwen/GLM XML tool formats, and round-tripping a reasoning model's chain-of-thought (MiniMax M3, DeepSeek, Gemini 3) across tool calls — all automatic, so they don't degrade mid-task.
56
+ - **Provider failover** — give an agent a backup key chain; on a 5xx, timeout, or quota mid-job the runner fails over to the next one and only fails loud when the whole chain is down.
57
+ - **Guards against runaway, lies, and silent stops** — a real-dollar cost cap (from the provider's billed cost), a no-progress detector, an atomic job claim (never run the same job twice), and a no-false-success guard that refuses to report "done" when an action actually failed.
58
+ - **Diagnosable failures** every failed job keeps its full transcript, the real upstream error, and a short, specific reason — propagated up through delegation, never a silent stop.
59
+
60
+ ### 🤝 Agents that actually finish
61
+
62
+ - **Orchestrators that finish** — pick the delegation style per request: route to one specialist and resume on its result, or fan work out to many sub-agents in parallel and compile the answer.
63
+ - **Memory that compounds** persistent facts auto-injected into every job, plus chat-thread continuity (your agent remembers what it said 30 seconds ago — and yesterday).
64
+ - **Self-improving (opt-in)** after a substantial job an agent can reflect and write itself a reusable skill; a weekly curator consolidates and prunes them. Every learned skill is reviewable, assignable, and revocable.
65
+ - **Self-extending ROOT** — designate an orchestrator as ROOT and let it create skills, agents, MCP servers, and connectors on your behalf — gated by per-grant toggles and an autonomy level (propose-confirm → fully-autonomous).
66
+ - **Human-in-the-loop** — risky tools pause for approval, and the prompt leads with the agent's plain-language explanation of *what* it wants to do and *why* (plus any ⚠️ impact) — not a wall of raw shell.
67
+
68
+ ---
69
+
70
+ ## Available now
71
+
72
+ **Models** — Anthropic · OpenAI · Google · Groq · Mistral · OpenRouter · **native DeepSeek** (`api.deepseek.com`) · **native MiniMax** (`api.minimax.io`) · any local model (LM Studio, Ollama). One key per provider; each agent picks its own model.
73
+
74
+ **Connectors** multi-instance (Gmail perso *and* boulot on one install), managed from the dashboard:
75
+ - *OAuth* Gmail · Google Drive · Sheets · Docs · Calendar · Notion · Airtable
76
+ - *API key*Notion · Airtable · Apify · Firecrawl · Tavily
77
+
78
+ **MCP servers** — over Streamable HTTP *and* stdio, plus add/edit your own:
79
+ Stripe · GitHub · Supabase · Notion · Linear · Sentry · n8n · PostgreSQL · Playwright · Perplexity · Apify · Filesystem · Git · Fetch · Sequential Thinking · Composio · Cogni Cortex
80
+
81
+ **Skills** — built-in: office editing (Excel/Word/PowerPoint), shell execution, Obsidian, Telegram etiquette, task planning, markdown output, citation discipline, research methodology, results delivery, language mirroring, HTML design. Plus **install any community `SKILL.md`** from GitHub / skills.sh / ClawHub — and agents can **write their own**.
82
+
83
+ **Channels** Telegram (long-poll, multi-agent routing via `/ask <slug>`, group-chat filters, conversation continuity) and the dashboard chat.
84
+
85
+ **Other** shell execution (`run_command`, approval-gated), per-agent sandboxed filesystem folders, cron automations, tool-call audit log, full job transcripts.
86
+
87
+ ---
88
+
89
+ ## How it works
90
+
91
+ ```
92
+ ┌─────────────┐ Telegram / ┌────────────────────────────────┐
93
+ │ Channel │ Dashboard ───▶ │ Runner (Hono) │
94
+ │ (telegram, │ POST /api ◀── │ • Job queue + executor │
95
+ │ web …) │ │ • Anti-runaway guards │
96
+ └─────────────┘ │ • Per-agent tool whitelist │
97
+ │ • Memory auto-injection │
98
+ │ • Session-thread continuity │
99
+ └────────┬───────────┬───────────┘
100
+ │ │
101
+ ┌──────▼────┐ ┌───▼─────────────┐
102
+ │ LLM │ │ Connectors / │
103
+ │ client │ │ MCP servers │
104
+ │ (multi- │ │ (Gmail, Drive, │
105
+ │ provider) │ │ Notion …) │
106
+ └────────────┘ └─────────────────┘
107
+ ```
108
+
109
+ Every agent is a **row in Postgres** — personality, skills, connectors, memory budget, and team assignments all live in the database. The runtime is generic: **zero hardcoded agent metadata.** Adding a capability means inserting rows, not editing code.
110
+
111
+ A message becomes an `agent_jobs` row. The runner loads the agent's prior chat-thread history, injects relevant memories, dispatches to the LLM, executes the tool calls it emits, and finalizes the reply. Delegations create child jobs that resume the parent on completion.
112
+
113
+ ---
114
+
115
+ ## The dashboard
116
+
117
+ | Route | Purpose |
118
+ | --- | --- |
119
+ | `/agents` | Create + edit agents; assign skills, connectors, MCP servers; pick each agent's provider, model, and failover chain. |
120
+ | `/llm-providers` | Connect each LLM provider with one API key. Models are chosen per-agent. |
121
+ | `/jobs` | Live job stream — task, agent, status, full transcript, tool I/O. |
122
+ | `/connectors` | Active connector instances + Marketplace (multi-instance, OAuth or API key). |
123
+ | `/mcp` | Active MCP servers + Marketplace — HTTP & stdio, plus your own custom servers. |
124
+ | `/memories` | Persistent facts per workspace — search, edit, archive. |
125
+ | `/skills` | Assigned / Custom / Built-in Library — write your own, customise built-ins, or install any community `SKILL.md`. |
126
+ | `/learned-skills` | Skills the agents wrote themselves review, assign, archive, restore. |
127
+ | `/approvals` | Human-in-the-loop gates for risky tools and the ROOT agent's meta-tools. |
128
+ | `/automations` | Cron-scheduled agent triggers. |
129
+ | `/settings` | Auth mode, network (loopback / LAN), bot tokens, workspaces, ROOT grants + autonomy. |
130
+
131
+ ---
132
+
133
+ ## For developers
134
+
135
+ ```bash
136
+ git clone https://github.com/Kwintspiracy/nodal-agents.git
137
+ cd nodal-agents
138
+ pnpm install
139
+ pnpm --filter nodal-agents exec tsx src/index.ts --dev # hot-reloading dashboard
140
+ ```
141
+
142
+ **Stack** Node 22+, TypeScript strict (no `any`), pnpm + Turborepo, embedded-postgres + Drizzle ORM (idempotent migrations), Zod everywhere, Hono (runner) + Next.js (dashboard), the Vercel AI SDK for multi-provider LLM, Vitest + Playwright + dependency-cruiser.
143
+
144
+ **Monorepo**
145
+
146
+ ```
147
+ apps/ cli · runner (Hono) · web (Next.js dashboard)
148
+ packages/ db · shared · llm · tools · memory · orchestration
149
+ adapters · runner-adapters · delivery · auth · catalog · secrets
150
+ ```
151
+
152
+ **Architecture rules** (enforced by `dependency-cruiser`, run in CI before every release):
153
+
154
+ - `apps/*` may import `packages/*` never the reverse.
155
+ - `apps/web` and `apps/runner` cannot import each other (DB or HTTP only).
156
+ - Only `packages/db` may import `postgres` / `drizzle-orm` / `pg`.
157
+ - No circular dependencies.
158
+
159
+ ```bash
160
+ pnpm deps:check
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Status
166
+
167
+ Used daily by the maintainer; stable enough for personal production. **Pre-1.0** breaking changes are still possible between minors.
168
+
169
+ **On the roadmap** (genuine, not vaporware):
170
+
171
+ - **MCP OAuth** → unlocks Linear, Notion remote, GitHub remote, Atlassian, Sentry, and the rest of the SaaS-as-MCP ecosystem.
172
+ - **Dry-run + test-workflow meta-tool** → preview what the ROOT would do before it runs.
173
+ - **Bundled pgvector** → semantic memory search out of the box (today: keyword fallback).
174
+ - **More channels** → Discord, Slack, and beyond Telegram.
175
+
176
+ ---
177
+
178
+ ## Upgrade
179
+
180
+ ```bash
181
+ nodal-agents update # stop, install @latest, restart — data preserved
182
+ nodal-agents update --no-restart
183
+ ```
184
+
185
+ When a newer version is available, `nodal-agents up` prints a one-line notice.
186
+
187
+ ---
188
+
189
+ ## License
190
+
191
+ TBD.
package/cli.js CHANGED
@@ -13041,6 +13041,14 @@ var init_skills = __esm({
13041
13041
  // them unless the owner flips this for a specific agent × skill — the
13042
13042
  // case-by-case execution gate. Loaded by the runner into the ToolContext.
13043
13043
  scriptsAuthorized: boolean("scripts_authorized").notNull().default(false),
13044
+ // Per-skill × per-agent authorization to WRITE files into the skill's bundle
13045
+ // (the install-store dir) via skill_file_write. Owner opt-in, default FALSE.
13046
+ // An agent can always READ its assigned skills' files (skill_file_read), but
13047
+ // it can only modify them — drop a workflow, update a reference — when the
13048
+ // owner flips this for a specific agent × skill. Loaded by the runner into
13049
+ // the ToolContext. Mirrors scriptsAuthorized: a bounded, owner-gated write
13050
+ // path that avoids handing the agent a full shell (command-execution).
13051
+ filesWritable: boolean("files_writable").notNull().default(false),
13044
13052
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
13045
13053
  },
13046
13054
  () => []
@@ -14136,7 +14144,7 @@ async function runUp(opts = {}) {
14136
14144
  console.log(chalk2.gray(" Updated ~/.nodalai/config.json.\n"));
14137
14145
  }
14138
14146
  const webUrl = `http://localhost:${config.ports.web}`;
14139
- const runnerUrl = `http://localhost:${config.ports.runner}`;
14147
+ const runnerUrl = `http://127.0.0.1:${config.ports.runner}`;
14140
14148
  const pgSpinner = ora2("Starting embedded Postgres\u2026").start();
14141
14149
  let pg;
14142
14150
  try {
@@ -0,0 +1 @@
1
+ ALTER TABLE "agent_skill_assignments" ADD COLUMN "files_writable" boolean DEFAULT false NOT NULL;
@@ -337,6 +337,13 @@
337
337
  "when": 1782800000000,
338
338
  "tag": "0048_entities_timezone",
339
339
  "breakpoints": true
340
+ },
341
+ {
342
+ "idx": 49,
343
+ "version": "7",
344
+ "when": 1782900000000,
345
+ "tag": "0049_skill_assignment_files_writable",
346
+ "breakpoints": true
340
347
  }
341
348
  ]
342
349
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodal-agents",
3
- "version": "0.5.5",
3
+ "version": "0.6.0",
4
4
  "description": "Local-first AI agent platform with a web dashboard — install in one command.",
5
5
  "license": "MIT",
6
6
  "repository": {