@checkstack/dependency-backend 1.3.0 → 1.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # @checkstack/dependency-backend
2
2
 
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9dcc848: Plugin-owned AI tools: every domain plugin contributes its own AI tools (chat assistant + automation AI action), and `ai-backend` is platform-only.
8
+
9
+ Every plugin-specific AI tool is owned by the plugin whose domain it acts on, registered via that plugin's own `aiToolExtensionPoint` / `aiToolProjectionExtensionPoint` from its init - the same path an external plugin author uses. `ai-backend` no longer imports or depends on any capability plugin's `*-common`; the dependency direction is strictly plugin -> ai-platform. Pure helpers (`computeFieldDiff`, capability-summary, `ScriptContextKind`) live in `@checkstack/ai-common`.
10
+
11
+ Tools shipped:
12
+
13
+ - Health checks and automations: full CRUD - `healthcheck.propose` / `automation.propose` and `*.update` (`mutate`, deep-validated) and `*.delete` (`destructive`, always confirm-gated). `healthcheck.propose`'s dry-run calls the new deep `validateConfiguration` so propose-time validation matches apply-time. Assertions are validated against the collector's result schema and the canonical operator vocabulary. Capability-catalog tools (`ai.listCapabilities`, `ai.getCapabilitySchema`), script context tools (`ai.getScriptContext`, `ai.testScript`), and notify-subscriber tools (`healthcheck.notifySystemSubscribers` / `...GroupSubscribers`).
14
+ - Catalog: `catalog.createSystem` / `updateSystem` / `createGroup` / `updateGroup` (`mutate`), `catalog.deleteSystem` / `deleteGroup` (`destructive`), membership tools (`mutate`), plus `catalog.listSystems` / `listGroups` read projections.
15
+ - Incident: `incident.create` / `update` / `addUpdate` / `resolve` / `addLink` (`mutate`), `incident.delete` / `removeLink` (`destructive`), and `incident.get` / `incident.list` read projections.
16
+ - Maintenance: `maintenance.create` / `update` / `addUpdate` / `close` / `addLink` (`mutate`), `maintenance.delete` / `removeLink` (`destructive`), and `maintenance.list` / `get` read projections.
17
+ - Read projections for SLO (`slo.listObjectives`), dependency (`dependency.list`), incident (`incident.list`), healthcheck (`healthcheck.status`), and anomaly (`anomaly.explain`), each gated by the source procedure's own access rule and routed as the principal.
18
+ - Documentation grounding: `ai.searchDocs` / `ai.getDoc` over a build-time bundled docs index (BM25-ish ranking), so the assistant grounds how-to answers in Checkstack's own docs offline.
19
+ - URL introspection: `ai.probeUrl`, an SSRF-guarded read tool the assistant uses to inspect a real endpoint before drafting a health check. Update tools compute a before -> after field diff rendered on the confirm card (approve mode) or an "Applied" card (auto mode), so a change is never silent.
20
+
21
+ `ai_analyze` automation action (automation-backend, with an editor connection picker + audited tool calls): runs a bounded AI agent on the run context as the automation's `runAs` service account, so it can never exceed that identity's permissions; destructive tools are never offered; mutating tools auto-apply through the service account's client. Produces an `automation.analysis` artifact downstream actions can branch on. The agent loop is exposed as a headless `aiAgentRunnerRef` service so automation-backend can drive it without depending on ai-backend.
22
+
23
+ `notification.notifyForSubscription` is now callable by user / application principals holding `notification.send` (previously service-only). Every tool routes through the user-scoped client, so handler-side authorization is enforced exactly as a direct UI/RPC action; the resolver gate plus the propose/apply re-check at propose AND apply are the additional authority. A systemic authz regression test asserts every registered tool falls into exactly one safe authorization category.
24
+
25
+ A new `ai_transport` enum value `automation` records the AI action's tool calls in the `ai_tool_calls` audit log. No new durable state beyond that; each tool is a thin, deterministic wrapper over an existing RPC, so every pod behaves identically.
26
+
27
+ This is a beta minor.
28
+
29
+ - 9dcc848: Align workspace dependency versions and migrate React Router to v7.
30
+
31
+ BREAKING CHANGES (React Router v7): All frontend packages now depend on `react-router-dom@^7.16.0`. Previously the workspace declared four divergent ranges (`^6.20.0`, `^6.22.0`, `^7.1.1`, `^7.14.2`), which resolved both `react-router@6` and `react-router@7` into a single bundle. Everything is now unified on v7. The public imports the app uses (`BrowserRouter`, `Routes`, `Route`, `Link`, `NavLink`, `MemoryRouter`, `useNavigate`, `useParams`, `useSearchParams`, `useLocation`) are unchanged between v6 and v7, so no source rewrites were required - but any out-of-tree plugin still on react-router v6 should upgrade to v7 (see the React Router v6 -> v7 upgrade guide) to share the host's single router instance via the import map.
32
+
33
+ Other unified ranges (no API change): `react` -> `^18.3.1`, the `@orpc/*` family (`contract`, `server`, `client`, `tanstack-query`, `openapi`, `zod`) -> `^1.14.4`, and `better-auth` -> `^1.6.13`.
34
+
35
+ Removed the pre-rename `@orpc/react-query` leftover from `@checkstack/frontend-api`; its `createRouterUtils` / `RouterUtils` / `ProcedureUtils` now come from `@orpc/tanstack-query` (the package already in use).
36
+
37
+ Stale in-range runtime deps pulled up to current published versions: `hono` `^4.12.23`, `@tanstack/react-query` (+devtools) `^5.100.14`, `date-fns` `^4.4.0`, `jose` `^6.2.3`, `tar` `^7.5.16`, `semver` `^7.8.1`, `@xyflow/react` `^12.11.0`.
38
+
39
+ ### Patch Changes
40
+
41
+ - Updated dependencies [9dcc848]
42
+ - Updated dependencies [9dcc848]
43
+ - Updated dependencies [9dcc848]
44
+ - Updated dependencies [9dcc848]
45
+ - Updated dependencies [9dcc848]
46
+ - Updated dependencies [9dcc848]
47
+ - Updated dependencies [9dcc848]
48
+ - Updated dependencies [9dcc848]
49
+ - Updated dependencies [9dcc848]
50
+ - Updated dependencies [9dcc848]
51
+ - Updated dependencies [9dcc848]
52
+ - Updated dependencies [9dcc848]
53
+ - Updated dependencies [9dcc848]
54
+ - Updated dependencies [9dcc848]
55
+ - Updated dependencies [9dcc848]
56
+ - Updated dependencies [9dcc848]
57
+ - Updated dependencies [9dcc848]
58
+ - Updated dependencies [9dcc848]
59
+ - @checkstack/ai-backend@0.1.0
60
+ - @checkstack/backend-api@0.21.0
61
+ - @checkstack/healthcheck-backend@1.6.0
62
+ - @checkstack/healthcheck-common@1.5.0
63
+ - @checkstack/automation-backend@0.5.0
64
+ - @checkstack/catalog-backend@1.4.0
65
+ - @checkstack/notification-common@1.3.0
66
+ - @checkstack/catalog-common@2.3.0
67
+ - @checkstack/common@0.13.0
68
+ - @checkstack/dependency-common@1.2.0
69
+ - @checkstack/gitops-backend@0.5.0
70
+ - @checkstack/gitops-common@0.6.0
71
+ - @checkstack/incident-common@1.4.0
72
+ - @checkstack/maintenance-common@1.4.0
73
+ - @checkstack/signal-common@0.2.6
74
+
75
+ ## 1.3.1
76
+
77
+ ### Patch Changes
78
+
79
+ - Updated dependencies [a57f7db]
80
+ - Updated dependencies [0d9e5d8]
81
+ - @checkstack/backend-api@0.20.0
82
+ - @checkstack/healthcheck-backend@1.5.0
83
+ - @checkstack/automation-backend@0.4.0
84
+ - @checkstack/catalog-backend@1.3.1
85
+ - @checkstack/gitops-backend@0.4.1
86
+
3
87
  ## 1.3.0
