@dforge-core/dforge-mcp 0.2.40 → 0.2.42

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
@@ -4,6 +4,24 @@ All notable changes to `@dforge-core/dforge-mcp`. This project uses semver-ish
4
4
  `0.1.0-rc.N` pre-release tags; the published version is set at publish time via
5
5
  the release workflow, so committed `package.json` versions are placeholders.
6
6
 
7
+ ## 0.2.41 — 2026-10-15
8
+
9
+ **Schemas follow metadata 0.0.42.** `dforge://schema/entity` describes `periodGuards` (a closed-period
10
+ lock for a document that posts to no register) and the `unique` / `where` keys of an index (a partial
11
+ or unique index). `dforge://schema/roles` checks the shape of a `rights` key, so an action grant written
12
+ without `action:` is flagged where it is typed.
13
+
14
+ **DSL builtins.** `getAccountBalance` and `getAccountTurnover` show the new last `options` argument
15
+ (`groupBy`, `exclude`, and `before` on a balance).
16
+
17
+ **Needs `@dforge-core/dforge-cli` 0.2.32**, which validates, packs and installs the above. It also
18
+ refuses a roles rights key that misses its prefix, which `dforge_module_validate` now reports.
19
+
20
+ ## 0.2.40 — 2026-10-13
21
+
22
+ **An extension file that declares only `reactions` is valid** in `dforge://schema/entity` (metadata
23
+ 0.0.41), so a bridge module's extension carrying just field-change reactions no longer fails validation.
24
+
7
25
  ## 0.2.39 — 2026-10-13
8
26
 
9
27
  **Field-change reactions are in the entity schema.** `dforge://schema/entity` describes `reactions`
package/dist/server.js CHANGED
@@ -31002,7 +31002,7 @@ var import_node_crypto = require("crypto");
31002
31002
  var fs2 = __toESM(require("fs"));
31003
31003
  var path2 = __toESM(require("path"));
31004
31004
 
