@hamak/smart-data-dico 1.6.1 → 1.8.1

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.
@@ -19143,18 +19143,18 @@ var require_router = __commonJS({
19143
19143
  var toString2 = Object.prototype.toString;
19144
19144
  var proto = module.exports = function(options2) {
19145
19145
  var opts = options2 || {};
19146
- function router25(req, res, next) {
19147
- router25.handle(req, res, next);
19148
- }
19149
- __name(router25, "router");
19150
- setPrototypeOf(router25, proto);
19151
- router25.params = {};
19152
- router25._params = [];
19153
- router25.caseSensitive = opts.caseSensitive;
19154
- router25.mergeParams = opts.mergeParams;
19155
- router25.strict = opts.strict;
19156
- router25.stack = [];
19157
- return router25;
19146
+ function router27(req, res, next) {
19147
+ router27.handle(req, res, next);
19148
+ }
19149
+ __name(router27, "router");
19150
+ setPrototypeOf(router27, proto);
19151
+ router27.params = {};
19152
+ router27._params = [];
19153
+ router27.caseSensitive = opts.caseSensitive;
19154
+ router27.mergeParams = opts.mergeParams;
19155
+ router27.strict = opts.strict;
19156
+ router27.stack = [];
19157
+ return router27;
19158
19158
  };
19159
19159
  proto.param = /* @__PURE__ */ __name(function param(name21, fn) {
19160
19160
  if (typeof name21 === "function") {
@@ -22278,7 +22278,7 @@ var require_application = __commonJS({
22278
22278
  "backend/node_modules/express/lib/application.js"(exports, module) {
22279
22279
  "use strict";
22280
22280
  var finalhandler = require_finalhandler();
22281
- var Router29 = require_router();
22281
+ var Router31 = require_router();
22282
22282
  var methods = require_methods();
22283
22283
  var middleware = require_init();
22284
22284
  var query = require_query();
@@ -22343,7 +22343,7 @@ var require_application = __commonJS({
22343
22343
  }, "defaultConfiguration");
22344
22344
  app2.lazyrouter = /* @__PURE__ */ __name(function lazyrouter() {
22345
22345
  if (!this._router) {
22346
- this._router = new Router29({
22346
+ this._router = new Router31({
22347
22347
  caseSensitive: this.enabled("case sensitive routing"),
22348
22348
  strict: this.enabled("strict routing")
22349
22349
  });
@@ -22352,17 +22352,17 @@ var require_application = __commonJS({
22352
22352
  }
22353
22353
  }, "lazyrouter");
22354
22354
  app2.handle = /* @__PURE__ */ __name(function handle(req, res, callback) {
22355
- var router25 = this._router;
22355
+ var router27 = this._router;
22356
22356
  var done = callback || finalhandler(req, res, {
22357
22357
  env: this.get("env"),
22358
22358
  onerror: logerror.bind(this)
22359
22359
  });
22360
- if (!router25) {
22360
+ if (!router27) {
22361
22361
  debug2("no routes defined on app");
22362
22362
  done();
22363
22363
  return;
22364
22364
  }
22365
- router25.handle(req, res, done);
22365
+ router27.handle(req, res, done);
22366
22366
  }, "handle");
22367
22367
  app2.use = /* @__PURE__ */ __name(function use(fn) {
22368
22368
  var offset = 0;
@@ -22382,15 +22382,15 @@ var require_application = __commonJS({
22382
22382
  throw new TypeError("app.use() requires a middleware function");
22383
22383
  }
22384
22384
  this.lazyrouter();
22385
- var router25 = this._router;
22385
+ var router27 = this._router;
22386
22386
  fns.forEach(function(fn2) {
22387
22387
  if (!fn2 || !fn2.handle || !fn2.set) {
22388
- return router25.use(path14, fn2);
22388
+ return router27.use(path14, fn2);
22389
22389
  }
22390
22390
  debug2(".use app under %s", path14);
22391
22391
  fn2.mountpath = path14;
22392
22392
  fn2.parent = this;
22393
- router25.use(path14, /* @__PURE__ */ __name(function mounted_app(req, res, next) {
22393
+ router27.use(path14, /* @__PURE__ */ __name(function mounted_app(req, res, next) {
22394
22394
  var orig = req.app;
22395
22395
  fn2.handle(req, res, function(err) {
22396
22396
  setPrototypeOf(req, orig.request);
@@ -24275,7 +24275,7 @@ var require_express = __commonJS({
24275
24275
  var mixin = require_merge_descriptors();
24276
24276
  var proto = require_application();
24277
24277
  var Route = require_route();
24278
- var Router29 = require_router();
24278
+ var Router31 = require_router();
24279
24279
  var req = require_request();
24280
24280
  var res = require_response();
24281
24281
  exports = module.exports = createApplication;
@@ -24299,7 +24299,7 @@ var require_express = __commonJS({
24299
24299
  exports.request = req;
24300
24300
  exports.response = res;
24301
24301
  exports.Route = Route;
24302
- exports.Router = Router29;
24302
+ exports.Router = Router31;
24303
24303
  exports.json = bodyParser2.json;
24304
24304
  exports.query = require_query();
24305
24305
  exports.raw = bodyParser2.raw;
@@ -43763,7 +43763,7 @@ var init_git_service = __esm({
43763
43763
  // backend/node_modules/@hamak/ui-remote-git-fs-backend/dist/routes/git-routes.js
43764
43764
  function createGitRoutes(config3) {
43765
43765
  const { gitService, debug: debug2 } = config3;
43766
- const router25 = (0, import_express2.Router)();
43766
+ const router27 = (0, import_express2.Router)();
43767
43767
  const log2 = /* @__PURE__ */ __name((message, ...args) => {
43768
43768
  if (debug2) {
43769
43769
  console.log(`[git-routes] ${message}`, ...args);
@@ -43777,21 +43777,21 @@ function createGitRoutes(config3) {
43777
43777
  const extractPath = /* @__PURE__ */ __name((req) => {
43778
43778
  return req.params[0] || "";
43779
43779
  }, "extractPath");
43780
- router25.get("/:workspaceId/status/*", asyncHandler(async (req, res) => {
43780
+ router27.get("/:workspaceId/status/*", asyncHandler(async (req, res) => {
43781
43781
  const { workspaceId } = req.params;
43782
43782
  const path14 = extractPath(req);
43783
43783
  log2("Status request", { workspaceId, path: path14 });
43784
43784
  const status = await gitService.getStatus(workspaceId, path14);
43785
43785
  res.json(status);
43786
43786
  }));
43787
- router25.get("/:workspaceId/branches/*", asyncHandler(async (req, res) => {
43787
+ router27.get("/:workspaceId/branches/*", asyncHandler(async (req, res) => {
43788
43788
  const { workspaceId } = req.params;
43789
43789
  const path14 = extractPath(req);
43790
43790
  log2("List branches request", { workspaceId, path: path14 });
43791
43791
  const branches = await gitService.listBranches(workspaceId, path14);
43792
43792
  res.json(branches);
43793
43793
  }));
43794
- router25.post("/:workspaceId/checkout/*", asyncHandler(async (req, res) => {
43794
+ router27.post("/:workspaceId/checkout/*", asyncHandler(async (req, res) => {
43795
43795
  const { workspaceId } = req.params;
43796
43796
  const path14 = extractPath(req);
43797
43797
  const { branch, create } = req.body;
@@ -43805,7 +43805,7 @@ function createGitRoutes(config3) {
43805
43805
  await gitService.checkout(workspaceId, path14, branch, create);
43806
43806
  res.json({ success: true, branch });
43807
43807
  }));
43808
- router25.post("/:workspaceId/branch/*", asyncHandler(async (req, res) => {
43808
+ router27.post("/:workspaceId/branch/*", asyncHandler(async (req, res) => {
43809
43809
  const { workspaceId } = req.params;
43810
43810
  const path14 = extractPath(req);
43811
43811
  const { branch, startPoint } = req.body;
@@ -43819,7 +43819,7 @@ function createGitRoutes(config3) {
43819
43819
  await gitService.createBranch(workspaceId, path14, branch, startPoint);
43820
43820
  res.json({ success: true, branch });
43821
43821
  }));
43822
- router25.post("/:workspaceId/stage/*", asyncHandler(async (req, res) => {
43822
+ router27.post("/:workspaceId/stage/*", asyncHandler(async (req, res) => {
43823
43823
  const { workspaceId } = req.params;
43824
43824
  const path14 = extractPath(req);
43825
43825
  const { files } = req.body;
@@ -43827,7 +43827,7 @@ function createGitRoutes(config3) {
43827
43827
  await gitService.stage(workspaceId, path14, files);
43828
43828
  res.json({ success: true });
43829
43829
  }));
43830
- router25.post("/:workspaceId/unstage/*", asyncHandler(async (req, res) => {
43830
+ router27.post("/:workspaceId/unstage/*", asyncHandler(async (req, res) => {
43831
43831
  const { workspaceId } = req.params;
43832
43832
  const path14 = extractPath(req);
43833
43833
  const { files } = req.body;
@@ -43835,7 +43835,7 @@ function createGitRoutes(config3) {
43835
43835
  await gitService.unstage(workspaceId, path14, files);
43836
43836
  res.json({ success: true });
43837
43837
  }));
43838
- router25.post("/:workspaceId/commit/*", asyncHandler(async (req, res) => {
43838
+ router27.post("/:workspaceId/commit/*", asyncHandler(async (req, res) => {
43839
43839
  const { workspaceId } = req.params;
43840
43840
  const path14 = extractPath(req);
43841
43841
  const { message } = req.body;
@@ -43849,7 +43849,7 @@ function createGitRoutes(config3) {
43849
43849
  const result = await gitService.commit(workspaceId, path14, message);
43850
43850
  res.json(result);
43851
43851
  }));
43852
- router25.post("/:workspaceId/pull/*", asyncHandler(async (req, res) => {
43852
+ router27.post("/:workspaceId/pull/*", asyncHandler(async (req, res) => {
43853
43853
  const { workspaceId } = req.params;
43854
43854
  const path14 = extractPath(req);
43855
43855
  const { remote, branch } = req.body;
@@ -43857,7 +43857,7 @@ function createGitRoutes(config3) {
43857
43857
  const result = await gitService.pull(workspaceId, path14, remote, branch);
43858
43858
  res.json(result);
43859
43859
  }));
43860
- router25.post("/:workspaceId/push/*", asyncHandler(async (req, res) => {
43860
+ router27.post("/:workspaceId/push/*", asyncHandler(async (req, res) => {
43861
43861
  const { workspaceId } = req.params;
43862
43862
  const path14 = extractPath(req);
43863
43863
  const { remote, branch } = req.body;
@@ -43865,7 +43865,7 @@ function createGitRoutes(config3) {
43865
43865
  await gitService.push(workspaceId, path14, remote, branch);
43866
43866
  res.json({ success: true });
43867
43867
  }));
43868
- router25.post("/:workspaceId/fetch/*", asyncHandler(async (req, res) => {
43868
+ router27.post("/:workspaceId/fetch/*", asyncHandler(async (req, res) => {
43869
43869
  const { workspaceId } = req.params;
43870
43870
  const path14 = extractPath(req);
43871
43871
  const { remote } = req.body;
@@ -43873,7 +43873,7 @@ function createGitRoutes(config3) {
43873
43873
  await gitService.fetch(workspaceId, path14, remote);
43874
43874
  res.json({ success: true });
43875
43875
  }));
43876
- router25.get("/:workspaceId/diff/*", asyncHandler(async (req, res) => {
43876
+ router27.get("/:workspaceId/diff/*", asyncHandler(async (req, res) => {
43877
43877
  const { workspaceId } = req.params;
43878
43878
  const path14 = extractPath(req);
43879
43879
  const { file: file2, staged } = req.query;
@@ -43881,7 +43881,7 @@ function createGitRoutes(config3) {
43881
43881
  const result = await gitService.diff(workspaceId, path14, file2, staged === "true");
43882
43882
  res.json(result);
43883
43883
  }));
43884
- router25.get("/:workspaceId/log/*", asyncHandler(async (req, res) => {
43884
+ router27.get("/:workspaceId/log/*", asyncHandler(async (req, res) => {
43885
43885
  const { workspaceId } = req.params;
43886
43886
  const path14 = extractPath(req);
43887
43887
  const { maxCount, file: file2 } = req.query;
@@ -43889,21 +43889,21 @@ function createGitRoutes(config3) {
43889
43889
  const result = await gitService.log(workspaceId, path14, maxCount ? parseInt(maxCount, 10) : void 0, file2);
43890
43890
  res.json(result);
43891
43891
  }));
43892
- router25.get("/:workspaceId/is-repo/*", asyncHandler(async (req, res) => {
43892
+ router27.get("/:workspaceId/is-repo/*", asyncHandler(async (req, res) => {
43893
43893
  const { workspaceId } = req.params;
43894
43894
  const path14 = extractPath(req);
43895
43895
  log2("Is repo request", { workspaceId, path: path14 });
43896
43896
  const isRepo = await gitService.isRepo(workspaceId, path14);
43897
43897
  res.json({ isRepo });
43898
43898
  }));
43899
- router25.get("/:workspaceId/repo-root/*", asyncHandler(async (req, res) => {
43899
+ router27.get("/:workspaceId/repo-root/*", asyncHandler(async (req, res) => {
43900
43900
  const { workspaceId } = req.params;
43901
43901
  const path14 = extractPath(req);
43902
43902
  log2("Repo root request", { workspaceId, path: path14 });
43903
43903
  const repoRoot = await gitService.getRepoRoot(workspaceId, path14);
43904
43904
  res.json({ repoRoot });
43905
43905
  }));
43906
- return router25;
43906
+ return router27;
43907
43907
  }
43908
43908
  function gitErrorHandler(err, req, res, next) {
43909
43909
  console.error("[git-routes] Error:", err);
@@ -44158,10 +44158,14 @@ var init_dist = __esm({
44158
44158
  // backend/src/utils/fileOperations.ts
44159
44159
  var fileOperations_exports = {};
44160
44160
  __export(fileOperations_exports, {
44161
+ deleteAction: () => deleteAction,
44161
44162
  deleteCaseFile: () => deleteCaseFile,
44162
44163
  deleteEntityFile: () => deleteEntityFile,
44164
+ deleteStateMachine: () => deleteStateMachine,
44163
44165
  ensureDirectoryStructure: () => ensureDirectoryStructure,
44164
44166
  ensurePackageDirectoryStructure: () => ensurePackageDirectoryStructure,
44167
+ findActionOwner: () => findActionOwner,
44168
+ findStateMachineOwner: () => findStateMachineOwner,
44165
44169
  getAllRelationships: () => getAllRelationships,
44166
44170
  getPackagePath: () => getPackagePath,
44167
44171
  getReservedPackageFiles: () => getReservedPackageFiles,
@@ -44179,6 +44183,7 @@ __export(fileOperations_exports, {
44179
44183
  mergePackageSections: () => mergePackageSections,
44180
44184
  normalizeEntityMetadata: () => normalizeEntityMetadata,
44181
44185
  parseSectionsFromString: () => parseSectionsFromString,
44186
+ readActionsForEntity: () => readActionsForEntity,
44182
44187
  readCaseFile: () => readCaseFile,
44183
44188
  readCaseRules: () => readCaseRules,
44184
44189
  readComments: () => readComments,
@@ -44187,6 +44192,8 @@ __export(fileOperations_exports, {
44187
44192
  readGlobalRules: () => readGlobalRules,
44188
44193
  readPackageRules: () => readPackageRules,
44189
44194
  readRelationshipsFile: () => readRelationshipsFile,
44195
+ readStateMachinesForEntity: () => readStateMachinesForEntity,
44196
+ writeAction: () => writeAction,
44190
44197
  writeCaseFile: () => writeCaseFile,
44191
44198
  writeCaseRules: () => writeCaseRules,
44192
44199
  writeComments: () => writeComments,
@@ -44195,7 +44202,8 @@ __export(fileOperations_exports, {
44195
44202
  writeEntityRules: () => writeEntityRules,
44196
44203
  writeGlobalRules: () => writeGlobalRules,
44197
44204
  writePackageRules: () => writePackageRules,
44198
- writeRelationshipsFile: () => writeRelationshipsFile
44205
+ writeRelationshipsFile: () => writeRelationshipsFile,
44206
+ writeStateMachine: () => writeStateMachine
44199
44207
  });
44200
44208
  import path4 from "path";
44201
44209
  function getStorage() {
@@ -44330,11 +44338,11 @@ async function listMicroservices() {
44330
44338
  function parseSectionsFromString(raw, label, filename) {
44331
44339
  try {
44332
44340
  const parsed = import_yaml.default.parse(raw);
44333
- if (!parsed) return { entities: [], relationships: [], rules: [], cases: [] };
44341
+ if (!parsed) return { entities: [], relationships: [], rules: [], cases: [], actions: [], stateMachines: [] };
44334
44342
  if (typeof parsed === "object" && !Array.isArray(parsed) && typeof parsed.uuid === "string" && Array.isArray(parsed.attributes)) {
44335
- return { entities: [parsed], relationships: [], rules: [], cases: [] };
44343
+ return { entities: [parsed], relationships: [], rules: [], cases: [], actions: [], stateMachines: [] };
44336
44344
  }
44337
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && ("entities" in parsed || "relationships" in parsed || "rules" in parsed || "cases" in parsed || "perspectives" in parsed)) {
44345
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && ("entities" in parsed || "relationships" in parsed || "rules" in parsed || "cases" in parsed || "perspectives" in parsed || "actions" in parsed || "stateMachines" in parsed)) {
44338
44346
  let cases = [];
44339
44347
  if (Array.isArray(parsed.cases)) {
44340
44348
  cases = parsed.cases;
@@ -44346,27 +44354,29 @@ function parseSectionsFromString(raw, label, filename) {
44346
44354
  entities: Array.isArray(parsed.entities) ? parsed.entities : [],
44347
44355
  relationships: Array.isArray(parsed.relationships) ? parsed.relationships : [],
44348
44356
  rules: Array.isArray(parsed.rules) ? parsed.rules : [],
44349
- cases
44357
+ cases,
44358
+ actions: Array.isArray(parsed.actions) ? parsed.actions : [],
44359
+ stateMachines: Array.isArray(parsed.stateMachines) ? parsed.stateMachines : []
44350
44360
  };
44351
44361
  }
44352
44362
  if (Array.isArray(parsed) && filename) {
44353
44363
  if (filename === "relationships.yaml") {
44354
- return { entities: [], relationships: parsed, rules: [], cases: [] };
44364
+ return { entities: [], relationships: parsed, rules: [], cases: [], actions: [], stateMachines: [] };
44355
44365
  }
44356
44366
  if (filename === "rules.yaml" || filename.endsWith(".rules.yaml")) {
44357
- return { entities: [], relationships: [], rules: parsed, cases: [] };
44367
+ return { entities: [], relationships: [], rules: parsed, cases: [], actions: [], stateMachines: [] };
44358
44368
  }
44359
44369
  }
44360
- return { entities: [], relationships: [], rules: [], cases: [] };
44370
+ return { entities: [], relationships: [], rules: [], cases: [], actions: [], stateMachines: [] };
44361
44371
  } catch (e) {
44362
44372
  logger.warn(`Failed to parse YAML: ${label}: ${e}`);
44363
- return { entities: [], relationships: [], rules: [], cases: [] };
44373
+ return { entities: [], relationships: [], rules: [], cases: [], actions: [], stateMachines: [] };
44364
44374
  }
44365
44375
  }
44366
44376
  async function parseSectionsFromStorage(p, label) {
44367
44377
  const content = await readOrNull(p);
44368
44378
  if (content === null) {
44369
- return { entities: [], relationships: [], rules: [], cases: [] };
44379
+ return { entities: [], relationships: [], rules: [], cases: [], actions: [], stateMachines: [] };
44370
44380
  }
44371
44381
  const filename = path4.basename(String(p));
44372
44382
  return parseSectionsFromString(content, label, filename);
@@ -44378,12 +44388,18 @@ function mergePackageSections(packageName, parsed) {
44378
44388
  relationships: [],
44379
44389
  rules: [],
44380
44390
  cases: [],
44391
+ actions: [],
44392
+ stateMachines: [],
44381
44393
  ownership: {
44382
44394
  entityByName: /* @__PURE__ */ new Map(),
44383
44395
  entityByUuid: /* @__PURE__ */ new Map(),
44384
44396
  relationshipByUuid: /* @__PURE__ */ new Map(),
44385
44397
  ruleByUuid: /* @__PURE__ */ new Map(),
44386
- caseByUuid: /* @__PURE__ */ new Map()
44398
+ caseByUuid: /* @__PURE__ */ new Map(),
44399
+ actionByUuid: /* @__PURE__ */ new Map(),
44400
+ stateMachineByUuid: /* @__PURE__ */ new Map(),
44401
+ actionByOwnerAndName: /* @__PURE__ */ new Map(),
44402
+ stateMachineByOwnerAndName: /* @__PURE__ */ new Map()
44387
44403
  }
44388
44404
  };
44389
44405
  for (const { label, sections } of parsed) {
@@ -44439,6 +44455,44 @@ function mergePackageSections(packageName, parsed) {
44439
44455
  model.ownership.caseByUuid.set(c.uuid, label);
44440
44456
  model.cases.push(c);
44441
44457
  }
44458
+ for (const action of sections.actions || []) {
44459
+ if (!action?.uuid || !action?.name || !action?.ownerRef) continue;
44460
+ const byUuid = model.ownership.actionByUuid.get(action.uuid);
44461
+ if (byUuid) {
44462
+ throw new Error(
44463
+ `Duplicate action uuid '${action.uuid}' in package '${packageName}': ${byUuid} and ${label}`
44464
+ );
44465
+ }
44466
+ const ownerNameKey = `${action.ownerRef}::${action.name}`;
44467
+ const byOwnerAndName = model.ownership.actionByOwnerAndName.get(ownerNameKey);
44468
+ if (byOwnerAndName) {
44469
+ throw new Error(
44470
+ `Duplicate action name '${action.name}' for ownerRef '${action.ownerRef}' in package '${packageName}': ${byOwnerAndName} and ${label}`
44471
+ );
44472
+ }
44473
+ model.ownership.actionByUuid.set(action.uuid, label);
44474
+ model.ownership.actionByOwnerAndName.set(ownerNameKey, label);
44475
+ model.actions.push(action);
44476
+ }
44477
+ for (const sm of sections.stateMachines || []) {
44478
+ if (!sm?.uuid || !sm?.name || !sm?.ownerRef) continue;
44479
+ const byUuid = model.ownership.stateMachineByUuid.get(sm.uuid);
44480
+ if (byUuid) {
44481
+ throw new Error(
44482
+ `Duplicate stateMachine uuid '${sm.uuid}' in package '${packageName}': ${byUuid} and ${label}`
44483
+ );
44484
+ }
44485
+ const ownerNameKey = `${sm.ownerRef}::${sm.name}`;
44486
+ const byOwnerAndName = model.ownership.stateMachineByOwnerAndName.get(ownerNameKey);
44487
+ if (byOwnerAndName) {
44488
+ throw new Error(
44489
+ `Duplicate stateMachine name '${sm.name}' for ownerRef '${sm.ownerRef}' in package '${packageName}': ${byOwnerAndName} and ${label}`
44490
+ );
44491
+ }
44492
+ model.ownership.stateMachineByUuid.set(sm.uuid, label);
44493
+ model.ownership.stateMachineByOwnerAndName.set(ownerNameKey, label);
44494
+ model.stateMachines.push(sm);
44495
+ }
44442
44496
  }
44443
44497
  return model;
44444
44498
  }
@@ -44451,6 +44505,8 @@ async function writeSectionsToStorage(p, sections) {
44451
44505
  if (sections.relationships.length > 0) payload.relationships = sections.relationships;
44452
44506
  if (sections.rules.length > 0) payload.rules = sections.rules;
44453
44507
  if (sections.cases.length > 0) payload.cases = sections.cases;
44508
+ if (sections.actions.length > 0) payload.actions = sections.actions;
44509
+ if (sections.stateMachines.length > 0) payload.stateMachines = sections.stateMachines;
44454
44510
  if (Object.keys(payload).length === 0) {
44455
44511
  await deleteIfExists(p);
44456
44512
  return;
@@ -44563,7 +44619,9 @@ async function writeEntityFile(entity, packageName) {
44563
44619
  entities: [entity],
44564
44620
  relationships: [],
44565
44621
  rules: [],
44566
- cases: []
44622
+ cases: [],
44623
+ actions: [],
44624
+ stateMachines: []
44567
44625
  });
44568
44626
  logger.info(`Entity written to new file: ${String(newFilePath)}`);
44569
44627
  await commitChanges(String(newFilePath), `Added entity: ${entity.name} (${entity.uuid})`);
@@ -45006,6 +45064,186 @@ async function listAllDictionaries() {
45006
45064
  return [];
45007
45065
  }
45008
45066
  }
45067
+ async function findActionOwner(actionUuid) {
45068
+ const packages = await listPackages();
45069
+ for (const pkg of packages) {
45070
+ const files = await listPackageYamlFilePaths(pkg);
45071
+ for (const f of files) {
45072
+ const s = await parseSectionsFromStorage(f, String(f));
45073
+ if (s.actions.some((a) => a.uuid === actionUuid)) {
45074
+ return { packageName: pkg, filePath: String(f) };
45075
+ }
45076
+ }
45077
+ }
45078
+ return null;
45079
+ }
45080
+ async function readActionsForEntity(entityUuid) {
45081
+ const packages = await listPackages();
45082
+ const result = [];
45083
+ for (const pkg of packages) {
45084
+ try {
45085
+ const model = await loadPackage(pkg);
45086
+ result.push(...model.actions.filter((a) => a.ownerRef === entityUuid));
45087
+ } catch {
45088
+ }
45089
+ }
45090
+ return result;
45091
+ }
45092
+ async function writeAction(action, packageName) {
45093
+ try {
45094
+ await ensurePackageDirectoryStructure(packageName);
45095
+ const files = await listPackageYamlFilePaths(packageName);
45096
+ let ownerFile = null;
45097
+ let ownerSections = null;
45098
+ for (const f of files) {
45099
+ const s = await parseSectionsFromStorage(f, String(f));
45100
+ if (s.actions.some((a) => a.uuid === action.uuid)) {
45101
+ ownerFile = f;
45102
+ ownerSections = s;
45103
+ break;
45104
+ }
45105
+ }
45106
+ if (ownerFile && ownerSections) {
45107
+ ownerSections.actions = ownerSections.actions.filter((a) => a.uuid !== action.uuid);
45108
+ ownerSections.actions.push(action);
45109
+ await writeSectionsToStorage(ownerFile, ownerSections);
45110
+ await commitChanges(String(ownerFile), `Updated action: ${action.name} (${action.uuid})`);
45111
+ return { ok: true, physicalPath: String(ownerFile) };
45112
+ }
45113
+ const entityModel = await loadPackage(packageName);
45114
+ const ownerEntityFile = entityModel.ownership.entityByUuid.get(action.ownerRef);
45115
+ if (ownerEntityFile) {
45116
+ const filePath = pathOf(ownerEntityFile);
45117
+ const s = await parseSectionsFromStorage(filePath, ownerEntityFile);
45118
+ s.actions = s.actions.filter((a) => a.uuid !== action.uuid);
45119
+ s.actions.push(action);
45120
+ await writeSectionsToStorage(filePath, s);
45121
+ await commitChanges(ownerEntityFile, `Added action: ${action.name} (${action.uuid})`);
45122
+ return { ok: true, physicalPath: ownerEntityFile };
45123
+ }
45124
+ const newFilePath = pathOf(`${packageName}/${sanitizeFsName(action.name)}.actions.yaml`);
45125
+ await writeSectionsToStorage(newFilePath, {
45126
+ entities: [],
45127
+ relationships: [],
45128
+ rules: [],
45129
+ cases: [],
45130
+ actions: [action],
45131
+ stateMachines: []
45132
+ });
45133
+ await commitChanges(String(newFilePath), `Added action: ${action.name} (${action.uuid})`);
45134
+ return { ok: true, physicalPath: String(newFilePath) };
45135
+ } catch (error48) {
45136
+ logger.error(`Error writing action: ${error48}`);
45137
+ return { ok: false };
45138
+ }
45139
+ }
45140
+ async function deleteAction(uuid3) {
45141
+ try {
45142
+ const owner = await findActionOwner(uuid3);
45143
+ if (!owner) return { ok: false };
45144
+ const ownerPath = pathOf(owner.filePath);
45145
+ const s = await parseSectionsFromStorage(ownerPath, owner.filePath);
45146
+ const before = s.actions.length;
45147
+ s.actions = s.actions.filter((a) => a.uuid !== uuid3);
45148
+ if (s.actions.length === before) return { ok: false };
45149
+ await writeSectionsToStorage(ownerPath, s);
45150
+ await commitChanges(owner.filePath, `Deleted action ${uuid3}`);
45151
+ return { ok: true, physicalPath: owner.filePath };
45152
+ } catch (error48) {
45153
+ logger.error(`Error deleting action ${uuid3}: ${error48}`);
45154
+ return { ok: false };
45155
+ }
45156
+ }
45157
+ async function findStateMachineOwner(smUuid) {
45158
+ const packages = await listPackages();
45159
+ for (const pkg of packages) {
45160
+ const files = await listPackageYamlFilePaths(pkg);
45161
+ for (const f of files) {
45162
+ const s = await parseSectionsFromStorage(f, String(f));
45163
+ if (s.stateMachines.some((m) => m.uuid === smUuid)) {
45164
+ return { packageName: pkg, filePath: String(f) };
45165
+ }
45166
+ }
45167
+ }
45168
+ return null;
45169
+ }
45170
+ async function readStateMachinesForEntity(entityUuid) {
45171
+ const packages = await listPackages();
45172
+ const result = [];
45173
+ for (const pkg of packages) {
45174
+ try {
45175
+ const model = await loadPackage(pkg);
45176
+ result.push(...model.stateMachines.filter((m) => m.ownerRef === entityUuid));
45177
+ } catch {
45178
+ }
45179
+ }
45180
+ return result;
45181
+ }
45182
+ async function writeStateMachine(sm, packageName) {
45183
+ try {
45184
+ await ensurePackageDirectoryStructure(packageName);
45185
+ const files = await listPackageYamlFilePaths(packageName);
45186
+ let ownerFile = null;
45187
+ let ownerSections = null;
45188
+ for (const f of files) {
45189
+ const s = await parseSectionsFromStorage(f, String(f));
45190
+ if (s.stateMachines.some((m) => m.uuid === sm.uuid)) {
45191
+ ownerFile = f;
45192
+ ownerSections = s;
45193
+ break;
45194
+ }
45195
+ }
45196
+ if (ownerFile && ownerSections) {
45197
+ ownerSections.stateMachines = ownerSections.stateMachines.filter((m) => m.uuid !== sm.uuid);
45198
+ ownerSections.stateMachines.push(sm);
45199
+ await writeSectionsToStorage(ownerFile, ownerSections);
45200
+ await commitChanges(String(ownerFile), `Updated stateMachine: ${sm.name} (${sm.uuid})`);
45201
+ return { ok: true, physicalPath: String(ownerFile) };
45202
+ }
45203
+ const entityModel = await loadPackage(packageName);
45204
+ const ownerEntityFile = entityModel.ownership.entityByUuid.get(sm.ownerRef);
45205
+ if (ownerEntityFile) {
45206
+ const filePath = pathOf(ownerEntityFile);
45207
+ const s = await parseSectionsFromStorage(filePath, ownerEntityFile);
45208
+ s.stateMachines = s.stateMachines.filter((m) => m.uuid !== sm.uuid);
45209
+ s.stateMachines.push(sm);
45210
+ await writeSectionsToStorage(filePath, s);
45211
+ await commitChanges(ownerEntityFile, `Added stateMachine: ${sm.name} (${sm.uuid})`);
45212
+ return { ok: true, physicalPath: ownerEntityFile };
45213
+ }
45214
+ const newFilePath = pathOf(`${packageName}/${sanitizeFsName(sm.name)}.statemachine.yaml`);
45215
+ await writeSectionsToStorage(newFilePath, {
45216
+ entities: [],
45217
+ relationships: [],
45218
+ rules: [],
45219
+ cases: [],
45220
+ actions: [],
45221
+ stateMachines: [sm]
45222
+ });
45223
+ await commitChanges(String(newFilePath), `Added stateMachine: ${sm.name} (${sm.uuid})`);
45224
+ return { ok: true, physicalPath: String(newFilePath) };
45225
+ } catch (error48) {
45226
+ logger.error(`Error writing stateMachine: ${error48}`);
45227
+ return { ok: false };
45228
+ }
45229
+ }
45230
+ async function deleteStateMachine(uuid3) {
45231
+ try {
45232
+ const owner = await findStateMachineOwner(uuid3);
45233
+ if (!owner) return { ok: false };
45234
+ const ownerPath = pathOf(owner.filePath);
45235
+ const s = await parseSectionsFromStorage(ownerPath, owner.filePath);
45236
+ const before = s.stateMachines.length;
45237
+ s.stateMachines = s.stateMachines.filter((m) => m.uuid !== uuid3);
45238
+ if (s.stateMachines.length === before) return { ok: false };
45239
+ await writeSectionsToStorage(ownerPath, s);
45240
+ await commitChanges(owner.filePath, `Deleted stateMachine ${uuid3}`);
45241
+ return { ok: true, physicalPath: owner.filePath };
45242
+ } catch (error48) {
45243
+ logger.error(`Error deleting stateMachine ${uuid3}: ${error48}`);
45244
+ return { ok: false };
45245
+ }
45246
+ }
45009
45247
  var import_yaml, WS, getDataDir, RESERVED_DIRS, RESERVED_PACKAGE_FILES, VALIDATION_FIELD_NAMES, gitServiceInstance;
45010
45248
  var init_fileOperations = __esm({
45011
45249
  "backend/src/utils/fileOperations.ts"() {
@@ -45083,6 +45321,14 @@ var init_fileOperations = __esm({
45083
45321
  __name(deleteCaseFile, "deleteCaseFile");
45084
45322
  __name(writeDictionaryMetadata, "writeDictionaryMetadata");
45085
45323
  __name(listAllDictionaries, "listAllDictionaries");
45324
+ __name(findActionOwner, "findActionOwner");
45325
+ __name(readActionsForEntity, "readActionsForEntity");
45326
+ __name(writeAction, "writeAction");
45327
+ __name(deleteAction, "deleteAction");
45328
+ __name(findStateMachineOwner, "findStateMachineOwner");
45329
+ __name(readStateMachinesForEntity, "readStateMachinesForEntity");
45330
+ __name(writeStateMachine, "writeStateMachine");
45331
+ __name(deleteStateMachine, "deleteStateMachine");
45086
45332
  }
45087
45333
  });
45088
45334
 
@@ -45302,7 +45548,11 @@ var init_dictionaryService = __esm({
45302
45548
  const model = await loadPackage(packageName);
45303
45549
  entities = model.entities;
45304
45550
  relationships = model.relationships;
45305
- cases = model.cases.map((c) => ({ uuid: c.uuid, name: c.name }));
45551
+ cases = model.cases.map((c) => ({
45552
+ uuid: c.uuid,
45553
+ name: c.name,
45554
+ ...c.description !== void 0 ? { description: c.description } : {}
45555
+ }));
45306
45556
  } catch (e) {
45307
45557
  logger.warn(`Failed to load package ${packageName}: ${e}`);
45308
45558
  }
@@ -99596,7 +99846,7 @@ async function auth(provider, options2) {
99596
99846
  throw error48;
99597
99847
  }
99598
99848
  }
99599
- async function authInternal(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl, fetchFn }) {
99849
+ async function authInternal(provider, { serverUrl: serverUrl2, authorizationCode, scope, resourceMetadataUrl, fetchFn }) {
99600
99850
  const cachedState = await provider.discoveryState?.();
99601
99851
  let resourceMetadata;
99602
99852
  let authorizationServerUrl;
@@ -99611,7 +99861,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
99611
99861
  metadata = cachedState.authorizationServerMetadata ?? await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn });
99612
99862
  if (!resourceMetadata) {
99613
99863
  try {
99614
- resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl }, fetchFn);
99864
+ resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl2, { resourceMetadataUrl: effectiveResourceMetadataUrl }, fetchFn);
99615
99865
  } catch {
99616
99866
  }
99617
99867
  }
@@ -99624,7 +99874,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
99624
99874
  });
99625
99875
  }
99626
99876
  } else {
99627
- const serverInfo = await discoverOAuthServerInfo(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl, fetchFn });
99877
+ const serverInfo = await discoverOAuthServerInfo(serverUrl2, { resourceMetadataUrl: effectiveResourceMetadataUrl, fetchFn });
99628
99878
  authorizationServerUrl = serverInfo.authorizationServerUrl;
99629
99879
  metadata = serverInfo.authorizationServerMetadata;
99630
99880
  resourceMetadata = serverInfo.resourceMetadata;
@@ -99635,7 +99885,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
99635
99885
  authorizationServerMetadata: metadata
99636
99886
  });
99637
99887
  }
99638
- const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
99888
+ const resource = await selectResourceURL(serverUrl2, provider, resourceMetadata);
99639
99889
  const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
99640
99890
  let clientInformation = await Promise.resolve(provider.clientInformation());
99641
99891
  if (!clientInformation) {
@@ -99721,8 +99971,8 @@ function isHttpsUrl(value) {
99721
99971
  return false;
99722
99972
  }
99723
99973
  }
99724
- async function selectResourceURL(serverUrl, provider, resourceMetadata) {
99725
- const defaultResource = resourceUrlFromServerUrl(serverUrl);
99974
+ async function selectResourceURL(serverUrl2, provider, resourceMetadata) {
99975
+ const defaultResource = resourceUrlFromServerUrl(serverUrl2);
99726
99976
  if (provider.validateResourceURL) {
99727
99977
  return await provider.validateResourceURL(defaultResource, resourceMetadata?.resource);
99728
99978
  }
@@ -99771,8 +100021,8 @@ function extractFieldFromWwwAuth(response, fieldName) {
99771
100021
  }
99772
100022
  return null;
99773
100023
  }
99774
- async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
99775
- const response = await discoverMetadataWithFallback(serverUrl, "oauth-protected-resource", fetchFn, {
100024
+ async function discoverOAuthProtectedResourceMetadata(serverUrl2, opts, fetchFn = fetch) {
100025
+ const response = await discoverMetadataWithFallback(serverUrl2, "oauth-protected-resource", fetchFn, {
99776
100026
  protocolVersion: opts?.protocolVersion,
99777
100027
  metadataUrl: opts?.resourceMetadataUrl
99778
100028
  });
@@ -99815,8 +100065,8 @@ async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
99815
100065
  function shouldAttemptFallback(response, pathname) {
99816
100066
  return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
99817
100067
  }
99818
- async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
99819
- const issuer = new URL(serverUrl);
100068
+ async function discoverMetadataWithFallback(serverUrl2, wellKnownType, fetchFn, opts) {
100069
+ const issuer = new URL(serverUrl2);
99820
100070
  const protocolVersion = opts?.protocolVersion ?? LATEST_PROTOCOL_VERSION;
99821
100071
  let url2;
99822
100072
  if (opts?.metadataUrl) {
@@ -99892,18 +100142,18 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
99892
100142
  }
99893
100143
  return void 0;
99894
100144
  }
99895
- async function discoverOAuthServerInfo(serverUrl, opts) {
100145
+ async function discoverOAuthServerInfo(serverUrl2, opts) {
99896
100146
  let resourceMetadata;
99897
100147
  let authorizationServerUrl;
99898
100148
  try {
99899
- resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: opts?.resourceMetadataUrl }, opts?.fetchFn);
100149
+ resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl2, { resourceMetadataUrl: opts?.resourceMetadataUrl }, opts?.fetchFn);
99900
100150
  if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {
99901
100151
  authorizationServerUrl = resourceMetadata.authorization_servers[0];
99902
100152
  }
99903
100153
  } catch {
99904
100154
  }
99905
100155
  if (!authorizationServerUrl) {
99906
- authorizationServerUrl = String(new URL("/", serverUrl));
100156
+ authorizationServerUrl = String(new URL("/", serverUrl2));
99907
100157
  }
99908
100158
  const authorizationServerMetadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn: opts?.fetchFn });
99909
100159
  return {
@@ -114060,21 +114310,21 @@ var chat_routes_exports = {};
114060
114310
  __export(chat_routes_exports, {
114061
114311
  default: () => chat_routes_default
114062
114312
  });
114063
- var import_express16, router15, chat_routes_default;
114313
+ var import_express18, router17, chat_routes_default;
114064
114314
  var init_chat_routes = __esm({
114065
114315
  "backend/src/routes/ai/chat.routes.ts"() {
114066
114316
  "use strict";
114067
- import_express16 = __toESM(require_express2(), 1);
114317
+ import_express18 = __toESM(require_express2(), 1);
114068
114318
  init_aiController();
114069
- router15 = (0, import_express16.Router)();
114070
- router15.post("/api/ai/chat", aiChat);
114071
- router15.get("/api/ai/status", aiStatus);
114072
- router15.get("/api/ai/config", aiGetConfig);
114073
- router15.post("/api/ai/config", aiSaveConfig);
114074
- router15.get("/api/ai/tools", aiTools);
114075
- router15.get("/api/ai/mentions/search", aiMentionsSearch);
114076
- router15.post("/api/ai/test-tools", aiTestTools);
114077
- chat_routes_default = router15;
114319
+ router17 = (0, import_express18.Router)();
114320
+ router17.post("/api/ai/chat", aiChat);
114321
+ router17.get("/api/ai/status", aiStatus);
114322
+ router17.get("/api/ai/config", aiGetConfig);
114323
+ router17.post("/api/ai/config", aiSaveConfig);
114324
+ router17.get("/api/ai/tools", aiTools);
114325
+ router17.get("/api/ai/mentions/search", aiMentionsSearch);
114326
+ router17.post("/api/ai/test-tools", aiTestTools);
114327
+ chat_routes_default = router17;
114078
114328
  }
114079
114329
  });
114080
114330
 
@@ -114083,19 +114333,19 @@ var conversation_routes_exports = {};
114083
114333
  __export(conversation_routes_exports, {
114084
114334
  default: () => conversation_routes_default
114085
114335
  });
114086
- var import_express17, router16, conversation_routes_default;
114336
+ var import_express19, router18, conversation_routes_default;
114087
114337
  var init_conversation_routes = __esm({
114088
114338
  "backend/src/routes/ai/conversation.routes.ts"() {
114089
114339
  "use strict";
114090
- import_express17 = __toESM(require_express2(), 1);
114340
+ import_express19 = __toESM(require_express2(), 1);
114091
114341
  init_aiController();
114092
- router16 = (0, import_express17.Router)();
114093
- router16.get("/api/ai/conversations", listConversations);
114094
- router16.get("/api/ai/conversations/:id", getConversation);
114095
- router16.post("/api/ai/conversations", saveConversation);
114096
- router16.patch("/api/ai/conversations/:id", patchConversation);
114097
- router16.delete("/api/ai/conversations/:id", deleteConversation);
114098
- conversation_routes_default = router16;
114342
+ router18 = (0, import_express19.Router)();
114343
+ router18.get("/api/ai/conversations", listConversations);
114344
+ router18.get("/api/ai/conversations/:id", getConversation);
114345
+ router18.post("/api/ai/conversations", saveConversation);
114346
+ router18.patch("/api/ai/conversations/:id", patchConversation);
114347
+ router18.delete("/api/ai/conversations/:id", deleteConversation);
114348
+ conversation_routes_default = router18;
114099
114349
  }
114100
114350
  });
114101
114351
 
@@ -114104,19 +114354,19 @@ var prompt_routes_exports = {};
114104
114354
  __export(prompt_routes_exports, {
114105
114355
  default: () => prompt_routes_default
114106
114356
  });
114107
- var import_express18, router17, prompt_routes_default;
114357
+ var import_express20, router19, prompt_routes_default;
114108
114358
  var init_prompt_routes = __esm({
114109
114359
  "backend/src/routes/ai/prompt.routes.ts"() {
114110
114360
  "use strict";
114111
- import_express18 = __toESM(require_express2(), 1);
114361
+ import_express20 = __toESM(require_express2(), 1);
114112
114362
  init_aiController();
114113
- router17 = (0, import_express18.Router)();
114114
- router17.get("/api/ai/prompts", listPrompts);
114115
- router17.get("/api/ai/prompts/:id", getPrompt);
114116
- router17.post("/api/ai/prompts", createPrompt);
114117
- router17.put("/api/ai/prompts/:id", updatePrompt);
114118
- router17.delete("/api/ai/prompts/:id", deletePrompt);
114119
- prompt_routes_default = router17;
114363
+ router19 = (0, import_express20.Router)();
114364
+ router19.get("/api/ai/prompts", listPrompts);
114365
+ router19.get("/api/ai/prompts/:id", getPrompt);
114366
+ router19.post("/api/ai/prompts", createPrompt);
114367
+ router19.put("/api/ai/prompts/:id", updatePrompt);
114368
+ router19.delete("/api/ai/prompts/:id", deletePrompt);
114369
+ prompt_routes_default = router19;
114120
114370
  }
114121
114371
  });
114122
114372
 
@@ -114152,19 +114402,19 @@ function mergeMaskedRecord(incoming, existing) {
114152
114402
  }
114153
114403
  return out;
114154
114404
  }
114155
- var import_express19, router18, MASK, looksLikeEnvRef, mcp_routes_default;
114405
+ var import_express21, router20, MASK, looksLikeEnvRef, mcp_routes_default;
114156
114406
  var init_mcp_routes = __esm({
114157
114407
  "backend/src/routes/ai/mcp.routes.ts"() {
114158
114408
  "use strict";
114159
- import_express19 = __toESM(require_express2(), 1);
114409
+ import_express21 = __toESM(require_express2(), 1);
114160
114410
  init_mcpClientRegistry();
114161
- router18 = (0, import_express19.Router)();
114411
+ router20 = (0, import_express21.Router)();
114162
114412
  MASK = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
114163
114413
  looksLikeEnvRef = /* @__PURE__ */ __name((v) => /\$\{[^}]+\}/.test(v), "looksLikeEnvRef");
114164
114414
  __name(maskRecord, "maskRecord");
114165
114415
  __name(maskConnection, "maskConnection");
114166
114416
  __name(mergeMaskedRecord, "mergeMaskedRecord");
114167
- router18.get("/api/ai/mcp/connections", (_req, res) => {
114417
+ router20.get("/api/ai/mcp/connections", (_req, res) => {
114168
114418
  try {
114169
114419
  const connections = mcpClientRegistry.getConnections().map(maskConnection);
114170
114420
  res.json({ data: connections });
@@ -114173,7 +114423,7 @@ var init_mcp_routes = __esm({
114173
114423
  res.status(500).json({ error: msg });
114174
114424
  }
114175
114425
  });
114176
- router18.post("/api/ai/mcp/connections", (req, res) => {
114426
+ router20.post("/api/ai/mcp/connections", (req, res) => {
114177
114427
  try {
114178
114428
  const body = req.body;
114179
114429
  const errors = mcpClientRegistry.validateConnection(body);
@@ -114193,7 +114443,7 @@ var init_mcp_routes = __esm({
114193
114443
  res.status(500).json({ error: msg });
114194
114444
  }
114195
114445
  });
114196
- router18.delete("/api/ai/mcp/connections/:id", (req, res) => {
114446
+ router20.delete("/api/ai/mcp/connections/:id", (req, res) => {
114197
114447
  try {
114198
114448
  const { id } = req.params;
114199
114449
  const deleted = mcpClientRegistry.deleteConnection(id);
@@ -114206,7 +114456,7 @@ var init_mcp_routes = __esm({
114206
114456
  res.status(500).json({ error: msg });
114207
114457
  }
114208
114458
  });
114209
- router18.post("/api/ai/mcp/connections/:id/test", async (req, res) => {
114459
+ router20.post("/api/ai/mcp/connections/:id/test", async (req, res) => {
114210
114460
  try {
114211
114461
  const { id } = req.params;
114212
114462
  const result = await mcpClientRegistry.testConnection(id);
@@ -114220,7 +114470,7 @@ var init_mcp_routes = __esm({
114220
114470
  res.status(500).json({ error: msg });
114221
114471
  }
114222
114472
  });
114223
- mcp_routes_default = router18;
114473
+ mcp_routes_default = router20;
114224
114474
  }
114225
114475
  });
114226
114476
 
@@ -114399,16 +114649,16 @@ var init_workspace_manager = __esm({
114399
114649
  });
114400
114650
 
114401
114651
  // backend/node_modules/@hamak/filesystem-server-impl/dist/routing/file-router.js
114402
- var import_express26, FileRouter;
114652
+ var import_express28, FileRouter;
114403
114653
  var init_file_router = __esm({
114404
114654
  "backend/node_modules/@hamak/filesystem-server-impl/dist/routing/file-router.js"() {
114405
- import_express26 = __toESM(require_express2(), 1);
114655
+ import_express28 = __toESM(require_express2(), 1);
114406
114656
  FileRouter = class {
114407
114657
  static {
114408
114658
  __name(this, "FileRouter");
114409
114659
  }
114410
114660
  constructor(workspaceManager2, options2) {
114411
- this.router = (0, import_express26.Router)();
114661
+ this.router = (0, import_express28.Router)();
114412
114662
  this.workspaceManager = workspaceManager2;
114413
114663
  this.enricherRegistry = options2?.enricherRegistry;
114414
114664
  this.initializeRoutes();
@@ -114535,7 +114785,7 @@ var init_file_router = __esm({
114535
114785
 
114536
114786
  // backend/node_modules/@hamak/filesystem-server-impl/dist/routing/create-router.js
114537
114787
  function createFileSystemRouter(workspaceManager2, config3) {
114538
- const app2 = (0, import_express27.Router)();
114788
+ const app2 = (0, import_express29.Router)();
114539
114789
  if (config3.enableCors ?? DEFAULT_FILESYSTEM_SERVER_CONFIG.enableCors) {
114540
114790
  app2.use((0, import_cors.default)());
114541
114791
  }
@@ -114545,10 +114795,10 @@ function createFileSystemRouter(workspaceManager2, config3) {
114545
114795
  app2.use(mountPath, fileRouter2.router);
114546
114796
  return app2;
114547
114797
  }
114548
- var import_express27, import_cors, import_body_parser;
114798
+ var import_express29, import_cors, import_body_parser;
114549
114799
  var init_create_router = __esm({
114550
114800
  "backend/node_modules/@hamak/filesystem-server-impl/dist/routing/create-router.js"() {
114551
- import_express27 = __toESM(require_express2(), 1);
114801
+ import_express29 = __toESM(require_express2(), 1);
114552
114802
  import_cors = __toESM(require_lib3(), 1);
114553
114803
  import_body_parser = __toESM(require_body_parser(), 1);
114554
114804
  init_dist9();
@@ -154254,8 +154504,8 @@ function respondError(res, err, fallbackStatus = 500) {
154254
154504
  res.status(fallbackStatus).json({ error: message });
154255
154505
  }
154256
154506
  function createLogicalFsRouter() {
154257
- const router25 = (0, import_express28.Router)();
154258
- router25.get("/:workspace/files/*", async (req, res) => {
154507
+ const router27 = (0, import_express30.Router)();
154508
+ router27.get("/:workspace/files/*", async (req, res) => {
154259
154509
  try {
154260
154510
  const ws = wsId(req.params.workspace);
154261
154511
  const projection = getProjection(ws);
@@ -154273,7 +154523,7 @@ function createLogicalFsRouter() {
154273
154523
  respondError(res, err);
154274
154524
  }
154275
154525
  });
154276
- router25.get("/:workspace/read/*", async (req, res) => {
154526
+ router27.get("/:workspace/read/*", async (req, res) => {
154277
154527
  try {
154278
154528
  const ws = wsId(req.params.workspace);
154279
154529
  const projection = getProjection(ws);
@@ -154317,9 +154567,9 @@ function createLogicalFsRouter() {
154317
154567
  respondError(res, err);
154318
154568
  }
154319
154569
  }, "writeHandler");
154320
- router25.put("/:workspace/put/*", writeHandler);
154321
- router25.post("/:workspace/post/*", writeHandler);
154322
- router25.delete("/:workspace/delete/*", async (req, res) => {
154570
+ router27.put("/:workspace/put/*", writeHandler);
154571
+ router27.post("/:workspace/post/*", writeHandler);
154572
+ router27.delete("/:workspace/delete/*", async (req, res) => {
154323
154573
  try {
154324
154574
  const ws = wsId(req.params.workspace);
154325
154575
  const projection = getProjection(ws);
@@ -154331,7 +154581,7 @@ function createLogicalFsRouter() {
154331
154581
  respondError(res, err);
154332
154582
  }
154333
154583
  });
154334
- router25.get("/:workspace/by-uuid/:uuid", (req, res) => {
154584
+ router27.get("/:workspace/by-uuid/:uuid", (req, res) => {
154335
154585
  try {
154336
154586
  const ws = wsId(req.params.workspace);
154337
154587
  const index = getUuidIndex(ws);
@@ -154346,13 +154596,13 @@ function createLogicalFsRouter() {
154346
154596
  respondError(res, err);
154347
154597
  }
154348
154598
  });
154349
- return router25;
154599
+ return router27;
154350
154600
  }
154351
- var import_express28;
154601
+ var import_express30;
154352
154602
  var init_logicalFsRouter = __esm({
154353
154603
  "backend/src/routes/logicalFsRouter.ts"() {
154354
154604
  "use strict";
154355
- import_express28 = __toESM(require_express2(), 1);
154605
+ import_express30 = __toESM(require_express2(), 1);
154356
154606
  init_types();
154357
154607
  init_ProjectionRegistry();
154358
154608
  init_UuidIndex();
@@ -154363,14 +154613,14 @@ var init_logicalFsRouter = __esm({
154363
154613
  });
154364
154614
 
154365
154615
  // backend/src/server.ts
154366
- var import_express29 = __toESM(require_express2(), 1);
154616
+ var import_express31 = __toESM(require_express2(), 1);
154367
154617
  var import_cors2 = __toESM(require_lib3(), 1);
154368
154618
  var import_dotenv2 = __toESM(require_main(), 1);
154369
154619
  import fs5 from "fs";
154370
154620
  import path13 from "path";
154371
154621
 
154372
154622
  // backend/src/routes/index.ts
154373
- var import_express25 = __toESM(require_express2(), 1);
154623
+ var import_express27 = __toESM(require_express2(), 1);
154374
154624
 
154375
154625
  // backend/src/routes/auth.routes.ts
154376
154626
  var import_express = __toESM(require_express2(), 1);
@@ -154548,7 +154798,7 @@ router.get("/api/auth/me", verifyToken, getCurrentUser);
154548
154798
  var auth_routes_default = router;
154549
154799
 
154550
154800
  // backend/src/routes/data-dictionary/index.ts
154551
- var import_express15 = __toESM(require_express2(), 1);
154801
+ var import_express17 = __toESM(require_express2(), 1);
154552
154802
 
154553
154803
  // backend/src/routes/data-dictionary/package.routes.ts
154554
154804
  var import_express3 = __toESM(require_express2(), 1);
@@ -156731,13 +156981,13 @@ async function resolveProjectPrefixAtRef(ref) {
156731
156981
  logger.warn(`Could not resolve git repo root: ${e}`);
156732
156982
  return null;
156733
156983
  }
156734
- const candidates = [];
156984
+ const candidates2 = [];
156735
156985
  const rel = path6.relative(repoRoot, config.dataDir);
156736
156986
  const primary = !rel || rel === "." || rel.startsWith("..") ? "" : rel.replace(/\\/g, "/") + "/";
156737
- candidates.push(primary);
156738
- if (primary !== "data-dictionaries/") candidates.push("data-dictionaries/");
156739
- if (primary !== "") candidates.push("");
156740
- for (const prefix of candidates) {
156987
+ candidates2.push(primary);
156988
+ if (primary !== "data-dictionaries/") candidates2.push("data-dictionaries/");
156989
+ if (primary !== "") candidates2.push("");
156990
+ for (const prefix of candidates2) {
156741
156991
  const marker21 = await readFileAtRef(ref, `${prefix}dico.config.json`);
156742
156992
  if (marker21 !== null) return prefix;
156743
156993
  }
@@ -160592,49 +160842,562 @@ router13.post("/api/revert", authorizeJwt(["admin" /* ADMIN */]), async (req, re
160592
160842
  });
160593
160843
  var publish_routes_default = router13;
160594
160844
 
160595
- // backend/src/routes/data-dictionary/index.ts
160845
+ // backend/src/routes/data-dictionary/action.routes.ts
160846
+ var import_express15 = __toESM(require_express2(), 1);
160847
+
160848
+ // backend/src/models/Action.ts
160849
+ var FLOW_STEP_KINDS = /* @__PURE__ */ new Set([
160850
+ "assign",
160851
+ "emitEvent",
160852
+ "invokeAction",
160853
+ "branch",
160854
+ "wait",
160855
+ "callExternal"
160856
+ ]);
160857
+
160858
+ // backend/src/services/actionService.ts
160859
+ init_fileOperations();
160860
+ init_uuid();
160861
+ init_logger();
160862
+ function checkInvokeRefs(steps, knownActionUuids, pathPrefix, errors) {
160863
+ for (let i = 0; i < steps.length; i++) {
160864
+ const step = steps[i];
160865
+ const path14 = `${pathPrefix}[${i}]`;
160866
+ if (step.kind === "invokeAction") {
160867
+ if (!knownActionUuids.has(step.actionRef)) {
160868
+ errors.push({
160869
+ field: `${path14}.actionRef`,
160870
+ message: `invokeAction references unknown action UUID '${step.actionRef}' at ${path14}`
160871
+ });
160872
+ }
160873
+ } else if (step.kind === "branch") {
160874
+ if (step.then && step.then.length > 0) {
160875
+ checkInvokeRefs(step.then, knownActionUuids, `${path14}.then`, errors);
160876
+ }
160877
+ if (step.else && step.else.length > 0) {
160878
+ checkInvokeRefs(step.else, knownActionUuids, `${path14}.else`, errors);
160879
+ }
160880
+ }
160881
+ }
160882
+ }
160883
+ __name(checkInvokeRefs, "checkInvokeRefs");
160884
+ function validateAction(action, knownActionUuids) {
160885
+ const errors = [];
160886
+ if (!action.uuid) errors.push({ field: "uuid", message: "uuid is required" });
160887
+ if (!action.name) errors.push({ field: "name", message: "name is required" });
160888
+ if (!action.ownerRef) errors.push({ field: "ownerRef", message: "ownerRef is required" });
160889
+ if (action.params && action.params.length > 0) {
160890
+ const names = action.params.map((p) => p.name);
160891
+ const unique = new Set(names);
160892
+ if (unique.size !== names.length) {
160893
+ errors.push({ field: "params", message: "Action params must have unique names" });
160894
+ }
160895
+ for (const p of action.params) {
160896
+ if (!p.name) errors.push({ field: "params", message: "Each param must have a name" });
160897
+ if (!p.type) errors.push({ field: "params", message: `Param '${p.name}' must have a type` });
160898
+ }
160899
+ }
160900
+ if (action.flow) {
160901
+ for (let i = 0; i < action.flow.length; i++) {
160902
+ const step = action.flow[i];
160903
+ if (!step.kind || !FLOW_STEP_KINDS.has(step.kind)) {
160904
+ errors.push({
160905
+ field: `flow[${i}].kind`,
160906
+ message: `Invalid flow step kind '${step.kind}'. Must be one of: ${[...FLOW_STEP_KINDS].join(", ")}`
160907
+ });
160908
+ }
160909
+ }
160910
+ if (knownActionUuids !== void 0) {
160911
+ checkInvokeRefs(action.flow, knownActionUuids, "flow", errors);
160912
+ }
160913
+ }
160914
+ return errors;
160915
+ }
160916
+ __name(validateAction, "validateAction");
160917
+ var ActionService = class {
160918
+ static {
160919
+ __name(this, "ActionService");
160920
+ }
160921
+ /** List all actions. Optionally filter by ownerRef (entity UUID). */
160922
+ async list(filters = {}) {
160923
+ try {
160924
+ if (filters.ownerRef) {
160925
+ return await readActionsForEntity(filters.ownerRef);
160926
+ }
160927
+ const packages = await listPackages();
160928
+ const result = [];
160929
+ for (const pkg of packages) {
160930
+ const model = await loadPackage(pkg);
160931
+ result.push(...model.actions);
160932
+ }
160933
+ return result;
160934
+ } catch (error48) {
160935
+ logger.error(`Error listing actions: ${error48}`);
160936
+ return [];
160937
+ }
160938
+ }
160939
+ /** Get one action by UUID. */
160940
+ async getByUuid(uuid3) {
160941
+ try {
160942
+ const owner = await findActionOwner(uuid3);
160943
+ if (!owner) return null;
160944
+ const model = await loadPackage(owner.packageName);
160945
+ return model.actions.find((a) => a.uuid === uuid3) ?? null;
160946
+ } catch (error48) {
160947
+ logger.error(`Error getting action ${uuid3}: ${error48}`);
160948
+ return null;
160949
+ }
160950
+ }
160951
+ /**
160952
+ * Create a new action. `ownerRef` must point to an existing entity UUID.
160953
+ * Returns the created action or a validation error list.
160954
+ */
160955
+ async create(data) {
160956
+ const action = {
160957
+ uuid: data.uuid || generateUUID(),
160958
+ name: data.name || "",
160959
+ description: data.description,
160960
+ ownerRef: data.ownerRef || "",
160961
+ internal: data.internal ?? false,
160962
+ params: data.params ?? [],
160963
+ returns: data.returns,
160964
+ flow: data.flow ?? [],
160965
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
160966
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
160967
+ };
160968
+ const { packageModel, packageName } = await this.resolvePackageContext(action.ownerRef);
160969
+ if (!packageModel || !packageName) {
160970
+ return { errors: [{ field: "ownerRef", message: `Entity '${action.ownerRef}' not found in any package` }] };
160971
+ }
160972
+ const knownActionUuids = new Set(packageModel.ownership.actionByUuid.keys());
160973
+ knownActionUuids.add(action.uuid);
160974
+ const errors = validateAction(action, knownActionUuids);
160975
+ if (errors.length > 0) return { errors };
160976
+ const result = await writeAction(action, packageName);
160977
+ if (!result.ok) {
160978
+ return { errors: [{ field: "_", message: "Failed to persist action" }] };
160979
+ }
160980
+ return action;
160981
+ }
160982
+ /**
160983
+ * Update an existing action.
160984
+ */
160985
+ async update(uuid3, data) {
160986
+ const existing = await this.getByUuid(uuid3);
160987
+ if (!existing) return null;
160988
+ const updated = {
160989
+ ...existing,
160990
+ ...data,
160991
+ uuid: uuid3,
160992
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
160993
+ };
160994
+ const { packageModel, packageName } = await this.resolvePackageContext(updated.ownerRef);
160995
+ if (!packageModel || !packageName) {
160996
+ return { errors: [{ field: "ownerRef", message: `Entity '${updated.ownerRef}' not found in any package` }] };
160997
+ }
160998
+ const knownActionUuids = new Set(packageModel.ownership.actionByUuid.keys());
160999
+ knownActionUuids.add(uuid3);
161000
+ const errors = validateAction(updated, knownActionUuids);
161001
+ if (errors.length > 0) return { errors };
161002
+ const result = await writeAction(updated, packageName);
161003
+ if (!result.ok) {
161004
+ return { errors: [{ field: "_", message: "Failed to persist action" }] };
161005
+ }
161006
+ return updated;
161007
+ }
161008
+ /**
161009
+ * Delete an action by UUID.
161010
+ */
161011
+ async delete(uuid3) {
161012
+ const result = await deleteAction(uuid3);
161013
+ return result.ok;
161014
+ }
161015
+ /** Find the package and loaded model for the entity with the given UUID. */
161016
+ async resolvePackageContext(entityUuid) {
161017
+ const packages = await listPackages();
161018
+ for (const pkg of packages) {
161019
+ const model = await loadPackage(pkg);
161020
+ if (model.ownership.entityByUuid.has(entityUuid)) {
161021
+ return { packageModel: model, packageName: pkg };
161022
+ }
161023
+ }
161024
+ return { packageModel: null, packageName: null };
161025
+ }
161026
+ };
161027
+ var actionService = new ActionService();
161028
+
161029
+ // backend/src/controllers/actionController.ts
161030
+ init_logger();
161031
+ var listActionsForEntity = /* @__PURE__ */ __name(async (req, res) => {
161032
+ try {
161033
+ const actions = await actionService.list({ ownerRef: req.params.uuid });
161034
+ res.json({ message: "Success", data: actions });
161035
+ } catch (error48) {
161036
+ logger.error("Error listing actions for entity", error48);
161037
+ res.status(500).json({ message: "Error listing actions for entity", error: error48 });
161038
+ }
161039
+ }, "listActionsForEntity");
161040
+ var getAction = /* @__PURE__ */ __name(async (req, res) => {
161041
+ try {
161042
+ const action = await actionService.getByUuid(req.params.uuid);
161043
+ if (!action) return res.status(404).json({ message: "Action not found" });
161044
+ res.json({ message: "Success", data: action });
161045
+ } catch (error48) {
161046
+ logger.error("Error fetching action", error48);
161047
+ res.status(500).json({ message: "Error fetching action", error: error48 });
161048
+ }
161049
+ }, "getAction");
161050
+ var createAction = /* @__PURE__ */ __name(async (req, res) => {
161051
+ try {
161052
+ const result = await actionService.create(req.body);
161053
+ if ("errors" in result) {
161054
+ return res.status(400).json({ message: "Failed to create action", errors: result.errors });
161055
+ }
161056
+ res.status(201).json({ message: "Action created successfully", data: result });
161057
+ } catch (error48) {
161058
+ logger.error("Error creating action", error48);
161059
+ res.status(500).json({ message: "Error creating action", error: error48 });
161060
+ }
161061
+ }, "createAction");
161062
+ var updateAction = /* @__PURE__ */ __name(async (req, res) => {
161063
+ try {
161064
+ const result = await actionService.update(req.params.uuid, req.body);
161065
+ if (result === null) {
161066
+ return res.status(404).json({ message: "Action not found" });
161067
+ }
161068
+ if ("errors" in result) {
161069
+ return res.status(400).json({ message: "Failed to update action", errors: result.errors });
161070
+ }
161071
+ res.json({ message: "Action updated successfully", data: result });
161072
+ } catch (error48) {
161073
+ logger.error("Error updating action", error48);
161074
+ res.status(500).json({ message: "Error updating action", error: error48 });
161075
+ }
161076
+ }, "updateAction");
161077
+ var deleteAction2 = /* @__PURE__ */ __name(async (req, res) => {
161078
+ try {
161079
+ const ok2 = await actionService.delete(req.params.uuid);
161080
+ if (!ok2) return res.status(404).json({ message: "Action not found" });
161081
+ res.json({ message: "Action deleted successfully" });
161082
+ } catch (error48) {
161083
+ logger.error("Error deleting action", error48);
161084
+ res.status(500).json({ message: "Error deleting action", error: error48 });
161085
+ }
161086
+ }, "deleteAction");
161087
+
161088
+ // backend/src/routes/data-dictionary/action.routes.ts
160596
161089
  var router14 = (0, import_express15.Router)();
160597
- router14.use(package_routes_default);
160598
- router14.use(relationship_routes_default);
160599
- router14.use(entity_routes_default);
160600
- router14.use(stereotype_routes_default);
160601
- router14.use(case_routes_default);
160602
- router14.use(rule_routes_default);
160603
- router14.use(integrity_routes_default);
160604
- router14.use(model_metadata_routes_default);
160605
- router14.use(dico_config_routes_default);
160606
- router14.use(diff_routes_default);
160607
- router14.use(import_export_routes_default);
160608
- router14.use(publish_routes_default);
160609
- var data_dictionary_default = router14;
161090
+ router14.get("/api/entities/:uuid/actions", listActionsForEntity);
161091
+ router14.get("/api/actions/:uuid", getAction);
161092
+ router14.post("/api/actions", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), createAction);
161093
+ router14.put("/api/actions/:uuid", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), updateAction);
161094
+ router14.delete("/api/actions/:uuid", authorizeJwt(["admin" /* ADMIN */]), deleteAction2);
161095
+ var action_routes_default = router14;
161096
+
161097
+ // backend/src/routes/data-dictionary/state-machine.routes.ts
161098
+ var import_express16 = __toESM(require_express2(), 1);
161099
+
161100
+ // backend/src/services/stateMachineService.ts
161101
+ init_fileOperations();
161102
+ init_uuid();
161103
+ init_logger();
161104
+ function validateStateMachine(sm, knownActionUuids, ownerAttributes) {
161105
+ const errors = [];
161106
+ if (!sm.uuid) errors.push({ field: "uuid", message: "uuid is required" });
161107
+ if (!sm.name) errors.push({ field: "name", message: "name is required" });
161108
+ if (!sm.ownerRef) errors.push({ field: "ownerRef", message: "ownerRef is required" });
161109
+ if (!sm.initialState) errors.push({ field: "initialState", message: "initialState is required" });
161110
+ if (!sm.states || sm.states.length === 0) {
161111
+ errors.push({ field: "states", message: "At least one state is required" });
161112
+ }
161113
+ if (sm.stateAttribute && ownerAttributes !== void 0) {
161114
+ if (!ownerAttributes.includes(sm.stateAttribute)) {
161115
+ errors.push({
161116
+ field: "stateAttribute",
161117
+ message: `stateAttribute '${sm.stateAttribute}' is not an attribute on the owner entity`
161118
+ });
161119
+ }
161120
+ }
161121
+ if (sm.states && sm.states.length > 0 && sm.initialState) {
161122
+ const stateNames = new Set(sm.states.map((s) => s.name));
161123
+ if (stateNames.size !== sm.states.length) {
161124
+ errors.push({ field: "states", message: "State names must be unique within a state machine" });
161125
+ }
161126
+ if (!stateNames.has(sm.initialState)) {
161127
+ errors.push({ field: "initialState", message: `initialState '${sm.initialState}' is not a declared state` });
161128
+ }
161129
+ if (sm.transitions) {
161130
+ const transitionUuids = /* @__PURE__ */ new Set();
161131
+ for (let i = 0; i < sm.transitions.length; i++) {
161132
+ const t = sm.transitions[i];
161133
+ if (!t.uuid) {
161134
+ errors.push({ field: `transitions[${i}].uuid`, message: "Transition uuid is required" });
161135
+ } else if (transitionUuids.has(t.uuid)) {
161136
+ errors.push({ field: `transitions[${i}].uuid`, message: `Duplicate transition uuid '${t.uuid}'` });
161137
+ } else {
161138
+ transitionUuids.add(t.uuid);
161139
+ }
161140
+ if (!t.from) {
161141
+ errors.push({ field: `transitions[${i}].from`, message: "Transition from is required" });
161142
+ } else if (t.from !== "*" && !stateNames.has(t.from)) {
161143
+ errors.push({
161144
+ field: `transitions[${i}].from`,
161145
+ message: `Transition from '${t.from}' is not a declared state (use "*" for wildcard)`
161146
+ });
161147
+ }
161148
+ if (!t.to) {
161149
+ errors.push({ field: `transitions[${i}].to`, message: "Transition to is required" });
161150
+ } else if (!stateNames.has(t.to)) {
161151
+ errors.push({
161152
+ field: `transitions[${i}].to`,
161153
+ message: `Transition to '${t.to}' is not a declared state`
161154
+ });
161155
+ }
161156
+ if (!t.on) {
161157
+ errors.push({ field: `transitions[${i}].on`, message: "Transition event (on) is required" });
161158
+ }
161159
+ if (knownActionUuids !== void 0 && t.invoke) {
161160
+ for (const actionUuid of t.invoke) {
161161
+ if (!knownActionUuids.has(actionUuid)) {
161162
+ errors.push({
161163
+ field: `transitions[${i}].invoke`,
161164
+ message: `invoke references unknown action UUID '${actionUuid}' in transition '${t.uuid}'`
161165
+ });
161166
+ }
161167
+ }
161168
+ }
161169
+ }
161170
+ }
161171
+ }
161172
+ return errors;
161173
+ }
161174
+ __name(validateStateMachine, "validateStateMachine");
161175
+ var StateMachineService = class {
161176
+ static {
161177
+ __name(this, "StateMachineService");
161178
+ }
161179
+ /** List all state machines. Optionally filter by ownerRef (entity UUID). */
161180
+ async list(filters = {}) {
161181
+ try {
161182
+ if (filters.ownerRef) {
161183
+ return await readStateMachinesForEntity(filters.ownerRef);
161184
+ }
161185
+ const packages = await listPackages();
161186
+ const result = [];
161187
+ for (const pkg of packages) {
161188
+ const model = await loadPackage(pkg);
161189
+ result.push(...model.stateMachines);
161190
+ }
161191
+ return result;
161192
+ } catch (error48) {
161193
+ logger.error(`Error listing state machines: ${error48}`);
161194
+ return [];
161195
+ }
161196
+ }
161197
+ /** Get one state machine by UUID. */
161198
+ async getByUuid(uuid3) {
161199
+ try {
161200
+ const owner = await findStateMachineOwner(uuid3);
161201
+ if (!owner) return null;
161202
+ const model = await loadPackage(owner.packageName);
161203
+ return model.stateMachines.find((m) => m.uuid === uuid3) ?? null;
161204
+ } catch (error48) {
161205
+ logger.error(`Error getting stateMachine ${uuid3}: ${error48}`);
161206
+ return null;
161207
+ }
161208
+ }
161209
+ /**
161210
+ * Create a new state machine.
161211
+ */
161212
+ async create(data) {
161213
+ const sm = {
161214
+ uuid: data.uuid || generateUUID(),
161215
+ name: data.name || "",
161216
+ description: data.description,
161217
+ ownerRef: data.ownerRef || "",
161218
+ stateAttribute: data.stateAttribute,
161219
+ initialState: data.initialState || "",
161220
+ states: data.states ?? [],
161221
+ transitions: data.transitions ?? [],
161222
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
161223
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
161224
+ };
161225
+ const { packageModel, packageName } = await this.resolvePackageContext(sm.ownerRef);
161226
+ if (!packageModel || !packageName) {
161227
+ return { errors: [{ field: "ownerRef", message: `Entity '${sm.ownerRef}' not found in any package` }] };
161228
+ }
161229
+ const knownActionUuids = new Set(packageModel.ownership.actionByUuid.keys());
161230
+ const ownerEntity = packageModel.entities.find((e) => e.uuid === sm.ownerRef);
161231
+ const ownerAttributes = ownerEntity?.attributes?.map((a) => a.name) ?? [];
161232
+ const errors = validateStateMachine(sm, knownActionUuids, ownerAttributes);
161233
+ if (errors.length > 0) return { errors };
161234
+ const result = await writeStateMachine(sm, packageName);
161235
+ if (!result.ok) {
161236
+ return { errors: [{ field: "_", message: "Failed to persist state machine" }] };
161237
+ }
161238
+ return sm;
161239
+ }
161240
+ /**
161241
+ * Update an existing state machine.
161242
+ */
161243
+ async update(uuid3, data) {
161244
+ const existing = await this.getByUuid(uuid3);
161245
+ if (!existing) return null;
161246
+ const updated = {
161247
+ ...existing,
161248
+ ...data,
161249
+ uuid: uuid3,
161250
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
161251
+ };
161252
+ const { packageModel, packageName } = await this.resolvePackageContext(updated.ownerRef);
161253
+ if (!packageModel || !packageName) {
161254
+ return { errors: [{ field: "ownerRef", message: `Entity '${updated.ownerRef}' not found in any package` }] };
161255
+ }
161256
+ const knownActionUuids = new Set(packageModel.ownership.actionByUuid.keys());
161257
+ const ownerEntity = packageModel.entities.find((e) => e.uuid === updated.ownerRef);
161258
+ const ownerAttributes = ownerEntity?.attributes?.map((a) => a.name) ?? [];
161259
+ const errors = validateStateMachine(updated, knownActionUuids, ownerAttributes);
161260
+ if (errors.length > 0) return { errors };
161261
+ const result = await writeStateMachine(updated, packageName);
161262
+ if (!result.ok) {
161263
+ return { errors: [{ field: "_", message: "Failed to persist state machine" }] };
161264
+ }
161265
+ return updated;
161266
+ }
161267
+ /**
161268
+ * Delete a state machine by UUID.
161269
+ */
161270
+ async delete(uuid3) {
161271
+ const result = await deleteStateMachine(uuid3);
161272
+ return result.ok;
161273
+ }
161274
+ /** Find the package and loaded model for the entity with the given UUID. */
161275
+ async resolvePackageContext(entityUuid) {
161276
+ const packages = await listPackages();
161277
+ for (const pkg of packages) {
161278
+ const model = await loadPackage(pkg);
161279
+ if (model.ownership.entityByUuid.has(entityUuid)) {
161280
+ return { packageModel: model, packageName: pkg };
161281
+ }
161282
+ }
161283
+ return { packageModel: null, packageName: null };
161284
+ }
161285
+ };
161286
+ var stateMachineService = new StateMachineService();
161287
+
161288
+ // backend/src/controllers/stateMachineController.ts
161289
+ init_logger();
161290
+ var listStateMachinesForEntity = /* @__PURE__ */ __name(async (req, res) => {
161291
+ try {
161292
+ const machines = await stateMachineService.list({ ownerRef: req.params.uuid });
161293
+ res.json({ message: "Success", data: machines });
161294
+ } catch (error48) {
161295
+ logger.error("Error listing state machines for entity", error48);
161296
+ res.status(500).json({ message: "Error listing state machines for entity", error: error48 });
161297
+ }
161298
+ }, "listStateMachinesForEntity");
161299
+ var getStateMachine = /* @__PURE__ */ __name(async (req, res) => {
161300
+ try {
161301
+ const sm = await stateMachineService.getByUuid(req.params.uuid);
161302
+ if (!sm) return res.status(404).json({ message: "State machine not found" });
161303
+ res.json({ message: "Success", data: sm });
161304
+ } catch (error48) {
161305
+ logger.error("Error fetching state machine", error48);
161306
+ res.status(500).json({ message: "Error fetching state machine", error: error48 });
161307
+ }
161308
+ }, "getStateMachine");
161309
+ var createStateMachine = /* @__PURE__ */ __name(async (req, res) => {
161310
+ try {
161311
+ const result = await stateMachineService.create(req.body);
161312
+ if ("errors" in result) {
161313
+ return res.status(400).json({ message: "Failed to create state machine", errors: result.errors });
161314
+ }
161315
+ res.status(201).json({ message: "State machine created successfully", data: result });
161316
+ } catch (error48) {
161317
+ logger.error("Error creating state machine", error48);
161318
+ res.status(500).json({ message: "Error creating state machine", error: error48 });
161319
+ }
161320
+ }, "createStateMachine");
161321
+ var updateStateMachine = /* @__PURE__ */ __name(async (req, res) => {
161322
+ try {
161323
+ const result = await stateMachineService.update(req.params.uuid, req.body);
161324
+ if (result === null) {
161325
+ return res.status(404).json({ message: "State machine not found" });
161326
+ }
161327
+ if ("errors" in result) {
161328
+ return res.status(400).json({ message: "Failed to update state machine", errors: result.errors });
161329
+ }
161330
+ res.json({ message: "State machine updated successfully", data: result });
161331
+ } catch (error48) {
161332
+ logger.error("Error updating state machine", error48);
161333
+ res.status(500).json({ message: "Error updating state machine", error: error48 });
161334
+ }
161335
+ }, "updateStateMachine");
161336
+ var deleteStateMachine2 = /* @__PURE__ */ __name(async (req, res) => {
161337
+ try {
161338
+ const ok2 = await stateMachineService.delete(req.params.uuid);
161339
+ if (!ok2) return res.status(404).json({ message: "State machine not found" });
161340
+ res.json({ message: "State machine deleted successfully" });
161341
+ } catch (error48) {
161342
+ logger.error("Error deleting state machine", error48);
161343
+ res.status(500).json({ message: "Error deleting state machine", error: error48 });
161344
+ }
161345
+ }, "deleteStateMachine");
161346
+
161347
+ // backend/src/routes/data-dictionary/state-machine.routes.ts
161348
+ var router15 = (0, import_express16.Router)();
161349
+ router15.get("/api/entities/:uuid/state-machines", listStateMachinesForEntity);
161350
+ router15.get("/api/state-machines/:uuid", getStateMachine);
161351
+ router15.post("/api/state-machines", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), createStateMachine);
161352
+ router15.put("/api/state-machines/:uuid", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), updateStateMachine);
161353
+ router15.delete("/api/state-machines/:uuid", authorizeJwt(["admin" /* ADMIN */]), deleteStateMachine2);
161354
+ var state_machine_routes_default = router15;
161355
+
161356
+ // backend/src/routes/data-dictionary/index.ts
161357
+ var router16 = (0, import_express17.Router)();
161358
+ router16.use(package_routes_default);
161359
+ router16.use(relationship_routes_default);
161360
+ router16.use(entity_routes_default);
161361
+ router16.use(stereotype_routes_default);
161362
+ router16.use(case_routes_default);
161363
+ router16.use(rule_routes_default);
161364
+ router16.use(integrity_routes_default);
161365
+ router16.use(model_metadata_routes_default);
161366
+ router16.use(dico_config_routes_default);
161367
+ router16.use(diff_routes_default);
161368
+ router16.use(import_export_routes_default);
161369
+ router16.use(publish_routes_default);
161370
+ router16.use(action_routes_default);
161371
+ router16.use(state_machine_routes_default);
161372
+ var data_dictionary_default = router16;
160610
161373
 
160611
161374
  // backend/src/routes/ai/index.ts
160612
- var import_express20 = __toESM(require_express2(), 1);
160613
- var router19 = (0, import_express20.Router)();
161375
+ var import_express22 = __toESM(require_express2(), 1);
161376
+ var router21 = (0, import_express22.Router)();
160614
161377
  (async () => {
160615
161378
  try {
160616
161379
  const chatRoutes = (await Promise.resolve().then(() => (init_chat_routes(), chat_routes_exports))).default;
160617
161380
  const conversationRoutes = (await Promise.resolve().then(() => (init_conversation_routes(), conversation_routes_exports))).default;
160618
161381
  const promptRoutes = (await Promise.resolve().then(() => (init_prompt_routes(), prompt_routes_exports))).default;
160619
161382
  const mcpRoutes = (await Promise.resolve().then(() => (init_mcp_routes(), mcp_routes_exports))).default;
160620
- router19.use(chatRoutes);
160621
- router19.use(conversationRoutes);
160622
- router19.use(promptRoutes);
160623
- router19.use(mcpRoutes);
161383
+ router21.use(chatRoutes);
161384
+ router21.use(conversationRoutes);
161385
+ router21.use(promptRoutes);
161386
+ router21.use(mcpRoutes);
160624
161387
  } catch {
160625
161388
  }
160626
161389
  })();
160627
- var ai_default = router19;
161390
+ var ai_default = router21;
160628
161391
 
160629
161392
  // backend/src/routes/search.routes.ts
160630
- var import_express21 = __toESM(require_express2(), 1);
160631
- var router20 = (0, import_express21.Router)();
160632
- router20.get("/api/entities/flat", getFlatEntitiesAndAttributes);
160633
- router20.get("/api/search", searchEntities);
160634
- var search_routes_default = router20;
161393
+ var import_express23 = __toESM(require_express2(), 1);
161394
+ var router22 = (0, import_express23.Router)();
161395
+ router22.get("/api/entities/flat", getFlatEntitiesAndAttributes);
161396
+ router22.get("/api/search", searchEntities);
161397
+ var search_routes_default = router22;
160635
161398
 
160636
161399
  // backend/src/routes/visualization.routes.ts
160637
- var import_express22 = __toESM(require_express2(), 1);
161400
+ var import_express24 = __toESM(require_express2(), 1);
160638
161401
 
160639
161402
  // backend/src/controllers/diagramController.ts
160640
161403
  init_diagramService();
@@ -160763,21 +161526,21 @@ var DiagramController = class {
160763
161526
  var diagramController = new DiagramController();
160764
161527
 
160765
161528
  // backend/src/routes/visualization.routes.ts
160766
- var router21 = (0, import_express22.Router)();
160767
- router21.get("/api/graph/:service", getGraphData);
160768
- router21.get("/api/entities/:uuid/impact", getImpactAnalysis);
160769
- router21.get("/api/entities/:uuid/lineage", getLineage);
160770
- router21.get("/api/diagrams", diagramController.listDiagramLayouts.bind(diagramController));
160771
- router21.post("/api/diagrams", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), diagramController.saveDiagramLayout.bind(diagramController));
160772
- router21.get("/api/diagrams/:id", diagramController.loadDiagramLayout.bind(diagramController));
160773
- router21.put("/api/diagrams/:id", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), diagramController.updateDiagramLayout.bind(diagramController));
160774
- router21.delete("/api/diagrams/:id", authorizeJwt(["admin" /* ADMIN */]), diagramController.deleteDiagramLayout.bind(diagramController));
160775
- var visualization_routes_default = router21;
161529
+ var router23 = (0, import_express24.Router)();
161530
+ router23.get("/api/graph/:service", getGraphData);
161531
+ router23.get("/api/entities/:uuid/impact", getImpactAnalysis);
161532
+ router23.get("/api/entities/:uuid/lineage", getLineage);
161533
+ router23.get("/api/diagrams", diagramController.listDiagramLayouts.bind(diagramController));
161534
+ router23.post("/api/diagrams", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), diagramController.saveDiagramLayout.bind(diagramController));
161535
+ router23.get("/api/diagrams/:id", diagramController.loadDiagramLayout.bind(diagramController));
161536
+ router23.put("/api/diagrams/:id", authorizeJwt(["admin" /* ADMIN */, "editor" /* EDITOR */]), diagramController.updateDiagramLayout.bind(diagramController));
161537
+ router23.delete("/api/diagrams/:id", authorizeJwt(["admin" /* ADMIN */]), diagramController.deleteDiagramLayout.bind(diagramController));
161538
+ var visualization_routes_default = router23;
160776
161539
 
160777
161540
  // backend/src/routes/status.routes.ts
160778
- var import_express23 = __toESM(require_express2(), 1);
160779
- var router22 = (0, import_express23.Router)();
160780
- router22.get("/api/status", (req, res) => {
161541
+ var import_express25 = __toESM(require_express2(), 1);
161542
+ var router24 = (0, import_express25.Router)();
161543
+ router24.get("/api/status", (req, res) => {
160781
161544
  const profile = process.env.PROFILE || "local";
160782
161545
  res.json({
160783
161546
  status: "operational",
@@ -160787,16 +161550,16 @@ router22.get("/api/status", (req, res) => {
160787
161550
  auth: profile === "local" ? "none" : "jwt"
160788
161551
  });
160789
161552
  });
160790
- var status_routes_default = router22;
161553
+ var status_routes_default = router24;
160791
161554
 
160792
161555
  // backend/src/routes/project.routes.ts
160793
- var import_express24 = __toESM(require_express2(), 1);
161556
+ var import_express26 = __toESM(require_express2(), 1);
160794
161557
  init_config();
160795
161558
  import fs2 from "fs";
160796
161559
  import path9 from "path";
160797
161560
  import os2 from "os";
160798
- var router23 = (0, import_express24.Router)();
160799
- router23.get("/api/filesystem/browse", (req, res) => {
161561
+ var router25 = (0, import_express26.Router)();
161562
+ router25.get("/api/filesystem/browse", (req, res) => {
160800
161563
  if (config.profile !== "local") {
160801
161564
  return res.status(403).json({ message: "Filesystem browsing is only available in local mode" });
160802
161565
  }
@@ -160821,7 +161584,7 @@ router23.get("/api/filesystem/browse", (req, res) => {
160821
161584
  res.status(500).json({ message: `Failed to read directory: ${e}` });
160822
161585
  }
160823
161586
  });
160824
- router23.get("/api/project", (req, res) => {
161587
+ router25.get("/api/project", (req, res) => {
160825
161588
  const dataDir = config.dataDir;
160826
161589
  const isOpen = fs2.existsSync(path9.join(dataDir, "dico.config.json"));
160827
161590
  res.json({
@@ -160833,7 +161596,7 @@ router23.get("/api/project", (req, res) => {
160833
161596
  }
160834
161597
  });
160835
161598
  });
160836
- router23.get("/api/project/status", async (_req, res) => {
161599
+ router25.get("/api/project/status", async (_req, res) => {
160837
161600
  try {
160838
161601
  const { versionService: versionService2 } = await Promise.resolve().then(() => (init_versionService(), versionService_exports));
160839
161602
  const status = await versionService2.getWorkingTreeStatus();
@@ -160842,7 +161605,7 @@ router23.get("/api/project/status", async (_req, res) => {
160842
161605
  res.status(500).json({ message: `Failed to read project status: ${e}` });
160843
161606
  }
160844
161607
  });
160845
- router23.post("/api/project/open", authorizeJwt(["admin" /* ADMIN */]), (req, res) => {
161608
+ router25.post("/api/project/open", authorizeJwt(["admin" /* ADMIN */]), (req, res) => {
160846
161609
  if (config.profile !== "local") {
160847
161610
  return res.status(403).json({ message: "Project switching is only available in local mode" });
160848
161611
  }
@@ -160865,7 +161628,7 @@ router23.post("/api/project/open", authorizeJwt(["admin" /* ADMIN */]), (req, re
160865
161628
  if (roots) roots.set("dictionaries", dataDir);
160866
161629
  res.json({ message: `Project opened: ${dataDir}`, data: { path: dataDir, name: path9.basename(path9.dirname(dataDir)) } });
160867
161630
  });
160868
- router23.post("/api/project/close", authorizeJwt(["admin" /* ADMIN */]), (req, res) => {
161631
+ router25.post("/api/project/close", authorizeJwt(["admin" /* ADMIN */]), (req, res) => {
160869
161632
  if (config.profile !== "local") {
160870
161633
  return res.status(403).json({ message: "Project switching is only available in local mode" });
160871
161634
  }
@@ -160876,7 +161639,7 @@ router23.post("/api/project/close", authorizeJwt(["admin" /* ADMIN */]), (req, r
160876
161639
  if (roots) roots.set("dictionaries", emptyDir);
160877
161640
  res.json({ message: "Project closed" });
160878
161641
  });
160879
- router23.post("/api/project/init", authorizeJwt(["admin" /* ADMIN */]), (req, res) => {
161642
+ router25.post("/api/project/init", authorizeJwt(["admin" /* ADMIN */]), (req, res) => {
160880
161643
  if (config.profile !== "local") {
160881
161644
  return res.status(403).json({ message: "Project initialization is only available in local mode" });
160882
161645
  }
@@ -160905,18 +161668,18 @@ router23.post("/api/project/init", authorizeJwt(["admin" /* ADMIN */]), (req, re
160905
161668
  res.status(500).json({ message: `Failed to initialize project: ${e}` });
160906
161669
  }
160907
161670
  });
160908
- var project_routes_default = router23;
161671
+ var project_routes_default = router25;
160909
161672
 
160910
161673
  // backend/src/routes/index.ts
160911
- var router24 = (0, import_express25.Router)();
160912
- router24.use(status_routes_default);
160913
- router24.use(auth_routes_default);
160914
- router24.use(search_routes_default);
160915
- router24.use(visualization_routes_default);
160916
- router24.use(project_routes_default);
160917
- router24.use(data_dictionary_default);
160918
- router24.use(ai_default);
160919
- var routes_default = router24;
161674
+ var router26 = (0, import_express27.Router)();
161675
+ router26.use(status_routes_default);
161676
+ router26.use(auth_routes_default);
161677
+ router26.use(search_routes_default);
161678
+ router26.use(visualization_routes_default);
161679
+ router26.use(project_routes_default);
161680
+ router26.use(data_dictionary_default);
161681
+ router26.use(ai_default);
161682
+ var routes_default = router26;
160920
161683
 
160921
161684
  // backend/src/server.ts
160922
161685
  init_logger();
@@ -161444,7 +162207,7 @@ __name(seedFromDisk, "seedFromDisk");
161444
162207
  // backend/src/server.ts
161445
162208
  init_mcpClientRegistry();
161446
162209
  import_dotenv2.default.config();
161447
- var app = (0, import_express29.default)();
162210
+ var app = (0, import_express31.default)();
161448
162211
  var port = config.port;
161449
162212
  app.use((0, import_cors2.default)());
161450
162213
  app.use((req, res, next) => {
@@ -161461,7 +162224,7 @@ app.use((req, res, next) => {
161461
162224
  });
161462
162225
  next();
161463
162226
  });
161464
- app.use(import_express29.default.json());
162227
+ app.use(import_express31.default.json());
161465
162228
  if (!config.isProduction) {
161466
162229
  app.get("/", (req, res) => {
161467
162230
  res.json({ message: "Welcome to the Data Dictionary Management System API" });
@@ -161554,8 +162317,8 @@ mountFrameworkRoutes().catch((err) => {
161554
162317
  logger.warn(`Failed to mount framework routes: ${err}`);
161555
162318
  });
161556
162319
  if (config.isProduction) {
161557
- const getServerDir = new Function("return new URL(import.meta.url).pathname");
161558
- const serverDir = path13.dirname(getServerDir());
162320
+ const serverUrl = eval("import.meta.url");
162321
+ const serverDir = path13.dirname(new URL(serverUrl).pathname);
161559
162322
  const candidates = [
161560
162323
  path13.join(serverDir, "..", "..", "frontend", "dist"),
161561
162324
  // npm package (server is at backend/src/)
@@ -161574,7 +162337,7 @@ if (config.isProduction) {
161574
162337
  }
161575
162338
  });
161576
162339
  if (publicDir) {
161577
- app.use(import_express29.default.static(publicDir));
162340
+ app.use(import_express31.default.static(publicDir));
161578
162341
  app.get("*", (req, res, next) => {
161579
162342
  if (req.path.startsWith("/api") || req.path.startsWith("/fs") || req.path.startsWith("/api-docs") || req.path.includes(".")) {
161580
162343
  return next();