4
88
 
5
89
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/dependency-backend",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "license": "Elastic-2.0",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -15,28 +15,30 @@
15
15
  "test": "bun test"
16
16
  },
17
17
  "dependencies": {
18
- "@checkstack/backend-api": "0.18.0",
19
- "@checkstack/automation-backend": "0.2.0",
18
+ "@checkstack/backend-api": "0.20.0",
19
+ "@checkstack/ai-backend": "0.0.0",
20
+ "@checkstack/automation-backend": "0.4.0",
20
21
  "@checkstack/dependency-common": "1.1.3",
21
22
  "@checkstack/catalog-common": "2.2.3",
22
- "@checkstack/catalog-backend": "1.2.0",
23
- "@checkstack/healthcheck-common": "1.3.0",
24
- "@checkstack/healthcheck-backend": "1.3.0",
25
- "@checkstack/maintenance-common": "1.2.3",
23
+ "@checkstack/catalog-backend": "1.3.1",
24
+ "@checkstack/healthcheck-common": "1.4.0",
25
+ "@checkstack/healthcheck-backend": "1.5.0",
26
+ "@checkstack/maintenance-common": "1.3.0",
26
27
  "@checkstack/incident-common": "1.3.1",
27
28
  "@checkstack/notification-common": "1.2.1",
28
29
  "@checkstack/signal-common": "0.2.5",
29
- "@checkstack/gitops-backend": "0.3.7",
30
- "@checkstack/gitops-common": "0.4.2",
30
+ "@checkstack/gitops-backend": "0.4.1",
31
+ "@checkstack/gitops-common": "0.5.0",
31
32
  "@checkstack/common": "0.12.0",
32
33
  "drizzle-orm": "^0.45.0",
33
34
  "zod": "^4.2.1",
34
- "@orpc/server": "^1.13.2"
35
+ "@orpc/contract": "^1.14.4",
36
+ "@orpc/server": "^1.14.4"
35
37
  },