31005
- // node_modules/.pnpm/@dforge-core+dforge-cli@0.2.30/node_modules/@dforge-core/dforge-cli/dist/lib.mjs
31005
+ // node_modules/.pnpm/@dforge-core+dforge-cli@0.2.32/node_modules/@dforge-core/dforge-cli/dist/lib.mjs
31006
31006
  function buildManifest(opts, moduleId) {
31007
31007
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
31008
31008
  const manifest = {
@@ -31290,7 +31290,7 @@ function buildZedTasks() {
31290
31290
  var fs = __toESM(require("fs"));
31291
31291
  var path = __toESM(require("path"));
31292
31292
 
31293
- // node_modules/.pnpm/@dforge-core+metadata@0.0.41/node_modules/@dforge-core/metadata/dist/index.js
31293
+ // node_modules/.pnpm/@dforge-core+metadata@0.0.42/node_modules/@dforge-core/metadata/dist/index.js
31294
31294
  var AggType = {
31295
31295
  Sum: "sum",
31296
31296
  Count: "count",
@@ -34622,7 +34622,7 @@ var path10 = __toESM(require("path"));
34622
34622
  var fs7 = __toESM(require("fs"));
34623
34623
  var path9 = __toESM(require("path"));
34624
34624
 
34625
- // node_modules/.pnpm/@dforge-core+metadata@0.0.41/node_modules/@dforge-core/metadata/dist/dsl/index.js
34625
+ // node_modules/.pnpm/@dforge-core+metadata@0.0.42/node_modules/@dforge-core/metadata/dist/dsl/index.js
34626
34626
  var PUNCT3 = ["===", "!=="];
34627
34627
  var PUNCT2 = [
34628
34628
  "==",
@@ -35425,15 +35425,15 @@ var BUILTINS = [
35425
35425
  },
35426
35426
  {
35427
35427
  name: "getAccountBalance",
35428
- signature: "getAccountBalance(register, account, filter?, asOf?)",
35428
+ signature: "getAccountBalance(register, account, filter?, asOf?, options?)",
35429
35429
  returns: "object",
35430
- doc: "Balance of one account of an accounting register: `{debit, credit, net}` per resource. `filter` narrows by a dimension, or by an analytic kind the ACCOUNT declares \u2014 an analytic takes the key alone, or `{ entity, value }` to name one entity of a kind that is a union of several."
35430
+ doc: "Balance of one account of an accounting register: `{debit, credit, net}` per resource. `filter` narrows by a dimension, or by an analytic kind the ACCOUNT declares \u2014 an analytic takes the key alone, or `{ entity, value }` to name one entity of a kind that is a union of several. `options`: `groupBy` (a name or array \u2014 returns an array, a row per combination with a non-zero balance), `exclude: { entity, key }` (leaves out that document's postings) and `before` (a moment, exclusive, in place of `asOf`)."
35431
35431
  },
35432
35432
  {
35433
35433
  name: "getAccountTurnover",
35434
- signature: "getAccountTurnover(register, account, filter, from, to)",
35434
+ signature: "getAccountTurnover(register, account, filter, from, to, options?)",
35435
35435
  returns: "object",
35436
- doc: "What moved through one account over an interval: `{debit, credit, net}` per resource. `filter` narrows as in `getAccountBalance` and may be `null`; `from` and `to` are both required."
35436
+ doc: "What moved through one account over an interval: `{debit, credit, net}` per resource. `filter` narrows as in `getAccountBalance` and may be `null`; `from` and `to` are both required. `options` takes `groupBy` and `exclude` as in `getAccountBalance`; a grouped turnover has a row per combination that moved."
35437
35437
  },
35438
35438
  {
35439
35439
  name: "getCorrespondence",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dforge-core/dforge-mcp",
3
- "version": "0.2.40",
3
+ "version": "0.2.42",
4
4
  "description": "MCP server for dForge module authoring. Exposes 35 scaffold/patch/validate/pack/install tools and schema resources so AI agents (Claude Code, Cursor, Zed) can create and ship dForge modules.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/iash44/dForge-core",
@@ -26,8 +26,8 @@
26
26
  "node": ">=18"
27
27
  },
28
28
  "dependencies": {
29
- "@dforge-core/dforge-cli": "^0.2.30",
30
- "@dforge-core/metadata": "^0.0.41",
29
+ "@dforge-core/dforge-cli": "^0.2.32",
30
+ "@dforge-core/metadata": "^0.0.42",
31
31
  "@modelcontextprotocol/sdk": "^1.30.0",
32
32
  "zod": "^4.4.3"
33
33
  },
@@ -192,11 +192,20 @@
192
192
  "type": "array",
193
193
  "minItems": 1,
194
194
  "items": { "type": "string" },
195
- "description": "Indexed columns, in order. Install refuses any key other than fields and using - \"columns\", which a unique constraint accepts, included."
195
+ "description": "Indexed columns, in order. Install refuses any key other than fields, using, unique and where - \"columns\", which a unique constraint accepts, included."
196
196
  },
197
197
  "using": {
198
198
  "enum": ["btree", "hash", "gin", "gist", "brin"],
199
199
  "description": "Index method. Omitted, btree."
200
+ },
201
+ "unique": {
202
+ "type": "boolean",
203
+ "description": "A unique index. With \"where\" it is unique among the rows the condition selects, which a unique constraint cannot be (unique among the rows that are not deleted)."
204
+ },
205
+ "where": {
206
+ "type": "string",
207
+ "minLength": 1,
208
+ "description": "A partial index: SQL condition over the table's columns, e.g. \"is_deleted = false\". Only the rows it selects are indexed, and a query uses the index only when its own filter implies the condition. One condition, without ';', '$' or comments. Changing it rebuilds the index on upgrade."
200
209
  }
201
210
  }
202
211
  }
@@ -209,6 +218,26 @@
209
218
  "$ref": "#/$defs/periodConfig",
210
219
  "description": "Period entity configuration. Requires 'period' trait."
211
220
  },
221
+ "periodGuards": {
222
+ "type": "array",
223
+ "description": "Closed-period locks for a document that posts to no register. Each guard names a period entity, the date the document's period follows from, and the column that references the period. The platform fills that column from the date and makes it a foreign key, so a document is written only into a period that exists and is open, and a period documents refer to cannot be deleted. Not allowed on an extension.",
224
+ "items": {
225
+ "type": "object",
226
+ "required": ["periodEntity", "periodDateField", "periodField", "lockedFields"],
227
+ "properties": {
228
+ "periodEntity": { "type": "string", "description": "The period entity ('period' trait): this module's, or another module's as 'module.entity'." },
229
+ "periodDateField": { "type": "string", "description": "The document's date column the period is resolved from." },
230
+ "periodField": { "type": "string", "description": "The document's column referencing the period's key (varchar, like the key). Filled by the platform from the date; whatever a writer puts there is replaced." },
231
+ "periodKeyField": { "type": "string", "default": "period_key", "description": "The period entity's key column. Must be its primary key or unique." },
232
+ "periodClosedField": { "type": "string", "default": "closed", "description": "The period entity's closed flag." },
233
+ "lockedFields": { "type": "array", "items": { "type": "string" }, "minItems": 1, "description": "Fields a closed period freezes. Insert and delete are always refused there, and the date is always watched; [\"periodDateField\"] refuses just that, [\"*\"] freezes the whole row." },
234
+ "lineEntity": { "type": "string", "description": "The document's line entity, guarded through its header's date." },
235
+ "lineField": { "type": "string", "description": "The line's foreign key to the header." },
236
+ "lockedLineFields": { "type": "array", "items": { "type": "string" }, "minItems": 1, "description": "Line fields a closed period freezes; [\"*\"] for the whole row. Required with lineEntity." }
237
+ },
238
+ "additionalProperties": false
239
+ }
240
+ },
212
241
  "accumulation": {
213
242
  "$ref": "#/$defs/accumulationConfig",
214
243
  "description": "Accumulation registry configuration (simple document without lines). Requires 'accumulation' trait."
@@ -18,11 +18,14 @@
18
18
  },
19
19
  "rights": {
20
20
  "type": "object",
21
- "description": "Entity rights: entity code → rights string",
21
+ "description": "Security object → rights string. Keys are PREFIX-NAMESPACED so an action and an entity may share a code: a bare key is an entity code in this module ('invoice'), 'module.entity' is an entity owned by a module this one depends on ('parties.party'), 'action:<action_cd>' is an action from this module's ui/actions.json, and 'sp:<sp_cd>' is a stored procedure from logic/stored_procedures.json ('sp:module.sp_cd' for a dependency's), and 'report:<report_cd>' is a report from ui/reports.json ('report:module.report_cd' for a dependency's). A grant on an action written WITHOUT the 'action:' prefix is read as an entity code, resolves to nothing, and is silently dropped at install — action.execute then returns PERMISSION_DENIED.",
22
+ "propertyNames": {
23
+ "pattern": "^(action:[A-Za-z_][A-Za-z0-9_-]*|(sp|report):([A-Za-z_][A-Za-z0-9_-]*\\.)?[A-Za-z_][A-Za-z0-9_-]*|([A-Za-z_][A-Za-z0-9_-]*\\.)?[A-Za-z_][A-Za-z0-9_-]*)$"
24
+ },
22
25
  "additionalProperties": {
23
26
  "type": "string",
24
27
  "pattern": "^[SIUDCE]*$",
25
- "description": "Rights: S=Select, I=Insert, U=Update, D=Delete, C=Clone, E=Execute"
28
+ "description": "Rights: S=Select, I=Insert, U=Update, D=Delete, C=Clone, E=Execute. Entity objects take any of SIUDC; actions, stored procedures and reports take E."
26
29
  }
27
30
  }
28
31
  },