nodal-agents 0.7.0 → 0.7.2

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 (165) hide show
  1. package/cli.js +335 -35
  2. package/migrations/0054_audit2_db_integrity.sql +52 -0
  3. package/migrations/0055_entity_settings.sql +22 -0
  4. package/migrations/0056_agents_skills_entity_scoped_unique.sql +23 -0
  5. package/migrations/0057_telegram_allowed_chats.sql +34 -0
  6. package/migrations/meta/_journal.json +28 -0
  7. package/package.json +1 -1
  8. package/runner.js +47123 -35332
  9. package/web/.next/BUILD_ID +1 -1
  10. package/web/.next/app-path-routes-manifest.json +4 -4
  11. package/web/.next/build-manifest.json +2 -2
  12. package/web/.next/prerender-manifest.json +3 -3
  13. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +3 -3
  14. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js.nft.json +1 -1
  15. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
  16. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +2 -2
  17. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js.nft.json +1 -1
  18. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
  19. package/web/.next/server/app/(dashboard)/agents/page.js +2 -2
  20. package/web/.next/server/app/(dashboard)/agents/page.js.nft.json +1 -1
  21. package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
  22. package/web/.next/server/app/(dashboard)/approvals/page.js +2 -2
  23. package/web/.next/server/app/(dashboard)/approvals/page.js.nft.json +1 -1
  24. package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
  25. package/web/.next/server/app/(dashboard)/automations/page.js +2 -2
  26. package/web/.next/server/app/(dashboard)/automations/page.js.nft.json +1 -1
  27. package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
  28. package/web/.next/server/app/(dashboard)/chat/page.js +2 -2
  29. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  30. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/connectors/page.js +1 -1
  32. package/web/.next/server/app/(dashboard)/connectors/page.js.nft.json +1 -1
  33. package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
  34. package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
  35. package/web/.next/server/app/(dashboard)/credentials/page.js.nft.json +1 -1
  36. package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
  37. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +2 -2
  38. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js.nft.json +1 -1
  39. package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/jobs/page.js +2 -2
  41. package/web/.next/server/app/(dashboard)/jobs/page.js.nft.json +1 -1
  42. package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/learned-skills/page.js +2 -2
  44. package/web/.next/server/app/(dashboard)/learned-skills/page.js.nft.json +1 -1
  45. package/web/.next/server/app/(dashboard)/learned-skills/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/llm-providers/page.js +1 -1
  47. package/web/.next/server/app/(dashboard)/llm-providers/page.js.nft.json +1 -1
  48. package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/logs/page.js +2 -2
  50. package/web/.next/server/app/(dashboard)/logs/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/mcp/page.js +2 -2
  53. package/web/.next/server/app/(dashboard)/mcp/page.js.nft.json +1 -1
  54. package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/(dashboard)/memories/page.js +2 -2
  56. package/web/.next/server/app/(dashboard)/memories/page.js.nft.json +1 -1
  57. package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
  58. package/web/.next/server/app/(dashboard)/page.js +2 -2
  59. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  60. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/settings/page.js +2 -2
  62. package/web/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/settings/root-context/page.js +2 -2
  65. package/web/.next/server/app/(dashboard)/settings/root-context/page.js.nft.json +1 -1
  66. package/web/.next/server/app/(dashboard)/settings/root-context/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +2 -2
  68. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js.nft.json +1 -1
  69. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/(dashboard)/skills/new/page.js +2 -2
  71. package/web/.next/server/app/(dashboard)/skills/new/page.js.nft.json +1 -1
  72. package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/skills/page.js +2 -2
  74. package/web/.next/server/app/(dashboard)/skills/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  77. package/web/.next/server/app/_global-error.html +1 -1
  78. package/web/.next/server/app/_global-error.rsc +2 -2
  79. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  80. package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  81. package/web/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  82. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  83. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +2 -2
  84. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  85. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  86. package/web/.next/server/app/_not-found.html +1 -1
  87. package/web/.next/server/app/_not-found.rsc +3 -3
  88. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  89. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  90. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  91. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  92. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  93. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  94. package/web/.next/server/app/api/auth/[...all]/route.js +1 -1
  95. package/web/.next/server/app/api/auth/[...all]/route.js.nft.json +1 -1
  96. package/web/.next/server/app/api/oauth/[provider]/callback/route.js +1 -1
  97. package/web/.next/server/app/api/oauth/[provider]/callback/route.js.nft.json +1 -1
  98. package/web/.next/server/app/api/oauth/[provider]/start/route.js +1 -1
  99. package/web/.next/server/app/api/oauth/[provider]/start/route.js.nft.json +1 -1
  100. package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/onboarding/page.js +205 -185
  102. package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/app-paths-manifest.json +4 -4
  104. package/web/.next/server/chunks/2713.js +47 -27
  105. package/web/.next/server/chunks/3223.js +1 -1
  106. package/web/.next/server/chunks/4574.js +1 -1
  107. package/web/.next/server/chunks/5515.js +1 -0
  108. package/web/.next/server/chunks/6468.js +1 -0
  109. package/web/.next/server/chunks/8410.js +1 -0
  110. package/web/.next/server/chunks/{4488.js → 8810.js} +2 -2
  111. package/web/.next/server/chunks/{3154.js → 960.js} +10 -10
  112. package/web/.next/server/middleware-build-manifest.js +1 -1
  113. package/web/.next/server/pages/404.html +1 -1
  114. package/web/.next/server/pages/500.html +1 -1
  115. package/web/.next/server/server-reference-manifest.js +1 -1
  116. package/web/.next/server/server-reference-manifest.json +1 -1
  117. package/web/.next/static/chunks/4964-c6711d3d479b6085.js +1 -0
  118. package/web/.next/static/chunks/{9836-6830cb9d49ad261f.js → 9836-177f6ca2f15ff703.js} +1 -1
  119. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-cfce874f4acede5e.js +6 -0
  120. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/telegram/page-9249c2839f551ba1.js +1 -0
  121. package/web/.next/static/chunks/app/(dashboard)/agents/page-7d784d737acedccf.js +1 -0
  122. package/web/.next/static/chunks/app/(dashboard)/approvals/{page-9a01cb723a6ccff0.js → page-b3a838ecbc94a030.js} +1 -1
  123. package/web/.next/static/chunks/app/(dashboard)/automations/page-b1b548de4f52696c.js +1 -0
  124. package/web/.next/static/chunks/app/(dashboard)/chat/{page-a6cc7a58986c0340.js → page-bcf6dcc73b370eb0.js} +1 -1
  125. package/web/.next/static/chunks/app/(dashboard)/connectors/{page-21d6c042800c8cd3.js → page-2c6f913cc6aea4b7.js} +1 -1
  126. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-43f033251eddcc4b.js +1 -0
  127. package/web/.next/static/chunks/app/(dashboard)/jobs/page-1f892f950bb30403.js +1 -0
  128. package/web/.next/static/chunks/app/(dashboard)/layout-e184673151ff8a05.js +1 -0
  129. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-f873bb6f8539e47e.js +1 -0
  130. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-64adda30176f4ccb.js +1 -0
  131. package/web/.next/static/chunks/app/(dashboard)/logs/page-79cfd9141c39d8ef.js +1 -0
  132. package/web/.next/static/chunks/app/(dashboard)/mcp/page-d276d7bab25286a1.js +1 -0
  133. package/web/.next/static/chunks/app/(dashboard)/memories/page-c66720494a340503.js +1 -0
  134. package/web/.next/static/chunks/app/(dashboard)/page-3649204dd27a0ad0.js +1 -0
  135. package/web/.next/static/chunks/app/(dashboard)/settings/page-1cab404d2eccfd80.js +1 -0
  136. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-b5898c5444f88c9a.js +1 -0
  137. package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/page-82d91fc6b6acc161.js +1 -0
  138. package/web/.next/static/chunks/app/(dashboard)/skills/new/page-58b5ed04583ca7d4.js +1 -0
  139. package/web/.next/static/chunks/app/(dashboard)/skills/page-312bd4ae8ddc8114.js +1 -0
  140. package/web/.next/static/chunks/app/onboarding/{page-a4116e2f430eaff8.js → page-f2f04878e81fdf23.js} +2 -2
  141. package/web/.next/static/css/{eff119dd24f92093.css → 4d808b91d7b58fce.css} +1 -1
  142. package/web/.next/server/chunks/4626.js +0 -1
  143. package/web/.next/server/chunks/8971.js +0 -1
  144. package/web/.next/server/chunks/9043.js +0 -1
  145. package/web/.next/static/chunks/4964-08171c654e41b0a4.js +0 -1
  146. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-fa5717f0d0450659.js +0 -6
  147. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/telegram/page-73012222871598aa.js +0 -1
  148. package/web/.next/static/chunks/app/(dashboard)/agents/page-7e9616b28c098e9e.js +0 -1
  149. package/web/.next/static/chunks/app/(dashboard)/automations/page-85c985cd687406ed.js +0 -1
  150. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-f6b993a88c70a2fe.js +0 -1
  151. package/web/.next/static/chunks/app/(dashboard)/jobs/page-d0d6b9db1b68451f.js +0 -1
  152. package/web/.next/static/chunks/app/(dashboard)/layout-d2ac2646967496bb.js +0 -1
  153. package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-ec6312f6dfd7ee23.js +0 -1
  154. package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-1fb26463eddf509c.js +0 -1
  155. package/web/.next/static/chunks/app/(dashboard)/logs/page-0bca733315e8a208.js +0 -1
  156. package/web/.next/static/chunks/app/(dashboard)/mcp/page-ff56ecf2f65f5466.js +0 -1
  157. package/web/.next/static/chunks/app/(dashboard)/memories/page-fe4d9438c93750d6.js +0 -1
  158. package/web/.next/static/chunks/app/(dashboard)/page-9402fe2931216f4b.js +0 -1
  159. package/web/.next/static/chunks/app/(dashboard)/settings/page-995662f10ebff365.js +0 -1
  160. package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-785b6ce3e4c5890b.js +0 -1
  161. package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/page-2106201c4df8b5a4.js +0 -1
  162. package/web/.next/static/chunks/app/(dashboard)/skills/new/page-0135bcb86ab60dc2.js +0 -1
  163. package/web/.next/static/chunks/app/(dashboard)/skills/page-54e939d40c8b5b6d.js +0 -1
  164. /package/web/.next/static/{KFac7DQ7gdp9XPQ2bnb-2 → SgnP_MouhUmw0bBf-lUmD}/_buildManifest.js +0 -0
  165. /package/web/.next/static/{KFac7DQ7gdp9XPQ2bnb-2 → SgnP_MouhUmw0bBf-lUmD}/_ssgManifest.js +0 -0