36
38
  "devDependencies": {
37
39
  "@checkstack/drizzle-helper": "0.0.5",
38
40
  "@checkstack/scripts": "0.3.4",
39
- "@checkstack/test-utils-backend": "0.1.31",
41
+ "@checkstack/test-utils-backend": "0.1.33",
40
42
  "@checkstack/tsconfig": "0.0.7",
41
43
  "@types/bun": "^1.0.0",
42
44
  "drizzle-kit": "^0.31.10",
@@ -0,0 +1,39 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import {
3
+ buildProjectedTool,
4
+ deferredProjectionExecute,
5
+ } from "@checkstack/ai-backend";
6
+ import {
7
+ dependencyContract,
8
+ pluginMetadata,
9
+ } from "@checkstack/dependency-common";
10
+
11
+ // Build the projected tool with the SAME inputs the plugin exposes via
12
+ // aiToolProjectionExtensionPoint in `index.ts`, and assert the resulting tool
13
+ // carries the source procedure's contract access rules - NOT the chat
14
+ // transport's `ai.chat.read` gate.
15
+ describe("dependency.list projection", () => {
16
+ const tool = buildProjectedTool({
17
+ procedure: dependencyContract.getAllDependencies,
18
+ sourcePluginMetadata: pluginMetadata,
19
+ procedureKey: "getAllDependencies",
20
+ name: "dependency.list",
21
+ description:
22
+ "List all cross-system dependencies (the dependency graph). Read-only.",
23
+ effect: "read",
24
+ execute: deferredProjectionExecute,
25
+ });
26
+
27
+ test("uses the overridden tool name", () => {
28
+ expect(tool.name).toBe("dependency.list");
29
+ });
30
+
31
+ test("is classified as a read-only effect", () => {
32
+ expect(tool.effect).toBe("read");
33
+ });
34
+
35
+ test("inherits the source procedure's qualified read access rule", () => {
36
+ // qualifyAccessRuleId: `${pluginId}.${rule.id}` where rule.id = `dependency.read`.
37
+ expect(tool.requiredAccessRules).toEqual(["dependency.dependency.read"]);
38
+ });
39
+ });
@@ -2,7 +2,7 @@
2
2
  * Behaviour tests for the dependency automation triggers + actions.
3
3
  */
4
4
  import { describe, expect, it, mock } from "bun:test";
5
- import type { Logger } from "@checkstack/backend-api";
5
+ import type { Logger, RpcClient } from "@checkstack/backend-api";
6
6
  import { createMockLogger } from "@checkstack/test-utils-backend";
7
7
 
8
8
  import {
@@ -26,6 +26,7 @@ const ctxBase = {
26
26
  getService: async <T,>(): Promise<T> => {
27
27
  throw new Error("not used");
28
28
  },
29
+ rpcClient: { forPlugin: () => ({}) } as unknown as RpcClient,
29
30
  };
30
31
 
31
32
  describe("dependency triggers", () => {
package/src/index.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import * as schema from "./schema";
2
2
  import type { SafeDatabase } from "@checkstack/backend-api";
3
+ import {
4
+ aiToolProjectionExtensionPoint,
5
+ deferredProjectionExecute,
6
+ } from "@checkstack/ai-backend";
3
7
  import {
4
8
  dependencyAccessRules,
5
9
  pluginMetadata,
@@ -128,6 +132,20 @@ export default createBackendPlugin({
128
132
  },
129
133
  });
130
134
 
135
+ // Expose this plugin's read-only AI projection (`dependency.list`) via
136
+ // the AI projection extension point. ai-backend collects its routing in
137
+ // afterPluginsReady and never imports dependency-common.
138
+ env.getExtensionPoint(aiToolProjectionExtensionPoint).expose({
139
+ procedure: dependencyContract.getAllDependencies,
140
+ sourcePluginMetadata: pluginMetadata,
141
+ procedureKey: "getAllDependencies",
142
+ name: "dependency.list",
143
+ description:
144
+ "List all cross-system dependencies (the dependency graph). Read-only.",
145
+ effect: "read",
146
+ execute: deferredProjectionExecute,
147
+ });
148
+
131
149
  env.registerInit({
132
150
  schema,
133
151
  deps: {
package/tsconfig.json CHANGED
@@ -4,6 +4,9 @@
4
4
  "src"
5
5
  ],
6
6
  "references": [
7
+ {
8
+ "path": "../ai-backend"
9
+ },
7
10
  {
8
11
  "path": "../automation-backend"
9
12
  },