@weave-kit/engine 1.2.0 → 1.3.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 +17 -0
- package/README.md +210 -210
- package/dist/adapters/mcp/approvals.d.ts +5 -0
- package/dist/adapters/mcp/approvals.d.ts.map +1 -0
- package/dist/adapters/mcp/approvals.js +69 -0
- package/dist/adapters/mcp/approvals.js.map +1 -0
- package/dist/adapters/mcp/generate.d.ts.map +1 -1
- package/dist/adapters/mcp/generate.js +50 -1
- package/dist/adapters/mcp/generate.js.map +1 -1
- package/dist/adapters/mcp/http.d.ts.map +1 -1
- package/dist/adapters/mcp/http.js +25 -2
- package/dist/adapters/mcp/http.js.map +1 -1
- package/dist/adapters/mcp/index.d.ts +6 -0
- package/dist/adapters/mcp/index.d.ts.map +1 -1
- package/dist/adapters/mcp/index.js.map +1 -1
- package/dist/adapters/mcp/resources.d.ts +37 -0
- package/dist/adapters/mcp/resources.d.ts.map +1 -0
- package/dist/adapters/mcp/resources.js +51 -0
- package/dist/adapters/mcp/resources.js.map +1 -0
- package/dist/adapters/mcp/tools.d.ts +5 -0
- package/dist/adapters/mcp/tools.d.ts.map +1 -1
- package/dist/adapters/mcp/tools.js +3 -3
- package/dist/adapters/mcp/tools.js.map +1 -1
- package/dist/adapters/mcp/types.d.ts +9 -1
- package/dist/adapters/mcp/types.d.ts.map +1 -1
- package/dist/adapters/mcp/types.js.map +1 -1
- package/dist/cli/commands/workflow-migrate.d.ts +11 -0
- package/dist/cli/commands/workflow-migrate.d.ts.map +1 -0
- package/dist/cli/commands/workflow-migrate.js +120 -0
- package/dist/cli/commands/workflow-migrate.js.map +1 -0
- package/dist/core/formula/evaluate.d.ts.map +1 -1
- package/dist/core/formula/evaluate.js +55 -0
- package/dist/core/formula/evaluate.js.map +1 -1
- package/dist/core/formula/validate.d.ts.map +1 -1
- package/dist/core/formula/validate.js +44 -0
- package/dist/core/formula/validate.js.map +1 -1
- package/dist/core/formula/values.d.ts +11 -0
- package/dist/core/formula/values.d.ts.map +1 -1
- package/dist/core/formula/values.js +14 -0
- package/dist/core/formula/values.js.map +1 -1
- package/dist/core/rbac/rowScope.js +6 -6
- package/dist/core/tools/values.d.ts +11 -0
- package/dist/core/tools/values.d.ts.map +1 -1
- package/dist/core/tools/values.js +11 -0
- package/dist/core/tools/values.js.map +1 -1
- package/dist/runtime/data-access/formula.js +1 -1
- package/dist/runtime/data-access/workflow.js +27 -27
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +8 -1
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime/identity/store.js +24 -24
- package/dist/runtime/metadata/revision.js +2 -2
- package/dist/runtime/record-meta/store.js +2 -2
- package/dist/subsystems/workflow/store.js +13 -13
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
All notable changes to `@weave-kit/engine`. Format follows [Keep a Changelog](https://keepachangelog.com/);
|
|
4
4
|
the project uses [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [1.3.0] - 2026-10-11
|
|
7
|
+
|
|
8
|
+
Additive (no `CONTRACT_VERSION` bump): MCP surface + formula catalog.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **MCP approval tools.** When an approval queue is wired and the session identity holds an
|
|
13
|
+
`adapters.mcp.adminRoles` role, the surface exposes `list_approvals` / `approve_approval` /
|
|
14
|
+
`reject_approval` (names frozen in `APPROVAL_TOOLS`). Resolution is audited by the queue facade and
|
|
15
|
+
the tool call by `callProtected` — the same admin gate as the REST `/approvals` routes.
|
|
16
|
+
- **MCP resources.** The schema is exposed as readable resources (`weavekit://objects`,
|
|
17
|
+
`weavekit://objects/{name}`), derived from the registry and RBAC-filtered per identity (mirrors
|
|
18
|
+
`list_objects` / `describe_object`). The server now advertises a `resources` capability.
|
|
19
|
+
- **Formula catalog.** New functions (single-source `FORMULA_FUNCTIONS`): `lower` / `upper` / `trim` /
|
|
20
|
+
`length` / `substr` / `replace`, `abs` / `floor` / `ceil` / `pow`, and null-coalescing `coalesce`,
|
|
21
|
+
with arity/type validation.
|
|
22
|
+
|
|
6
23
|
## [1.2.0] - 2026-10-11
|
|
7
24
|
|
|
8
25
|
Additive (no `CONTRACT_VERSION` bump): seams for the Cloud/Console control plane.
|
package/README.md
CHANGED
|
@@ -1,210 +1,210 @@
|
|
|
1
|
-
<h1 align="center">Let AI agents operate your data — safely</h1>
|
|
2
|
-
|
|
3
|
-
Define your data model once in `schema.json`, and WeaveKit compiles it into PostgreSQL tables, REST
|
|
4
|
-
and GraphQL APIs with row- and field-level RBAC, an immutable audit log with execution evidence, and
|
|
5
|
-
an MCP tool surface that AI agents call with typed tools — never raw SQL. Self-hosted: your data
|
|
6
|
-
stays in your database.
|
|
7
|
-
|
|
8
|
-
```
|
|
9
|
-
objects/leads/schema.json → Git commit (source of truth)
|
|
10
|
-
PostgreSQL tables + indexes + RLS
|
|
11
|
-
REST + GraphQL APIs (CRUD + RBAC)
|
|
12
|
-
MCP tools (per-identity surface + guardrails + approvals)
|
|
13
|
-
Immutable audit log + execution evidence
|
|
14
|
-
TypeScript types
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Why WeaveKit
|
|
18
|
-
|
|
19
|
-
- **Safe by construction** — every agent action is authorized by row- and field-level RBAC and
|
|
20
|
-
native PostgreSQL RLS, and recorded in an immutable audit log. Guardrails (and optional
|
|
21
|
-
approvals) sit in front.
|
|
22
|
-
- **Your model is a Git repository** — schema, hooks and policies are files you review, diff and
|
|
23
|
-
revert; the engine commits every change for you, and PostgreSQL is a derived cache.
|
|
24
|
-
- **One agent, many users** — each MCP call carries the acting user's identity (on-behalf-of), and
|
|
25
|
-
the engine compiles a per-identity tool surface: a salesperson's agent sees only their own leads,
|
|
26
|
-
a finance agent cannot read sales notes. Prompt injection cannot bypass RBAC/RLS.
|
|
27
|
-
- **Bring your existing PostgreSQL** — point the engine at a live database and declare the tables
|
|
28
|
-
you want to expose; existing tables stay read-only unless you explicitly allow additive DDL, and
|
|
29
|
-
`weave introspect` can reverse-model them into `schema.json`.
|
|
30
|
-
- **Typed tools in minutes, not weeks** — hand-writing an MCP server (tools + permissions + audit)
|
|
31
|
-
for a few tables takes days; here it is a few `schema.json` files, and new fields or tables
|
|
32
|
-
extend the tool surface automatically.
|
|
33
|
-
- **More than MCP** — the same schema also drives REST and GraphQL APIs and generated TypeScript
|
|
34
|
-
types, so people and agents share one governed contract.
|
|
35
|
-
- **Self-hosted** — the engine runs in your environment; no data leaves your database.
|
|
36
|
-
|
|
37
|
-
## How it works
|
|
38
|
-
|
|
39
|
-
`weave` reads `objects/<name>/schema.json`, validates it, and syncs it to PostgreSQL (state-diff
|
|
40
|
-
migrations; existing tables stay read-only unless you allow additive DDL). The same metadata drives
|
|
41
|
-
the REST routes and the MCP tool surface, and the data-access layer enforces RBAC and audits every
|
|
42
|
-
write.
|
|
43
|
-
|
|
44
|
-
## Features
|
|
45
|
-
|
|
46
|
-
- **Git-versioned metadata** — schema, hooks and policies are plain files in your repository; every
|
|
47
|
-
change is a scoped, atomic Git commit, so review, history and rollback come for free. PostgreSQL
|
|
48
|
-
stays a derived cache.
|
|
49
|
-
- **Schema as the source of truth** — `objects/<name>/schema.json` drives the tables, REST API and MCP
|
|
50
|
-
surface; state-diff migrations to PostgreSQL.
|
|
51
|
-
- **Custom field types** — register business-semantic types (`money`, `address`, …) as thin, namespaced
|
|
52
|
-
layers over a built-in primitive; they inherit storage, REST/MCP/OpenAPI schemas and generated
|
|
53
|
-
types. Declared in a project-local, Git-committed `field-types/` directory.
|
|
54
|
-
- **Named enums** — declare a shared enum once in `enums/` and reference it from any object by
|
|
55
|
-
`enumType`; every field shares one native PostgreSQL type and one set of per-value labels.
|
|
56
|
-
- **Governed REST API** — object CRUD with row-level (`all`/`own`/`department`) and field-level RBAC
|
|
57
|
-
and a uniform error contract.
|
|
58
|
-
- **MCP tool surface** — a streamable HTTP endpoint at `/mcp` with a per-identity tool surface and
|
|
59
|
-
guardrails.
|
|
60
|
-
- **GraphQL API** — an opt-in read/write GraphQL endpoint compiled from the same `schema.json`, with
|
|
61
|
-
nested relations, the same RBAC/audit, per-request batching and query hardening.
|
|
62
|
-
- **Schema revisions & atomic deploys** — `weave deploy plan` previews the diff; `weave deploy apply`
|
|
63
|
-
commits the DDL, the metadata cache and a global **schema revision** in one transaction (no
|
|
64
|
-
half-applied deploys).
|
|
65
|
-
- **Agent execution pipeline** — every write and tool call runs through one
|
|
66
|
-
Plan → Validate → Authorize → Guardrail → Approval → Execute → Commit → Evidence pipeline, so
|
|
67
|
-
guardrails and approvals cover REST, MCP and GraphQL alike; enable `evidence` to record a
|
|
68
|
-
`weavekit_evidence` row per execution (correlated by request / trace / schema revision).
|
|
69
|
-
- **Query budget** — bound a read/query across the engine: rows, filters and sorts in data-access,
|
|
70
|
-
joins / SQL length / statement timeout in restricted SQL, and GraphQL depth.
|
|
71
|
-
- **Multi-tenancy (row)** — mark a field `"tenant": true` and every read/write is scoped to the
|
|
72
|
-
subject's tenant (RBAC row scope + PostgreSQL RLS + audit); single-tenant by default.
|
|
73
|
-
- **Audit log** — an immutable event log for data mutations, with durability modes
|
|
74
|
-
(`best-effort` / `transactional` / `durable`) and a keyset-cursor query.
|
|
75
|
-
- **Observability** — a low-level metrics/trace seam (`MetricsSink` / `TraceSink`, `METRIC_NAMES`)
|
|
76
|
-
that emits request latency, RBAC denials, query-budget rejects and W3C `traceparent`-correlated
|
|
77
|
-
spans; the engine ships a no-op default and brings no backend.
|
|
78
|
-
- **Sandboxed hooks** — `*.server.js` lifecycle hooks running in isolated workers.
|
|
79
|
-
- **Type generation** — object-level TypeScript types derived from the schema.
|
|
80
|
-
- **Live events** — an SSE stream with replay.
|
|
81
|
-
- **Operations** — `weave doctor` preflight, health / readiness / version endpoints, request rate
|
|
82
|
-
limiting, CORS and structured logging.
|
|
83
|
-
|
|
84
|
-
## Requirements
|
|
85
|
-
|
|
86
|
-
- Node.js 22+
|
|
87
|
-
- PostgreSQL 12+ (the engine's tested floor; `weave doctor` reports the version)
|
|
88
|
-
|
|
89
|
-
## Quick start
|
|
90
|
-
|
|
91
|
-
```sh
|
|
92
|
-
npm create weavekit-app my-app -- --type=agent
|
|
93
|
-
cd my-app
|
|
94
|
-
cp .env.example .env # set DATABASE_URL
|
|
95
|
-
weave migrate # state-diff migration: schema.json → PostgreSQL tables (+ metadata cache)
|
|
96
|
-
weave dev # http://localhost:3000 — hot reload
|
|
97
|
-
weave types # object-level TS types → generated/types.ts
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**Existing database?** Reverse-model it instead of authoring from scratch:
|
|
101
|
-
|
|
102
|
-
```sh
|
|
103
|
-
weave introspect # live tables → objects/<table>/schema.json (read-only)
|
|
104
|
-
weave schema:map # schema field ↔ PostgreSQL column mapping + drift
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Connect an agent** (MCP is available at `/mcp`):
|
|
108
|
-
|
|
109
|
-
```sh
|
|
110
|
-
weave mcp:config # ready-to-paste config for Claude Code / Cursor / VS Code / Claude Desktop
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Documentation
|
|
114
|
-
|
|
115
|
-
Full documentation: **[docs.weavekit.io/engine](https://docs.weavekit.io/engine)**
|
|
116
|
-
|
|
117
|
-
- [Getting started](https://docs.weavekit.io/engine/guides/getting-started) — scaffold, migrate, run, consume
|
|
118
|
-
- [Git-versioned metadata](https://docs.weavekit.io/engine/guides/model/git-versioned-metadata) — your data model as reviewable Git commits
|
|
119
|
-
- [Schema guide](https://docs.weavekit.io/engine/guides/model/schema) · [RBAC](https://docs.weavekit.io/engine/guides/access/rbac) · [Multi-tenancy](https://docs.weavekit.io/engine/guides/access/multi-tenancy) · [Formulas](https://docs.weavekit.io/engine/guides/model/formulas) · [Audit](https://docs.weavekit.io/engine/guides/platform/audit)
|
|
120
|
-
- [CLI reference](https://docs.weavekit.io/engine/guides/platform/cli) · [Observability](https://docs.weavekit.io/engine/guides/platform/observability) · [MCP](https://docs.weavekit.io/engine/guides/agents/mcp) · [Execution & evidence](https://docs.weavekit.io/engine/guides/agents/execution-and-evidence) · [Script hooks](https://docs.weavekit.io/engine/guides/automation/script-hooks)
|
|
121
|
-
- [Custom tools & guardrails](https://docs.weavekit.io/engine/guides/agents/custom-tools-and-guardrails) · [Query budget](https://docs.weavekit.io/engine/guides/automation/query-budget) · [Custom field types](https://docs.weavekit.io/engine/reference/schema/custom-field-types) · [Quotas](https://docs.weavekit.io/engine/guides/automation/quotas) · [Inbound events](https://docs.weavekit.io/engine/guides/integration/ingress)
|
|
122
|
-
- [Public API & dependency budget](https://docs.weavekit.io/engine/reference/api/public-api) · [Enterprise seams](https://docs.weavekit.io/engine/reference/enterprise-seams) · [Contract freeze](https://docs.weavekit.io/engine/reference/contract-freeze)
|
|
123
|
-
- [Practices & operations](https://docs.weavekit.io/engine/practices/agent/existing-crm-to-mcp) · [Release checklist](https://docs.weavekit.io/engine/operations/release) — real integration and deployment walkthroughs
|
|
124
|
-
|
|
125
|
-
The Markdown sources live in [`docs/`](https://github.com/weavekit/engine/tree/main/docs).
|
|
126
|
-
|
|
127
|
-
## Programmatic use
|
|
128
|
-
|
|
129
|
-
```ts
|
|
130
|
-
import { createEngine } from '@weave-kit/engine';
|
|
131
|
-
|
|
132
|
-
const engine = await createEngine({
|
|
133
|
-
databaseUrl: process.env.DATABASE_URL,
|
|
134
|
-
schemaDir: '.', // project root containing objects/
|
|
135
|
-
auth: { source: { 'sk-admin': { id: 'admin', roles: ['admin'] } } },
|
|
136
|
-
});
|
|
137
|
-
await engine.app.listen({ port: 3000 });
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## Metadata
|
|
141
|
-
|
|
142
|
-
- **Objects** live in `objects/<name>/schema.json` (one directory per object; the directory name must
|
|
143
|
-
equal the object name).
|
|
144
|
-
- **`weavekit.config.ts`** is the single wiring point — a default export `satisfies EngineConfig`
|
|
145
|
-
(`schemaDir`, `auth`, `adapters`, `subsystems`).
|
|
146
|
-
- `schema.json` is versioned in Git and is the source of truth; the engine syncs it to PostgreSQL and
|
|
147
|
-
a metadata cache.
|
|
148
|
-
|
|
149
|
-
## CLI
|
|
150
|
-
|
|
151
|
-
| Command | Description |
|
|
152
|
-
| --- | --- |
|
|
153
|
-
| `weave migrate [--dry-run]` | State-diff migration + metadata cache + auto-commit |
|
|
154
|
-
| `weave deploy plan` / `weave deploy apply` | Preview / atomically apply schema changes and record a global schema revision |
|
|
155
|
-
| `weave doctor` | Read-only preflight (connection, PostgreSQL compatibility, drift, system tables, RLS + sandbox) |
|
|
156
|
-
| `weave dev [--port]` | Run with hot reload |
|
|
157
|
-
| `weave build` | Bundle the server entry (esbuild) |
|
|
158
|
-
| `weave test` | Proxy the project test suite |
|
|
159
|
-
| `weave types [--outdir]` | Compile `schema.json` into object-level TS types |
|
|
160
|
-
| `weave introspect` | Reverse-model an existing Postgres DB into `objects/*/schema.json` |
|
|
161
|
-
| `weave schema:map [object] [--drift]` | Report the schema field ↔ PostgreSQL column mapping |
|
|
162
|
-
| `weave schema:upgrade [--dry-run]` | Upgrade `objects/*/schema.json` to the current format version |
|
|
163
|
-
| `weave openapi [--out] [--generic] [--server]` | Emit an OpenAPI 3.1 document for the REST API |
|
|
164
|
-
| `weave graphql:schema [--out]` | Emit the GraphQL SDL for this project |
|
|
165
|
-
| `weave mcp:config [--host]` | Print MCP client config for this project's `/mcp` endpoint |
|
|
166
|
-
| `weave connect` | Connect a self-hosted engine out to a governance tunnel endpoint |
|
|
167
|
-
| `weave object:create <name>` | Scaffold `objects/<name>/schema.json` + `server.js` hooks |
|
|
168
|
-
| `weave field:add <object>` | Add a validated field to a schema |
|
|
169
|
-
| `weave field-type:list` | List built-in + registered field types |
|
|
170
|
-
| `weave field-type:check` | Validate registrations + schemas against the registry |
|
|
171
|
-
| `weave enum:list` | List declared named enums (`enums/<name>.json`) |
|
|
172
|
-
| `weave enum:check` | Validate enum declarations + schema references |
|
|
173
|
-
| `weave module:add` / `module:remove <name>` | Enable/disable an optional subsystem (audit/script/workflow) |
|
|
174
|
-
|
|
175
|
-
## Object-level types
|
|
176
|
-
|
|
177
|
-
```sh
|
|
178
|
-
weave types # → generated/types.ts
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
```ts
|
|
182
|
-
import type { Lead } from './generated/types';
|
|
183
|
-
import { createClient } from '@weave-kit/client';
|
|
184
|
-
|
|
185
|
-
const leads = createClient({ baseUrl, apiKey }).objects<Lead>('lead');
|
|
186
|
-
const { rows } = await leads.find({ filter: { status: 'open' } });
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## Development
|
|
190
|
-
|
|
191
|
-
```sh
|
|
192
|
-
npm install
|
|
193
|
-
npm run build # tsc → dist
|
|
194
|
-
npm test # unit + e2e (e2e needs DATABASE_URL)
|
|
195
|
-
npm run test:coverage # coverage gate on security-critical paths
|
|
196
|
-
npm run typecheck
|
|
197
|
-
npm run lint
|
|
198
|
-
node scripts/check-exports.mjs # verify package exports + contract names
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Issues and pull requests are welcome. See [`AGENTS.md`](AGENTS.md) for architecture notes and
|
|
202
|
-
contribution invariants.
|
|
203
|
-
|
|
204
|
-
## Support
|
|
205
|
-
|
|
206
|
-
Questions, bug reports and security reports: **support@weavekit.io**.
|
|
207
|
-
|
|
208
|
-
## License
|
|
209
|
-
|
|
210
|
-
[MIT](LICENSE) · For support, contact **support@weavekit.io**.
|
|
1
|
+
<h1 align="center">Let AI agents operate your data — safely</h1>
|
|
2
|
+
|
|
3
|
+
Define your data model once in `schema.json`, and WeaveKit compiles it into PostgreSQL tables, REST
|
|
4
|
+
and GraphQL APIs with row- and field-level RBAC, an immutable audit log with execution evidence, and
|
|
5
|
+
an MCP tool surface that AI agents call with typed tools — never raw SQL. Self-hosted: your data
|
|
6
|
+
stays in your database.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
objects/leads/schema.json → Git commit (source of truth)
|
|
10
|
+
PostgreSQL tables + indexes + RLS
|
|
11
|
+
REST + GraphQL APIs (CRUD + RBAC)
|
|
12
|
+
MCP tools (per-identity surface + guardrails + approvals)
|
|
13
|
+
Immutable audit log + execution evidence
|
|
14
|
+
TypeScript types
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Why WeaveKit
|
|
18
|
+
|
|
19
|
+
- **Safe by construction** — every agent action is authorized by row- and field-level RBAC and
|
|
20
|
+
native PostgreSQL RLS, and recorded in an immutable audit log. Guardrails (and optional
|
|
21
|
+
approvals) sit in front.
|
|
22
|
+
- **Your model is a Git repository** — schema, hooks and policies are files you review, diff and
|
|
23
|
+
revert; the engine commits every change for you, and PostgreSQL is a derived cache.
|
|
24
|
+
- **One agent, many users** — each MCP call carries the acting user's identity (on-behalf-of), and
|
|
25
|
+
the engine compiles a per-identity tool surface: a salesperson's agent sees only their own leads,
|
|
26
|
+
a finance agent cannot read sales notes. Prompt injection cannot bypass RBAC/RLS.
|
|
27
|
+
- **Bring your existing PostgreSQL** — point the engine at a live database and declare the tables
|
|
28
|
+
you want to expose; existing tables stay read-only unless you explicitly allow additive DDL, and
|
|
29
|
+
`weave introspect` can reverse-model them into `schema.json`.
|
|
30
|
+
- **Typed tools in minutes, not weeks** — hand-writing an MCP server (tools + permissions + audit)
|
|
31
|
+
for a few tables takes days; here it is a few `schema.json` files, and new fields or tables
|
|
32
|
+
extend the tool surface automatically.
|
|
33
|
+
- **More than MCP** — the same schema also drives REST and GraphQL APIs and generated TypeScript
|
|
34
|
+
types, so people and agents share one governed contract.
|
|
35
|
+
- **Self-hosted** — the engine runs in your environment; no data leaves your database.
|
|
36
|
+
|
|
37
|
+
## How it works
|
|
38
|
+
|
|
39
|
+
`weave` reads `objects/<name>/schema.json`, validates it, and syncs it to PostgreSQL (state-diff
|
|
40
|
+
migrations; existing tables stay read-only unless you allow additive DDL). The same metadata drives
|
|
41
|
+
the REST routes and the MCP tool surface, and the data-access layer enforces RBAC and audits every
|
|
42
|
+
write.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Git-versioned metadata** — schema, hooks and policies are plain files in your repository; every
|
|
47
|
+
change is a scoped, atomic Git commit, so review, history and rollback come for free. PostgreSQL
|
|
48
|
+
stays a derived cache.
|
|
49
|
+
- **Schema as the source of truth** — `objects/<name>/schema.json` drives the tables, REST API and MCP
|
|
50
|
+
surface; state-diff migrations to PostgreSQL.
|
|
51
|
+
- **Custom field types** — register business-semantic types (`money`, `address`, …) as thin, namespaced
|
|
52
|
+
layers over a built-in primitive; they inherit storage, REST/MCP/OpenAPI schemas and generated
|
|
53
|
+
types. Declared in a project-local, Git-committed `field-types/` directory.
|
|
54
|
+
- **Named enums** — declare a shared enum once in `enums/` and reference it from any object by
|
|
55
|
+
`enumType`; every field shares one native PostgreSQL type and one set of per-value labels.
|
|
56
|
+
- **Governed REST API** — object CRUD with row-level (`all`/`own`/`department`) and field-level RBAC
|
|
57
|
+
and a uniform error contract.
|
|
58
|
+
- **MCP tool surface** — a streamable HTTP endpoint at `/mcp` with a per-identity tool surface and
|
|
59
|
+
guardrails.
|
|
60
|
+
- **GraphQL API** — an opt-in read/write GraphQL endpoint compiled from the same `schema.json`, with
|
|
61
|
+
nested relations, the same RBAC/audit, per-request batching and query hardening.
|
|
62
|
+
- **Schema revisions & atomic deploys** — `weave deploy plan` previews the diff; `weave deploy apply`
|
|
63
|
+
commits the DDL, the metadata cache and a global **schema revision** in one transaction (no
|
|
64
|
+
half-applied deploys).
|
|
65
|
+
- **Agent execution pipeline** — every write and tool call runs through one
|
|
66
|
+
Plan → Validate → Authorize → Guardrail → Approval → Execute → Commit → Evidence pipeline, so
|
|
67
|
+
guardrails and approvals cover REST, MCP and GraphQL alike; enable `evidence` to record a
|
|
68
|
+
`weavekit_evidence` row per execution (correlated by request / trace / schema revision).
|
|
69
|
+
- **Query budget** — bound a read/query across the engine: rows, filters and sorts in data-access,
|
|
70
|
+
joins / SQL length / statement timeout in restricted SQL, and GraphQL depth.
|
|
71
|
+
- **Multi-tenancy (row)** — mark a field `"tenant": true` and every read/write is scoped to the
|
|
72
|
+
subject's tenant (RBAC row scope + PostgreSQL RLS + audit); single-tenant by default.
|
|
73
|
+
- **Audit log** — an immutable event log for data mutations, with durability modes
|
|
74
|
+
(`best-effort` / `transactional` / `durable`) and a keyset-cursor query.
|
|
75
|
+
- **Observability** — a low-level metrics/trace seam (`MetricsSink` / `TraceSink`, `METRIC_NAMES`)
|
|
76
|
+
that emits request latency, RBAC denials, query-budget rejects and W3C `traceparent`-correlated
|
|
77
|
+
spans; the engine ships a no-op default and brings no backend.
|
|
78
|
+
- **Sandboxed hooks** — `*.server.js` lifecycle hooks running in isolated workers.
|
|
79
|
+
- **Type generation** — object-level TypeScript types derived from the schema.
|
|
80
|
+
- **Live events** — an SSE stream with replay.
|
|
81
|
+
- **Operations** — `weave doctor` preflight, health / readiness / version endpoints, request rate
|
|
82
|
+
limiting, CORS and structured logging.
|
|
83
|
+
|
|
84
|
+
## Requirements
|
|
85
|
+
|
|
86
|
+
- Node.js 22+
|
|
87
|
+
- PostgreSQL 12+ (the engine's tested floor; `weave doctor` reports the version)
|
|
88
|
+
|
|
89
|
+
## Quick start
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
npm create weavekit-app my-app -- --type=agent
|
|
93
|
+
cd my-app
|
|
94
|
+
cp .env.example .env # set DATABASE_URL
|
|
95
|
+
weave migrate # state-diff migration: schema.json → PostgreSQL tables (+ metadata cache)
|
|
96
|
+
weave dev # http://localhost:3000 — hot reload
|
|
97
|
+
weave types # object-level TS types → generated/types.ts
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Existing database?** Reverse-model it instead of authoring from scratch:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
weave introspect # live tables → objects/<table>/schema.json (read-only)
|
|
104
|
+
weave schema:map # schema field ↔ PostgreSQL column mapping + drift
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Connect an agent** (MCP is available at `/mcp`):
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
weave mcp:config # ready-to-paste config for Claude Code / Cursor / VS Code / Claude Desktop
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Documentation
|
|
114
|
+
|
|
115
|
+
Full documentation: **[docs.weavekit.io/engine](https://docs.weavekit.io/engine)**
|
|
116
|
+
|
|
117
|
+
- [Getting started](https://docs.weavekit.io/engine/guides/getting-started) — scaffold, migrate, run, consume
|
|
118
|
+
- [Git-versioned metadata](https://docs.weavekit.io/engine/guides/model/git-versioned-metadata) — your data model as reviewable Git commits
|
|
119
|
+
- [Schema guide](https://docs.weavekit.io/engine/guides/model/schema) · [RBAC](https://docs.weavekit.io/engine/guides/access/rbac) · [Multi-tenancy](https://docs.weavekit.io/engine/guides/access/multi-tenancy) · [Formulas](https://docs.weavekit.io/engine/guides/model/formulas) · [Audit](https://docs.weavekit.io/engine/guides/platform/audit)
|
|
120
|
+
- [CLI reference](https://docs.weavekit.io/engine/guides/platform/cli) · [Observability](https://docs.weavekit.io/engine/guides/platform/observability) · [MCP](https://docs.weavekit.io/engine/guides/agents/mcp) · [Execution & evidence](https://docs.weavekit.io/engine/guides/agents/execution-and-evidence) · [Script hooks](https://docs.weavekit.io/engine/guides/automation/script-hooks)
|
|
121
|
+
- [Custom tools & guardrails](https://docs.weavekit.io/engine/guides/agents/custom-tools-and-guardrails) · [Query budget](https://docs.weavekit.io/engine/guides/automation/query-budget) · [Custom field types](https://docs.weavekit.io/engine/reference/schema/custom-field-types) · [Quotas](https://docs.weavekit.io/engine/guides/automation/quotas) · [Inbound events](https://docs.weavekit.io/engine/guides/integration/ingress)
|
|
122
|
+
- [Public API & dependency budget](https://docs.weavekit.io/engine/reference/api/public-api) · [Enterprise seams](https://docs.weavekit.io/engine/reference/enterprise-seams) · [Contract freeze](https://docs.weavekit.io/engine/reference/contract-freeze)
|
|
123
|
+
- [Practices & operations](https://docs.weavekit.io/engine/practices/agent/existing-crm-to-mcp) · [Release checklist](https://docs.weavekit.io/engine/operations/release) — real integration and deployment walkthroughs
|
|
124
|
+
|
|
125
|
+
The Markdown sources live in [`docs/`](https://github.com/weavekit/engine/tree/main/docs).
|
|
126
|
+
|
|
127
|
+
## Programmatic use
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { createEngine } from '@weave-kit/engine';
|
|
131
|
+
|
|
132
|
+
const engine = await createEngine({
|
|
133
|
+
databaseUrl: process.env.DATABASE_URL,
|
|
134
|
+
schemaDir: '.', // project root containing objects/
|
|
135
|
+
auth: { source: { 'sk-admin': { id: 'admin', roles: ['admin'] } } },
|
|
136
|
+
});
|
|
137
|
+
await engine.app.listen({ port: 3000 });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Metadata
|
|
141
|
+
|
|
142
|
+
- **Objects** live in `objects/<name>/schema.json` (one directory per object; the directory name must
|
|
143
|
+
equal the object name).
|
|
144
|
+
- **`weavekit.config.ts`** is the single wiring point — a default export `satisfies EngineConfig`
|
|
145
|
+
(`schemaDir`, `auth`, `adapters`, `subsystems`).
|
|
146
|
+
- `schema.json` is versioned in Git and is the source of truth; the engine syncs it to PostgreSQL and
|
|
147
|
+
a metadata cache.
|
|
148
|
+
|
|
149
|
+
## CLI
|
|
150
|
+
|
|
151
|
+
| Command | Description |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| `weave migrate [--dry-run]` | State-diff migration + metadata cache + auto-commit |
|
|
154
|
+
| `weave deploy plan` / `weave deploy apply` | Preview / atomically apply schema changes and record a global schema revision |
|
|
155
|
+
| `weave doctor` | Read-only preflight (connection, PostgreSQL compatibility, drift, system tables, RLS + sandbox) |
|
|
156
|
+
| `weave dev [--port]` | Run with hot reload |
|
|
157
|
+
| `weave build` | Bundle the server entry (esbuild) |
|
|
158
|
+
| `weave test` | Proxy the project test suite |
|
|
159
|
+
| `weave types [--outdir]` | Compile `schema.json` into object-level TS types |
|
|
160
|
+
| `weave introspect` | Reverse-model an existing Postgres DB into `objects/*/schema.json` |
|
|
161
|
+
| `weave schema:map [object] [--drift]` | Report the schema field ↔ PostgreSQL column mapping |
|
|
162
|
+
| `weave schema:upgrade [--dry-run]` | Upgrade `objects/*/schema.json` to the current format version |
|
|
163
|
+
| `weave openapi [--out] [--generic] [--server]` | Emit an OpenAPI 3.1 document for the REST API |
|
|
164
|
+
| `weave graphql:schema [--out]` | Emit the GraphQL SDL for this project |
|
|
165
|
+
| `weave mcp:config [--host]` | Print MCP client config for this project's `/mcp` endpoint |
|
|
166
|
+
| `weave connect` | Connect a self-hosted engine out to a governance tunnel endpoint |
|
|
167
|
+
| `weave object:create <name>` | Scaffold `objects/<name>/schema.json` + `server.js` hooks |
|
|
168
|
+
| `weave field:add <object>` | Add a validated field to a schema |
|
|
169
|
+
| `weave field-type:list` | List built-in + registered field types |
|
|
170
|
+
| `weave field-type:check` | Validate registrations + schemas against the registry |
|
|
171
|
+
| `weave enum:list` | List declared named enums (`enums/<name>.json`) |
|
|
172
|
+
| `weave enum:check` | Validate enum declarations + schema references |
|
|
173
|
+
| `weave module:add` / `module:remove <name>` | Enable/disable an optional subsystem (audit/script/workflow) |
|
|
174
|
+
|
|
175
|
+
## Object-level types
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
weave types # → generated/types.ts
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import type { Lead } from './generated/types';
|
|
183
|
+
import { createClient } from '@weave-kit/client';
|
|
184
|
+
|
|
185
|
+
const leads = createClient({ baseUrl, apiKey }).objects<Lead>('lead');
|
|
186
|
+
const { rows } = await leads.find({ filter: { status: 'open' } });
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Development
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
npm install
|
|
193
|
+
npm run build # tsc → dist
|
|
194
|
+
npm test # unit + e2e (e2e needs DATABASE_URL)
|
|
195
|
+
npm run test:coverage # coverage gate on security-critical paths
|
|
196
|
+
npm run typecheck
|
|
197
|
+
npm run lint
|
|
198
|
+
node scripts/check-exports.mjs # verify package exports + contract names
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Issues and pull requests are welcome. See [`AGENTS.md`](AGENTS.md) for architecture notes and
|
|
202
|
+
contribution invariants.
|
|
203
|
+
|
|
204
|
+
## Support
|
|
205
|
+
|
|
206
|
+
Questions, bug reports and security reports: **support@weavekit.io**.
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
[MIT](LICENSE) · For support, contact **support@weavekit.io**.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpToolResult, ToolExecContext } from './types.js';
|
|
2
|
+
export declare function listApprovalsHandler(args: Record<string, unknown>, ctx: ToolExecContext): Promise<McpToolResult>;
|
|
3
|
+
export declare function approveApprovalHandler(args: Record<string, unknown>, ctx: ToolExecContext): Promise<McpToolResult>;
|
|
4
|
+
export declare function rejectApprovalHandler(args: Record<string, unknown>, ctx: ToolExecContext): Promise<McpToolResult>;
|
|
5
|
+
//# sourceMappingURL=approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../../src/adapters/mcp/approvals.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8CjE,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,aAAa,CAAC,CAOxB;AAoBD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,aAAa,CAAC,CAExB;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,aAAa,CAAC,CAExB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { APPROVAL_STATUSES, APPROVAL_TOOLS, SchemaError } from '../../core/index.js';
|
|
2
|
+
import { callProtected, textResult } from './tools.js';
|
|
3
|
+
/**
|
|
4
|
+
* Approval-queue MCP tools (`list_approvals` / `approve_approval` /
|
|
5
|
+
* `reject_approval`). They mirror the REST `/approvals` routes: admin-gated
|
|
6
|
+
* (the queue carries request arguments) and backed by the same injected
|
|
7
|
+
* `ToolApprovals` queue — resolution is audited by the queue facade, the tool
|
|
8
|
+
* call itself is audited here via `callProtected`.
|
|
9
|
+
*/
|
|
10
|
+
const VALID_STATUSES = new Set(Object.values(APPROVAL_STATUSES));
|
|
11
|
+
/**
|
|
12
|
+
* Fail-closed gate: the queue must be wired and the caller must carry a role
|
|
13
|
+
* listed in `adminRoles`. The compiled surface already filters to admins; this
|
|
14
|
+
* re-check is the execution-layer double (mirrors the object-RBAC double layer).
|
|
15
|
+
*/
|
|
16
|
+
function requireApprovals(ctx) {
|
|
17
|
+
const approvals = ctx.engine.approvals;
|
|
18
|
+
const admin = new Set(ctx.engine.adminRoles ?? []);
|
|
19
|
+
if (approvals === undefined || !ctx.session.user.roles.some((role) => admin.has(role))) {
|
|
20
|
+
throw new SchemaError('rbac.denied.update', { object: 'approvals', role: ctx.session.user.roles.join(',') }, ctx.engine.locale);
|
|
21
|
+
}
|
|
22
|
+
return approvals;
|
|
23
|
+
}
|
|
24
|
+
function parseFilter(args, ctx) {
|
|
25
|
+
const filter = {};
|
|
26
|
+
const status = args.status;
|
|
27
|
+
if (status !== undefined) {
|
|
28
|
+
if (typeof status !== 'string' || !VALID_STATUSES.has(status)) {
|
|
29
|
+
throw new SchemaError('http.param.invalid', { param: 'status' }, ctx.engine.locale);
|
|
30
|
+
}
|
|
31
|
+
filter.status = status;
|
|
32
|
+
}
|
|
33
|
+
if (typeof args.action === 'string')
|
|
34
|
+
filter.action = args.action;
|
|
35
|
+
if (typeof args.actorKey === 'string')
|
|
36
|
+
filter.actorKey = args.actorKey;
|
|
37
|
+
if (typeof args.limit === 'number')
|
|
38
|
+
filter.limit = args.limit;
|
|
39
|
+
if (typeof args.offset === 'number')
|
|
40
|
+
filter.offset = args.offset;
|
|
41
|
+
return filter;
|
|
42
|
+
}
|
|
43
|
+
export async function listApprovalsHandler(args, ctx) {
|
|
44
|
+
return callProtected(ctx, APPROVAL_TOOLS.LIST, undefined, args, async () => ctx.session.user, async () => {
|
|
45
|
+
const approvals = requireApprovals(ctx);
|
|
46
|
+
const filter = parseFilter(args, ctx);
|
|
47
|
+
const [rows, total] = await Promise.all([approvals.list(filter), approvals.count(filter)]);
|
|
48
|
+
return textResult(JSON.stringify({ rows, total }));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function resolveApproval(args, ctx, decision) {
|
|
52
|
+
const tool = decision === 'approved' ? APPROVAL_TOOLS.APPROVE : APPROVAL_TOOLS.REJECT;
|
|
53
|
+
return callProtected(ctx, tool, undefined, args, async () => ctx.session.user, async (subject) => {
|
|
54
|
+
const approvals = requireApprovals(ctx);
|
|
55
|
+
const key = String(args.key ?? '');
|
|
56
|
+
const ok = decision === 'approved' ? await approvals.approve(key, subject.id) : await approvals.reject(key, subject.id);
|
|
57
|
+
if (!ok) {
|
|
58
|
+
throw new SchemaError('approval.notFound', { approvalKey: key }, ctx.engine.locale);
|
|
59
|
+
}
|
|
60
|
+
return textResult(JSON.stringify({ approvalKey: key, status: decision, approver: subject.id }));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
export async function approveApprovalHandler(args, ctx) {
|
|
64
|
+
return resolveApproval(args, ctx, 'approved');
|
|
65
|
+
}
|
|
66
|
+
export async function rejectApprovalHandler(args, ctx) {
|
|
67
|
+
return resolveApproval(args, ctx, 'rejected');
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../src/adapters/mcp/approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/adapters/mcp/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/adapters/mcp/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAWjE,OAAO,KAAK,EAAc,SAAS,EAAiB,WAAW,EAAmB,MAAM,YAAY,CAAC;AAErG;;;;;;;;;;GAUG;AAEH,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AA6PD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,eAAe,EACxB,MAAM,CAAC,EAAE;IAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GAC1D,YAAY,EAAE,CAmChB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { INTROSPECTION_TOOLS, REGISTRY_TOOLS, WORKFLOW_TOOLS, resolvePermissionFor } from '../../core/index.js';
|
|
1
|
+
import { APPROVAL_TOOLS, INTROSPECTION_TOOLS, REGISTRY_TOOLS, WORKFLOW_TOOLS, resolvePermissionFor } from '../../core/index.js';
|
|
2
2
|
import { ACTION_PREFIXES } from '../../core/audit/index.js';
|
|
3
3
|
import { createRecordHandler, deleteRecordHandler, getRecordHandler, searchRecordsHandler, updateRecordHandler, workflowTransitionHandler, } from './tools.js';
|
|
4
|
+
import { approveApprovalHandler, listApprovalsHandler, rejectApprovalHandler } from './approvals.js';
|
|
4
5
|
import { describeObjectHandler, listObjectsHandler } from './introspection.js';
|
|
5
6
|
/** capabilities the subject holds on at least one object (drives which generic ops appear) */
|
|
6
7
|
function capabilities(registry, subject) {
|
|
@@ -153,6 +154,53 @@ function registryTools(engine, subject) {
|
|
|
153
154
|
}
|
|
154
155
|
return tools;
|
|
155
156
|
}
|
|
157
|
+
/** approval-queue tools: admin-only, present only when a queue is wired (the queue carries request args) */
|
|
158
|
+
function approvalTools(engine, subject) {
|
|
159
|
+
if (engine.approvals === undefined)
|
|
160
|
+
return [];
|
|
161
|
+
const admin = new Set(engine.adminRoles ?? []);
|
|
162
|
+
if (!subject.roles.some((role) => admin.has(role)))
|
|
163
|
+
return [];
|
|
164
|
+
const KEY_ARG = { type: 'string', description: 'the approval key (see list_approvals)' };
|
|
165
|
+
return [
|
|
166
|
+
{
|
|
167
|
+
objectName: undefined,
|
|
168
|
+
spec: {
|
|
169
|
+
name: APPROVAL_TOOLS.LIST,
|
|
170
|
+
description: 'List the approval queue (paged; filtered to your admin scope)',
|
|
171
|
+
inputSchema: {
|
|
172
|
+
type: 'object',
|
|
173
|
+
properties: {
|
|
174
|
+
status: { type: 'string', enum: ['pending', 'approved', 'rejected'] },
|
|
175
|
+
action: { type: 'string', description: 'filter by the gated action (e.g. object.lead.update)' },
|
|
176
|
+
actorKey: { type: 'string', description: 'filter by requester actor key' },
|
|
177
|
+
limit: { type: 'integer', minimum: 1, maximum: 1000 },
|
|
178
|
+
offset: { type: 'integer', minimum: 0 },
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
handler: (args, ctx) => listApprovalsHandler(args, ctx),
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
objectName: undefined,
|
|
186
|
+
spec: {
|
|
187
|
+
name: APPROVAL_TOOLS.APPROVE,
|
|
188
|
+
description: 'Approve a pending approval (the original call may then be replayed)',
|
|
189
|
+
inputSchema: { type: 'object', properties: { key: KEY_ARG }, required: ['key'] },
|
|
190
|
+
handler: (args, ctx) => approveApprovalHandler(args, ctx),
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
objectName: undefined,
|
|
195
|
+
spec: {
|
|
196
|
+
name: APPROVAL_TOOLS.REJECT,
|
|
197
|
+
description: 'Reject a pending approval',
|
|
198
|
+
inputSchema: { type: 'object', properties: { key: KEY_ARG }, required: ['key'] },
|
|
199
|
+
handler: (args, ctx) => rejectApprovalHandler(args, ctx),
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
];
|
|
203
|
+
}
|
|
156
204
|
/** custom-tool surface merged into the session tool surface (roles filtered by the executor, cached per subject) */
|
|
157
205
|
function customToolTools(engine, subject, custom) {
|
|
158
206
|
return custom.executor.surface(subject, custom.defs).map((entry) => {
|
|
@@ -221,6 +269,7 @@ export function compileToolsFor(engine, subject, custom) {
|
|
|
221
269
|
if (custom !== undefined) {
|
|
222
270
|
tools.push(...customToolTools(engine, subject, custom));
|
|
223
271
|
}
|
|
272
|
+
tools.push(...approvalTools(engine, subject));
|
|
224
273
|
return tools;
|
|
225
274
|
}
|
|
226
275
|
//# sourceMappingURL=generate.js.map
|