@@ -0,0 +1,52 @@
1
+ -- Dedup pass (audit#2 follow-up): these six tables never had the UNIQUE
2
+ -- constraints below, and their pre-fix write paths were check-then-insert
3
+ -- (raceable) — so an upgraded install may already carry duplicate rows. A bare
4
+ -- ADD CONSTRAINT / CREATE UNIQUE INDEX validates existing rows and aborts the
5
+ -- whole migration (Postgres 23505) if any duplicate exists, bricking `up` with
6
+ -- no recovery. Follow migration 0007's precedent: collapse each duplicate group
7
+ -- to a single survivor BEFORE adding the constraint. Survivor = most recently
8
+ -- updated/created row (id as final, always-unique tiebreaker); COALESCE guards
9
+ -- NULL timestamps; IS NOT DISTINCT FROM matches the NULLS NOT DISTINCT semantics
10
+ -- of the entity_id keys. On a clean install (no duplicates) every DELETE is a
11
+ -- no-op.
12
+ DELETE FROM "approval_rules" a USING "approval_rules" b
13
+ WHERE a."id" <> b."id"
14
+ AND a."entity_id" IS NOT DISTINCT FROM b."entity_id"
15
+ AND a."agent_id" IS NOT DISTINCT FROM b."agent_id"
16
+ AND a."tool_name" = b."tool_name"
17
+ AND (COALESCE(a."updated_at", 'epoch'::timestamptz) < COALESCE(b."updated_at", 'epoch'::timestamptz)
18
+ OR (COALESCE(a."updated_at", 'epoch'::timestamptz) = COALESCE(b."updated_at", 'epoch'::timestamptz) AND a."id" < b."id"));--> statement-breakpoint
19
+ DELETE FROM "agent_skill_assignments" a USING "agent_skill_assignments" b
20
+ WHERE a."agent_id" = b."agent_id"
21
+ AND a."skill_id" = b."skill_id"
22
+ AND a."id" < b."id";--> statement-breakpoint
23
+ DELETE FROM "agent_assignments" a USING "agent_assignments" b
24
+ WHERE a."orchestrator_id" = b."orchestrator_id"
25
+ AND a."sub_agent_id" = b."sub_agent_id"
26
+ AND (COALESCE(a."created_at", 'epoch'::timestamptz) < COALESCE(b."created_at", 'epoch'::timestamptz)
27
+ OR (COALESCE(a."created_at", 'epoch'::timestamptz) = COALESCE(b."created_at", 'epoch'::timestamptz) AND a."id" < b."id"));--> statement-breakpoint
28
+ DELETE FROM "agent_plugins" a USING "agent_plugins" b
29
+ WHERE a."id" <> b."id"
30
+ AND a."entity_id" IS NOT DISTINCT FROM b."entity_id"
31
+ AND a."slug" = b."slug"
32
+ AND (COALESCE(a."updated_at", 'epoch'::timestamptz) < COALESCE(b."updated_at", 'epoch'::timestamptz)
33
+ OR (COALESCE(a."updated_at", 'epoch'::timestamptz) = COALESCE(b."updated_at", 'epoch'::timestamptz) AND a."id" < b."id"));--> statement-breakpoint
34
+ DELETE FROM "mcp_connections" a USING "mcp_connections" b
35
+ WHERE a."entity_id" = b."entity_id"
36
+ AND a."slug" = b."slug"
37
+ AND (COALESCE(a."updated_at", 'epoch'::timestamptz) < COALESCE(b."updated_at", 'epoch'::timestamptz)
38
+ OR (COALESCE(a."updated_at", 'epoch'::timestamptz) = COALESCE(b."updated_at", 'epoch'::timestamptz) AND a."id" < b."id"));--> statement-breakpoint
39
+ DELETE FROM "entity_members" a USING "entity_members" b
40
+ WHERE a."entity_id" = b."entity_id"
41
+ AND a."user_id" = b."user_id"
42
+ AND (COALESCE(a."created_at", 'epoch'::timestamptz) < COALESCE(b."created_at", 'epoch'::timestamptz)
43
+ OR (COALESCE(a."created_at", 'epoch'::timestamptz) = COALESCE(b."created_at", 'epoch'::timestamptz) AND a."id" < b."id"));--> statement-breakpoint
44
+ ALTER TABLE "approval_rules" ADD CONSTRAINT "approval_rules_entity_agent_tool_unique" UNIQUE NULLS NOT DISTINCT("entity_id","agent_id","tool_name");--> statement-breakpoint
45
+ ALTER TABLE "agent_skill_assignments" ADD CONSTRAINT "agent_skill_assignments_agent_skill_unique" UNIQUE("agent_id","skill_id");--> statement-breakpoint
46
+ ALTER TABLE "agent_assignments" ADD CONSTRAINT "agent_assignments_orchestrator_sub_agent_unique" UNIQUE("orchestrator_id","sub_agent_id");--> statement-breakpoint
47
+ CREATE INDEX "idx_agent_tasks_root_job_id" ON "agent_tasks" USING btree ("root_job_id");--> statement-breakpoint
48
+ CREATE INDEX "idx_agent_jobs_completed_at_null" ON "agent_jobs" USING btree ("completed_at") WHERE "completed_at" IS NULL;--> statement-breakpoint
49
+ DROP INDEX "idx_jobs_parent";--> statement-breakpoint
50
+ ALTER TABLE "agent_plugins" ADD CONSTRAINT "agent_plugins_entity_slug_unique" UNIQUE NULLS NOT DISTINCT("entity_id","slug");--> statement-breakpoint
51
+ CREATE UNIQUE INDEX "mcp_connections_entity_slug_unique" ON "mcp_connections" USING btree ("entity_id","slug");--> statement-breakpoint
52
+ CREATE UNIQUE INDEX "entity_members_entity_user_unique" ON "entity_members" USING btree ("entity_id","user_id");
@@ -0,0 +1,22 @@
1
+ CREATE TABLE "entity_settings" (
2
+ "entity_id" uuid NOT NULL,
3
+ "key" text NOT NULL,
4
+ "value" text DEFAULT '' NOT NULL,
5
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
6
+ CONSTRAINT "entity_settings_entity_id_key_pk" PRIMARY KEY("entity_id","key")
7
+ );
8
+ --> statement-breakpoint
9
+ ALTER TABLE "entity_settings" ADD CONSTRAINT "entity_settings_entity_id_entities_id_fk" FOREIGN KEY ("entity_id") REFERENCES "entities"("id") ON DELETE cascade ON UPDATE no action;
10
+ --> statement-breakpoint
11
+ -- M-2 (audit #2): install_notes used to be one machine-global row injected
12
+ -- into EVERY entity's agents — the opposite of isolation. Backfill preserves
13
+ -- current behaviour for existing installs (the note was already visible
14
+ -- everywhere) by copying it to every existing entity as its own row; going
15
+ -- forward each entity's notes are independent and owner-gated per entity
16
+ -- (see setInstallNotesAction in apps/web).
17
+ INSERT INTO "entity_settings" ("entity_id", "key", "value")
18
+ SELECT "entities"."id", 'install_notes', "app_settings"."value"
19
+ FROM "entities", "app_settings"
20
+ WHERE "app_settings"."key" = 'install_notes' AND "app_settings"."value" <> '';
21
+ --> statement-breakpoint
22
+ DELETE FROM "app_settings" WHERE "key" = 'install_notes';
@@ -0,0 +1,23 @@
1
+ -- F-6 (audit #2): agents.slug and agent_skills.slug/name were UNIQUE
2
+ -- GLOBALLY across the whole install. Consequences: (a) a 2nd entity/
3
+ -- workspace installing the same community skill (e.g. slug 'comfyui') or
4
+ -- creating an agent/skill that happens to share a slug or name with another
5
+ -- entity's crashed the insert outright; (b) in multi-user mode, slug/name
6
+ -- collisions let one entity enumerate or squat another's identifiers.
7
+ --
8
+ -- Fix: drop the global unique constraints and replace them with composite
9
+ -- (entity_id, slug) / (entity_id, name) uniques, NULLS NOT DISTINCT (same
10
+ -- pattern as 0000's agent_plugins_entity_slug_unique / approval_rules —
11
+ -- entity_id is nullable in both tables, and a plain UNIQUE treats every NULL
12
+ -- as distinct, which would let multiple (NULL, 'x') rows back in).
13
+ --
14
+ -- Safe to apply: the OLD global unique constraints made it structurally
15
+ -- impossible for two existing rows to already share a (entity_id, slug) or
16
+ -- (entity_id, name) pair, so the new composite constraints cannot fail on
17
+ -- current data.
18
+ ALTER TABLE "agents" DROP CONSTRAINT "agents_slug_unique";--> statement-breakpoint
19
+ ALTER TABLE "agent_skills" DROP CONSTRAINT "agent_skills_slug_unique";--> statement-breakpoint
20
+ ALTER TABLE "agent_skills" DROP CONSTRAINT "agent_skills_name_unique";--> statement-breakpoint
21
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_entity_slug_unique" UNIQUE NULLS NOT DISTINCT("entity_id","slug");--> statement-breakpoint
22
+ ALTER TABLE "agent_skills" ADD CONSTRAINT "agent_skills_entity_slug_unique" UNIQUE NULLS NOT DISTINCT("entity_id","slug");--> statement-breakpoint
23
+ ALTER TABLE "agent_skills" ADD CONSTRAINT "agent_skills_entity_name_unique" UNIQUE NULLS NOT DISTINCT("entity_id","name");
@@ -0,0 +1,34 @@
1
+ CREATE TABLE "telegram_allowed_chats" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "entity_id" uuid,
4
+ "agent_id" uuid NOT NULL,
5
+ "chat_id" text NOT NULL,
6
+ "role" text DEFAULT 'member' NOT NULL,
7
+ "status" text DEFAULT 'pending' NOT NULL,
8
+ "requester_name" text,
9
+ "created_at" timestamp with time zone DEFAULT now(),
10
+ "updated_at" timestamp with time zone DEFAULT now(),
11
+ CONSTRAINT "telegram_allowed_chats_agent_chat_unique" UNIQUE("agent_id","chat_id"),
12
+ CONSTRAINT "telegram_allowed_chats_role_check" CHECK ("telegram_allowed_chats"."role" IN ('owner','member')),
13
+ CONSTRAINT "telegram_allowed_chats_status_check" CHECK ("telegram_allowed_chats"."status" IN ('active','pending'))
14
+ );
15
+ --> statement-breakpoint
16
+ ALTER TABLE "telegram_allowed_chats" ADD CONSTRAINT "telegram_allowed_chats_entity_id_entities_id_fk" FOREIGN KEY ("entity_id") REFERENCES "entities"("id") ON DELETE cascade ON UPDATE no action;
17
+ --> statement-breakpoint
18
+ ALTER TABLE "telegram_allowed_chats" ADD CONSTRAINT "telegram_allowed_chats_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "agents"("id") ON DELETE cascade ON UPDATE no action;
19
+ --> statement-breakpoint
20
+ CREATE INDEX "idx_telegram_allowed_chats_agent" ON "telegram_allowed_chats" ("agent_id");
21
+ --> statement-breakpoint
22
+ CREATE INDEX "idx_telegram_allowed_chats_entity" ON "telegram_allowed_chats" ("entity_id");
23
+ --> statement-breakpoint
24
+ -- H-1: seed the OWNER for every bot that already has a known chat, so existing
25
+ -- installs are not locked out AND a stranger can't claim ownership of a bot the
26
+ -- real user was already using. The last chat that talked to each configured bot
27
+ -- becomes its active owner. New bots (no prior chat) claim their owner on the
28
+ -- first DM instead. NULLS-safe and idempotent (unique(agent_id,chat_id)).
29
+ INSERT INTO "telegram_allowed_chats" ("entity_id", "agent_id", "chat_id", "role", "status")
30
+ SELECT "entity_id", "id", "last_seen_chat_id_telegram", 'owner', 'active'
31
+ FROM "agents"
32
+ WHERE "last_seen_chat_id_telegram" IS NOT NULL
33
+ AND "telegram_bot_token" IS NOT NULL
34
+ ON CONFLICT ("agent_id","chat_id") DO NOTHING;
@@ -372,6 +372,34 @@
372
372
  "when": 1783300000000,
373
373
  "tag": "0053_memory_importance_locked",
374
374
  "breakpoints": true
375
+ },
376
+ {
377
+ "idx": 54,
378
+ "version": "7",
379
+ "when": 1783400000000,
380
+ "tag": "0054_audit2_db_integrity",
381
+ "breakpoints": true
382
+ },
383
+ {
384
+ "idx": 55,
385
+ "version": "7",
386
+ "when": 1783500000000,
387
+ "tag": "0055_entity_settings",
388
+ "breakpoints": true
389
+ },
390
+ {
391
+ "idx": 56,
392
+ "version": "7",
393
+ "when": 1783600000000,
394
+ "tag": "0056_agents_skills_entity_scoped_unique",
395
+ "breakpoints": true
396
+ },
397
+ {
398
+ "idx": 57,
399
+ "version": "7",
400
+ "when": 1783700000000,
401
+ "tag": "0057_telegram_allowed_chats",
402
+ "breakpoints": true
375
403
  }
376
404
  ]
377
405
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodal-agents",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Local-first AI agent platform with a web dashboard — install in one command.",
5
5
  "license": "MIT",
6
6
  "repository": {