@softacus-software/elwis-data-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +6 -0
  3. package/README.md +183 -0
  4. package/dist/app-scope.js +92 -0
  5. package/dist/app-scope.js.map +1 -0
  6. package/dist/artifact-read.js +114 -0
  7. package/dist/artifact-read.js.map +1 -0
  8. package/dist/audit.js +36 -0
  9. package/dist/audit.js.map +1 -0
  10. package/dist/builders/artifact-type-execute.js +100 -0
  11. package/dist/builders/artifact-type-execute.js.map +1 -0
  12. package/dist/builders/artifact-type-plan.js +139 -0
  13. package/dist/builders/artifact-type-plan.js.map +1 -0
  14. package/dist/builders/design-interview.js +246 -0
  15. package/dist/builders/design-interview.js.map +1 -0
  16. package/dist/builders/entity-lifecycle-execute.js +12 -0
  17. package/dist/builders/entity-lifecycle-execute.js.map +1 -0
  18. package/dist/builders/entity-lifecycle-plan.js +345 -0
  19. package/dist/builders/entity-lifecycle-plan.js.map +1 -0
  20. package/dist/builders/links-execute.js +50 -0
  21. package/dist/builders/links-execute.js.map +1 -0
  22. package/dist/builders/links-plan.js +62 -0
  23. package/dist/builders/links-plan.js.map +1 -0
  24. package/dist/builders/page-execute.js +38 -0
  25. package/dist/builders/page-execute.js.map +1 -0
  26. package/dist/builders/page-plan.js +148 -0
  27. package/dist/builders/page-plan.js.map +1 -0
  28. package/dist/builders/records-execute.js +24 -0
  29. package/dist/builders/records-execute.js.map +1 -0
  30. package/dist/builders/records-lifecycle-execute.js +30 -0
  31. package/dist/builders/records-lifecycle-execute.js.map +1 -0
  32. package/dist/builders/records-lifecycle-plan.js +199 -0
  33. package/dist/builders/records-lifecycle-plan.js.map +1 -0
  34. package/dist/builders/records-plan.js +74 -0
  35. package/dist/builders/records-plan.js.map +1 -0
  36. package/dist/builders/update-page-execute.js +38 -0
  37. package/dist/builders/update-page-execute.js.map +1 -0
  38. package/dist/builders/update-page-plan.js +137 -0
  39. package/dist/builders/update-page-plan.js.map +1 -0
  40. package/dist/builders/workflow-execute.js +11 -0
  41. package/dist/builders/workflow-execute.js.map +1 -0
  42. package/dist/builders/workflow-plan.js +115 -0
  43. package/dist/builders/workflow-plan.js.map +1 -0
  44. package/dist/cli/client-configs.js +98 -0
  45. package/dist/cli/client-configs.js.map +1 -0
  46. package/dist/cli/login.js +64 -0
  47. package/dist/cli/login.js.map +1 -0
  48. package/dist/cli/prompter.js +77 -0
  49. package/dist/cli/prompter.js.map +1 -0
  50. package/dist/cli/setup.js +214 -0
  51. package/dist/cli/setup.js.map +1 -0
  52. package/dist/config.js +38 -0
  53. package/dist/config.js.map +1 -0
  54. package/dist/confirm.js +22 -0
  55. package/dist/confirm.js.map +1 -0
  56. package/dist/elwis-api.js +96 -0
  57. package/dist/elwis-api.js.map +1 -0
  58. package/dist/http-client.js +142 -0
  59. package/dist/http-client.js.map +1 -0
  60. package/dist/index.js +20 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/jwt.js +18 -0
  63. package/dist/jwt.js.map +1 -0
  64. package/dist/prune.js +9 -0
  65. package/dist/prune.js.map +1 -0
  66. package/dist/resolve.js +71 -0
  67. package/dist/resolve.js.map +1 -0
  68. package/dist/result.js +16 -0
  69. package/dist/result.js.map +1 -0
  70. package/dist/server.js +82 -0
  71. package/dist/server.js.map +1 -0
  72. package/dist/session-store.js +51 -0
  73. package/dist/session-store.js.map +1 -0
  74. package/dist/tools/build-artifact-type.js +36 -0
  75. package/dist/tools/build-artifact-type.js.map +1 -0
  76. package/dist/tools/build-links.js +33 -0
  77. package/dist/tools/build-links.js.map +1 -0
  78. package/dist/tools/build-page.js +40 -0
  79. package/dist/tools/build-page.js.map +1 -0
  80. package/dist/tools/build-workflow.js +36 -0
  81. package/dist/tools/build-workflow.js.map +1 -0
  82. package/dist/tools/create-application.js +44 -0
  83. package/dist/tools/create-application.js.map +1 -0
  84. package/dist/tools/create-artifacts.js +33 -0
  85. package/dist/tools/create-artifacts.js.map +1 -0
  86. package/dist/tools/create-folder.js +55 -0
  87. package/dist/tools/create-folder.js.map +1 -0
  88. package/dist/tools/delete-artifacts.js +33 -0
  89. package/dist/tools/delete-artifacts.js.map +1 -0
  90. package/dist/tools/delete-entity.js +35 -0
  91. package/dist/tools/delete-entity.js.map +1 -0
  92. package/dist/tools/explain-access.js +40 -0
  93. package/dist/tools/explain-access.js.map +1 -0
  94. package/dist/tools/get-entity.js +36 -0
  95. package/dist/tools/get-entity.js.map +1 -0
  96. package/dist/tools/get-page.js +75 -0
  97. package/dist/tools/get-page.js.map +1 -0
  98. package/dist/tools/list-apps.js +22 -0
  99. package/dist/tools/list-apps.js.map +1 -0
  100. package/dist/tools/list-entities.js +43 -0
  101. package/dist/tools/list-entities.js.map +1 -0
  102. package/dist/tools/propose-page-design.js +17 -0
  103. package/dist/tools/propose-page-design.js.map +1 -0
  104. package/dist/tools/raw-api.js +132 -0
  105. package/dist/tools/raw-api.js.map +1 -0
  106. package/dist/tools/read-artifacts.js +197 -0
  107. package/dist/tools/read-artifacts.js.map +1 -0
  108. package/dist/tools/resolve-entity.js +22 -0
  109. package/dist/tools/resolve-entity.js.map +1 -0
  110. package/dist/tools/update-artifacts.js +33 -0
  111. package/dist/tools/update-artifacts.js.map +1 -0
  112. package/dist/tools/update-entity.js +41 -0
  113. package/dist/tools/update-entity.js.map +1 -0
  114. package/dist/tools/update-page.js +40 -0
  115. package/dist/tools/update-page.js.map +1 -0
  116. package/dist/write-gate.js +25 -0
  117. package/dist/write-gate.js.map +1 -0
  118. package/package.json +55 -0
@@ -0,0 +1,71 @@
1
+ import { ElwisHttpError } from './http-client.js';
2
+ const OID = /^[a-f0-9]{24}$/i;
3
+ export function IsObjectId(value) {
4
+ return OID.test(value);
5
+ }
6
+ export async function RequireApplicationId(api, ref) {
7
+ const appRef = ref.applicationId ?? ref.applicationName;
8
+ if (!appRef)
9
+ throw new Error('Provide applicationId or applicationName');
10
+ return ResolveApplicationId(api, appRef);
11
+ }
12
+ export class AmbiguityError extends Error {
13
+ candidates;
14
+ constructor(message, candidates) {
15
+ super(message);
16
+ this.name = 'AmbiguityError';
17
+ this.candidates = candidates;
18
+ }
19
+ }
20
+ export async function ResolveEntity(api, kind, applicationId, nameOrAlias) {
21
+ const scope = { applicationId: { $oid: applicationId } };
22
+ let rows;
23
+ try {
24
+ rows = await api.list(kind, { ...scope, $or: [{ name: nameOrAlias }, { alias: nameOrAlias }] });
25
+ }
26
+ catch (error) {
27
+ if (error instanceof ElwisHttpError && error.status === 400) {
28
+ rows = await api.list(kind, { ...scope, name: nameOrAlias });
29
+ }
30
+ else {
31
+ throw error;
32
+ }
33
+ }
34
+ return { matches: rows.map(r => ({ id: r.id, name: r.name, alias: r.alias, kind })) };
35
+ }
36
+ export async function ResolveOneId(api, kind, applicationId, ref) {
37
+ if (IsObjectId(ref))
38
+ return ref;
39
+ const { matches } = await ResolveEntity(api, kind, applicationId, ref);
40
+ if (matches.length === 1)
41
+ return matches[0].id;
42
+ if (matches.length === 0)
43
+ throw new AmbiguityError(`No active ${kind} named "${ref}" in the application`, []);
44
+ throw new AmbiguityError(`Multiple ${kind} entries named "${ref}" in the application; pass an explicit id`, matches.map(m => ({ id: m.id, name: m.name })));
45
+ }
46
+ export async function ResolveArtifactByRef(api, nameAttributeId, artifactTypeId, ref, label) {
47
+ if (IsObjectId(ref)) {
48
+ const artifact = await api.getOne('artifact', ref);
49
+ return { id: ref, name: artifact.attributes?.[nameAttributeId]?.value ?? ref };
50
+ }
51
+ const filter = { [`attributes.${nameAttributeId}.value`]: ref };
52
+ if (artifactTypeId)
53
+ filter.artifactTypeId = { $oid: artifactTypeId };
54
+ const page = await api.listRecords('artifact', filter, { limit: 2 });
55
+ if (page.data.length === 1)
56
+ return { id: page.data[0].id, name: ref };
57
+ if (page.data.length === 0)
58
+ throw new Error(`No ${label} artifact named "${ref}"${artifactTypeId ? ' in the restricted artifact type' : ''}`);
59
+ throw new AmbiguityError(`Multiple ${label} artifacts named "${ref}"; pass an explicit id`, page.data.map(a => ({ id: a.id, name: ref })));
60
+ }
61
+ export async function ResolveApplicationId(api, applicationIdOrName) {
62
+ if (IsObjectId(applicationIdOrName))
63
+ return applicationIdOrName;
64
+ const rows = await api.list('application', { name: applicationIdOrName });
65
+ if (rows.length === 1)
66
+ return rows[0].id;
67
+ if (rows.length === 0)
68
+ throw new AmbiguityError(`No active application named "${applicationIdOrName}"`, []);
69
+ throw new AmbiguityError(`Multiple active applications named "${applicationIdOrName}"; pass an explicit applicationId`, rows.map(r => ({ id: r.id, name: r.name })));
70
+ }
71
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
package/dist/result.js ADDED
@@ -0,0 +1,16 @@
1
+ import { AmbiguityError } from './resolve.js';
2
+ import { ElwisHttpError } from './http-client.js';
3
+ export function Text(value, isError = false) {
4
+ const result = { content: [{ type: 'text', text: JSON.stringify(value, null, 2) }] };
5
+ if (isError)
6
+ result.isError = true;
7
+ return result;
8
+ }
9
+ export function ErrorResult(error) {
10
+ if (error instanceof AmbiguityError)
11
+ return Text({ status: 'error', error: error.message, candidates: error.candidates }, true);
12
+ if (error instanceof ElwisHttpError)
13
+ return Text({ status: 'error', error: error.message, status_code: error.status, detail: error.body }, true);
14
+ return Text({ status: 'error', error: error.message }, true);
15
+ }
16
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,UAAU,IAAI,CAAC,KAAc,EAAE,OAAO,GAAG,KAAK;IAClD,MAAM,MAAM,GAAqE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACvJ,IAAI,OAAO;QAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACnC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,cAAc;QAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAC;IAChI,IAAI,KAAK,YAAY,cAAc;QAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IACjJ,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;AAC1E,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,82 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { LoadConfig } from './config.js';
3
+ import { ElwisHttpClient } from './http-client.js';
4
+ import { LoadSession, SaveSession } from './session-store.js';
5
+ import { ElwisApi } from './elwis-api.js';
6
+ import { AppScope } from './app-scope.js';
7
+ import { RegisterExplainAccess } from './tools/explain-access.js';
8
+ import { RegisterListApps } from './tools/list-apps.js';
9
+ import { RegisterListEntities } from './tools/list-entities.js';
10
+ import { RegisterReadArtifacts } from './tools/read-artifacts.js';
11
+ import { RegisterResolveEntity } from './tools/resolve-entity.js';
12
+ import { RegisterProposePageDesign } from './tools/propose-page-design.js';
13
+ import { RegisterBuildArtifactType } from './tools/build-artifact-type.js';
14
+ import { RegisterBuildPage } from './tools/build-page.js';
15
+ import { RegisterGetPage } from './tools/get-page.js';
16
+ import { RegisterUpdatePage } from './tools/update-page.js';
17
+ import { RegisterBuildWorkflow } from './tools/build-workflow.js';
18
+ import { RegisterCreateArtifacts } from './tools/create-artifacts.js';
19
+ import { RegisterUpdateArtifacts } from './tools/update-artifacts.js';
20
+ import { RegisterDeleteArtifacts } from './tools/delete-artifacts.js';
21
+ import { RegisterUpdateEntity } from './tools/update-entity.js';
22
+ import { RegisterDeleteEntity } from './tools/delete-entity.js';
23
+ import { RegisterGetEntity } from './tools/get-entity.js';
24
+ import { RegisterCreateApplication } from './tools/create-application.js';
25
+ import { RegisterCreateFolder } from './tools/create-folder.js';
26
+ import { RegisterBuildLinks } from './tools/build-links.js';
27
+ import { RegisterRawApi } from './tools/raw-api.js';
28
+ export function BuildServer() {
29
+ const server = new McpServer({ name: 'elwis-data-mcp', version: '0.1.0' });
30
+ const cfg = LoadConfig();
31
+ const client = new ElwisHttpClient(cfg, cfg.authMode === 'session'
32
+ ? {
33
+ refresh: true,
34
+ reload: () => LoadSession(cfg.baseUrl)?.token ?? null,
35
+ persist: (token) => {
36
+ const existing = LoadSession(cfg.baseUrl);
37
+ SaveSession({
38
+ host: cfg.baseUrl,
39
+ token,
40
+ tenantId: existing?.tenantId ?? null,
41
+ email: existing?.email ?? null,
42
+ updatedAt: new Date().toISOString(),
43
+ });
44
+ },
45
+ }
46
+ : {});
47
+ const api = new ElwisApi(client, cfg.expectedTenant);
48
+ const scope = new AppScope(api, cfg.allowedApps, cfg.expectedTenant);
49
+ if (!cfg.expectedTenant) {
50
+ process.stderr.write('WARNING: no ELWIS_TENANT set, data tools are disabled until a tenant is configured (explain_elwis_access shows the id, or re-run setup)\n');
51
+ }
52
+ if (cfg.writeEnabled && !cfg.requireConfirmation) {
53
+ process.stderr.write('WARNING: writes are enabled without per-plan confirmation (ELWIS_REQUIRE_CONFIRMATION=false), intended for scripted automation only\n');
54
+ }
55
+ RegisterExplainAccess(server, cfg, api, scope);
56
+ RegisterListApps(server, api, scope);
57
+ RegisterListEntities(server, api, scope);
58
+ RegisterReadArtifacts(server, api, scope);
59
+ RegisterResolveEntity(server, api, scope);
60
+ RegisterGetPage(server, api, scope);
61
+ RegisterProposePageDesign(server);
62
+ if (cfg.buildersEnabled) {
63
+ RegisterBuildArtifactType(server, api, cfg, scope);
64
+ RegisterBuildPage(server, api, cfg, scope);
65
+ RegisterUpdatePage(server, api, cfg, scope);
66
+ RegisterBuildWorkflow(server, api, cfg, scope);
67
+ RegisterCreateArtifacts(server, api, cfg, scope);
68
+ RegisterUpdateArtifacts(server, api, cfg, scope);
69
+ RegisterDeleteArtifacts(server, api, cfg, scope);
70
+ RegisterUpdateEntity(server, api, cfg, scope);
71
+ RegisterDeleteEntity(server, api, cfg, scope);
72
+ RegisterGetEntity(server, api, scope);
73
+ RegisterCreateApplication(server, api, cfg, scope);
74
+ RegisterCreateFolder(server, api, cfg, scope);
75
+ RegisterBuildLinks(server, api, cfg, scope);
76
+ }
77
+ else {
78
+ RegisterRawApi(server, api, cfg, scope);
79
+ }
80
+ return server;
81
+ }
82
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { chmodSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+ export function DefaultSessionsDir() {
6
+ return process.env.ELWIS_SESSIONS_DIR?.trim() || join(homedir(), '.elwis', 'sessions');
7
+ }
8
+ export function SessionPath(host, dir = DefaultSessionsDir()) {
9
+ const key = createHash('sha256').update(host.replace(/\/$/, '')).digest('hex').slice(0, 12);
10
+ return join(dir, `${key}.json`);
11
+ }
12
+ export function LoadSession(host, dir) {
13
+ try {
14
+ const record = JSON.parse(readFileSync(SessionPath(host, dir), 'utf8'));
15
+ return typeof record.token === 'string' && record.token.length > 0 ? record : null;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ export function ListSessions(dir = DefaultSessionsDir()) {
22
+ try {
23
+ return readdirSync(dir)
24
+ .filter(name => name.endsWith('.json'))
25
+ .map(name => {
26
+ try {
27
+ return JSON.parse(readFileSync(join(dir, name), 'utf8'));
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ })
33
+ .filter((record) => record !== null && typeof record.token === 'string');
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ }
39
+ export function SaveSession(record, dir) {
40
+ const path = SessionPath(record.host, dir);
41
+ const parent = dirname(path);
42
+ mkdirSync(parent, { recursive: true, mode: 0o700 });
43
+ chmodSync(parent, 0o700);
44
+ writeFileSync(path, `${JSON.stringify(record, null, 2)}\n`, { mode: 0o600 });
45
+ chmodSync(path, 0o600);
46
+ return path;
47
+ }
48
+ export function DeleteSession(host, dir) {
49
+ rmSync(SessionPath(host, dir), { force: true });
50
+ }
51
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { BuildArtifactTypePlan, BuildArtifactTypeInput } from '../builders/artifact-type-plan.js';
2
+ import { ExecuteArtifactTypePlan } from '../builders/artifact-type-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterBuildArtifactType(server, api, cfg, scope) {
9
+ server.registerTool('build_artifact_type', {
10
+ description: 'Build an ELWIS artifact type with its attributes and data types in one call. Creates missing data types and attributes, reuses existing ones by name, and assembles the artifact type. Per attribute you may pass: description, icon, uri, private (true for a private attribute); multipleValuesOrdering (ASC/DESC/NONE) for list-valued attributes; minimum and maximum for a BOUNDED kind; units [{name, symbol, base}] for a CUSTOM-UNIT kind; siUnit (one of TIME, LENGTH, MASS, AREA, VOLUME, SPEED) for a UNIT kind; counterFormat and counterNextValue for a COUNTER kind (both default sensibly); fileArtifactTypeId to override the file reference for HTML/FILE base types; and the per-attribute placement fields initialValue, help, regexValidator, regexFlags, equation, equationRecalculate, entityFilter. At the artifact-type level you may pass: color, delimiter, isLoggingDisabled, inheritableAcl, defaultIsHeading; defaultFolder and defaultPage (id or name, resolved within the application); defaultWidgets {artifactWidgetTemplateId, cardWidgetTemplateId}; avrMapper and avrTriggers (CREATE/UPDATE/DEMAND); and preferredArtifactTypes (ids or names, only valid when format is MODULE). Use dryRun to preview without writing.',
11
+ inputSchema: BuildArtifactTypeInput.shape,
12
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
13
+ }, async (raw) => {
14
+ try {
15
+ const applicationId = await RequireApplicationId(api, raw);
16
+ await scope.assertAllowed(applicationId);
17
+ const plan = await BuildArtifactTypePlan(api, { ...raw, applicationId });
18
+ if (plan.reuse) {
19
+ return Text({ status: 'ok', artifactType: plan.reuse, createdDataTypes: [], createdAttributes: [], reused: [{ ...plan.reuse, kind: 'artifact-type', note: 'An artifact type with this name already exists in the application; it was returned unchanged and not updated.' }] });
20
+ }
21
+ const token = PlanToken(cfg, 'build_artifact_type', plan);
22
+ if (raw.dryRun)
23
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
24
+ AssertWriteEnabled(cfg);
25
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
26
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
27
+ }
28
+ const report = await AuditedExecute(cfg, scope, 'build_artifact_type', token, () => ExecuteArtifactTypePlan(api, plan), (r) => ({ artifactType: r.artifactType, createdDataTypes: r.createdDataTypes.length, createdAttributes: r.createdAttributes.length }));
29
+ return Text({ status: 'ok', ...report });
30
+ }
31
+ catch (e) {
32
+ return ErrorResult(e);
33
+ }
34
+ });
35
+ }
36
+ //# sourceMappingURL=build-artifact-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-artifact-type.js","sourceRoot":"","sources":["../../src/tools/build-artifact-type.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { BuildLinksInput, BuildLinksPlan } from '../builders/links-plan.js';
2
+ import { ExecuteLinksPlan } from '../builders/links-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterBuildLinks(server, api, cfg, scope) {
9
+ server.registerTool('build_links', {
10
+ description: 'Create an ELWIS link type and link instances between records in one call. An existing active link type with the given name is reused; otherwise it is created, which requires sourceArtifactType and destinationArtifactType (restriction of what can be linked). Link instances are passed as source/destination artifact names (resolved within the restricted artifact types) or ids; pairs that are already linked are skipped, so the call is safe to repeat. Cardinality defaults to unrestricted on both sides. Use dryRun to preview the resolved plan without writing.',
11
+ inputSchema: BuildLinksInput.shape,
12
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
13
+ }, async (raw) => {
14
+ try {
15
+ const applicationId = await RequireApplicationId(api, raw);
16
+ await scope.assertAllowed(applicationId);
17
+ const plan = await BuildLinksPlan(api, raw, applicationId);
18
+ const token = PlanToken(cfg, 'build_links', plan);
19
+ if (raw.dryRun)
20
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
21
+ AssertWriteEnabled(cfg);
22
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
23
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
24
+ }
25
+ const report = await AuditedExecute(cfg, scope, 'build_links', token, () => ExecuteLinksPlan(api, plan), (r) => ({ linkType: r.linkType, createdLinks: r.createdLinks.length, skippedExisting: r.skippedExisting.length }));
26
+ return Text({ status: 'ok', ...report });
27
+ }
28
+ catch (e) {
29
+ return ErrorResult(e);
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=build-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-links.js","sourceRoot":"","sources":["../../src/tools/build-links.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,GAAa,EAAE,GAAgB,EAAE,KAAe;IACpG,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,WAAW,EAAE,ijBAAijB;QAC9jB,WAAW,EAAE,eAAe,CAAC,KAAK;QAClC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACxG,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3H,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAClH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC5N,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { BuildPagePlan, BuildPageInput, ADVERTISED_WIDGET_CODES } from '../builders/page-plan.js';
2
+ import { ExecutePagePlan } from '../builders/page-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterBuildPage(server, api, cfg, scope) {
9
+ server.registerTool('build_page', {
10
+ description: `Build an ELWIS page with its widgets in one call. Provide the full section/row/block/part nesting; put each widget inline at the part level as { code, value } (the server creates the widget and wires its id into the page). Supported widget codes: ${ADVERTISED_WIDGET_CODES.join(', ')}. Row layout is an array of numeric strings summing to 12. Section styles, if given, must be shaped { outerContainer, innerContainer }.
11
+
12
+ DATA FIRST: when the page shows or manages records, bind a native LIST-NEW widget to the artifact type, do NOT render record values as HTML text; TEXT widgets are for prose, headers and layout only. A live table needs only { code: 'LIST-NEW', value: { model: { selected: { applications: [{ id: <appId> }], artifactTypes: [{ id: <artifactTypeId> }], columns: [{ key: <attributeId> }, ...] } } } }, the server fills the full working skeleton (listType, state.columnOrder, per-column settings, table defaults) and your values win on conflict. columns is effectively required: a LIST-NEW without columns renders an empty "No records found" table even when records exist, so always pass at least the Name system attribute as a column. The table then always shows the current records: editing the data changes the page with no rebuild. Resolve attribute ids for columns via list_elwis_entities (kind attribute); system attribute ids like Name come from explain_elwis_access systemAttributes. An HTML table or list of data inside a TEXT widget is always wrong, if the values exist (or should exist) as records, the LIST-NEW widget shows them; never duplicate them into TEXT. A CHART widget takes { model: { settings: { chartType: 'pie' | 'doughnut' }, selected: { artifactType: { id }, groupByAttributeId, totalByAttributeId } } }.
13
+
14
+ Reference a widget created earlier in the same page by its part position with a $widgetIndex placeholder. A page with the same name is returned unchanged, use update_elwis_page to change an existing page. For a page requested in plain language, run the propose_page_design interview first and build only from a brief it marked ready, never build on a guess. Use dryRun to preview without writing and show the user the plan before the real run.`,
15
+ inputSchema: BuildPageInput.shape,
16
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
17
+ }, async (raw) => {
18
+ try {
19
+ const applicationId = await RequireApplicationId(api, raw);
20
+ await scope.assertAllowed(applicationId);
21
+ const plan = await BuildPagePlan(api, { ...raw, applicationId });
22
+ if (plan.reuse) {
23
+ return Text({ status: 'ok', page: plan.reuse, widgets: [], reused: [{ ...plan.reuse, kind: 'page', note: 'A page with this name already exists in the application; it was returned unchanged and not updated.' }] });
24
+ }
25
+ const token = PlanToken(cfg, 'build_page', plan);
26
+ if (raw.dryRun)
27
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
28
+ AssertWriteEnabled(cfg);
29
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
30
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
31
+ }
32
+ const report = await AuditedExecute(cfg, scope, 'build_page', token, () => ExecutePagePlan(api, plan), (r) => ({ page: r.page, widgets: r.widgets.length }));
33
+ return Text({ status: 'ok', ...report });
34
+ }
35
+ catch (e) {
36
+ return ErrorResult(e);
37
+ }
38
+ });
39
+ }
40
+ //# sourceMappingURL=build-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-page.js","sourceRoot":"","sources":["../../src/tools/build-page.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,GAAa,EAAE,GAAgB,EAAE,KAAe;IACnG,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,WAAW,EAAE,0PAA0P,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;4bAI6I;QACtb,WAAW,EAAE,cAAc,CAAC,KAAK;QACjC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACxG,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;YACjE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qGAAqG,EAAE,CAAC,EAAE,CAAC,CAAC;YACvN,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;YACjD,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3H,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAClH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC7J,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { BuildWorkflowPlan, BuildWorkflowInput } from '../builders/workflow-plan.js';
2
+ import { ExecuteWorkflowPlan } from '../builders/workflow-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterBuildWorkflow(server, api, cfg, scope) {
9
+ server.registerTool('build_workflow', {
10
+ description: `Build an ELWIS workflow in one call. type is "be" (server-side automation on data changes) or "fe" (client-side automation on UI events). ownerType scopes the workflow to what it reacts to (data-type, attribute, artifact-type, artifact, link-type, link, widget, page, template, or CUSTOM). The owner is the container the workflow belongs to, which differs by ownerType: for data-type, attribute, artifact-type and link-type the owner is the application itself, so leave owner unset and it defaults to applicationId/applicationName; for artifact the owner is its artifact type, for link the owner is its link type, and for page and widget the owner is that page or widget, pass these by name (resolved within applicationId/applicationName) or as an id; for template pass an explicit id; CUSTOM workflows take no owner. usedIn defaults to the owner and can be left unset. Provide triggers and actions as full objects with their type and settings, the server passes them through and the backend validates them. Common trigger types: OWNER_CREATE, OWNER_UPDATE, OWNER_DELETE, ATTRIBUTE_VALUE_CHANGE, PAGE_LOAD, BUTTON_CLICK, MANUAL. Common action types: SET_VALUE, CREATE_LINK, CREATE_ARTIFACTS, UPDATE_ARTIFACTS, DELETE_ARTIFACTS, SEND_EMAIL, NAVIGATE_TO_PAGE, EXEC_CUSTOM_JAVASCRIPT. A SET_VALUE action is shaped { type: 'SET_VALUE', attributeId, actionSettings: { value: { isDynamic, value }, operation: { isDynamic, value } } }: the target attribute is the action's top-level attributeId, the per-type settings live under actionSettings, each setting is wrapped as { isDynamic, value } (set isDynamic true when value is an equation or reference rather than a literal), and operation is one of add, remove, replace. Other trigger and action types follow the same { type, ...top-level target ids, actionSettings } pattern and pass through untouched, so any documented field is accepted. Every trigger and action needs a settings object (triggerSettings / actionSettings); the server fills in an empty one when you omit it. Use dryRun to preview without writing.`,
11
+ inputSchema: BuildWorkflowInput.shape,
12
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
13
+ }, async (raw) => {
14
+ try {
15
+ const applicationId = await RequireApplicationId(api, raw);
16
+ await scope.assertAllowed(applicationId);
17
+ const plan = await BuildWorkflowPlan(api, { ...raw, applicationId });
18
+ if (plan.reuse) {
19
+ return Text({ status: 'ok', workflow: plan.reuse, reused: [{ ...plan.reuse, kind: 'workflow', note: 'A workflow with this name already exists for this owner; it was returned unchanged and not updated.' }] });
20
+ }
21
+ const token = PlanToken(cfg, 'build_workflow', plan);
22
+ if (raw.dryRun)
23
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
24
+ AssertWriteEnabled(cfg);
25
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
26
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
27
+ }
28
+ const report = await AuditedExecute(cfg, scope, 'build_workflow', token, () => ExecuteWorkflowPlan(api, plan), (r) => ({ workflow: r.workflow }));
29
+ return Text({ status: 'ok', ...report });
30
+ }
31
+ catch (e) {
32
+ return ErrorResult(e);
33
+ }
34
+ });
35
+ }
36
+ //# sourceMappingURL=build-workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-workflow.js","sourceRoot":"","sources":["../../src/tools/build-workflow.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,GAAa,EAAE,GAAgB,EAAE,KAAe;IACvG,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EAAE,6gEAA6gE;QAC1hE,WAAW,EAAE,kBAAkB,CAAC,KAAK;QACrC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;KACxG,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;YACrE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,qGAAqG,EAAE,CAAC,EAAE,CAAC,CAAC;YAClN,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;YACrD,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3H,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAClH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAClJ,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ import { AppScopeError } from '../app-scope.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { Text, ErrorResult } from '../result.js';
7
+ const CreateApplicationInput = z.object({
8
+ name: z.string().min(1).max(50),
9
+ description: z.string().max(1000).optional(),
10
+ dryRun: z.boolean().default(false).describe('Preview without creating anything'),
11
+ confirm: z.string().optional().describe('Confirmation token from the previous preview of this exact plan; required to execute when confirmation mode is on'),
12
+ });
13
+ export function RegisterCreateApplication(server, api, cfg, scope) {
14
+ server.registerTool('create_elwis_application', {
15
+ description: 'Create a new ELWIS application, the top-level container that data types, attributes, artifact types, link types, pages, and records live in. Use this when the user wants to start a fresh workspace ("make me an app for the warehouse"), then build inside it with build_artifact_type and the other tools. An active application with the same name is an error suggesting reuse instead of a duplicate. Not available on connections restricted to an application allowlist, a new application would be outside the allowlist and unusable; the allowlist owner has to create it and add its id to ELWIS_ALLOWED_APPS.',
16
+ inputSchema: CreateApplicationInput.shape,
17
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
18
+ }, async (raw) => {
19
+ try {
20
+ await scope.assertTenant();
21
+ if (scope.restricted) {
22
+ throw new AppScopeError('creating applications, this connection is limited to an application allowlist, and a new application would be outside it');
23
+ }
24
+ const existing = await api.list('application', { name: raw.name });
25
+ if (existing.length) {
26
+ throw new Error(`An active application named "${raw.name}" already exists (${existing[0].id}); use it instead of creating a duplicate, or pick another name`);
27
+ }
28
+ const plan = { name: raw.name, description: raw.description ?? '' };
29
+ const token = PlanToken(cfg, 'create_elwis_application', plan);
30
+ if (raw.dryRun)
31
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
32
+ AssertWriteEnabled(cfg);
33
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
34
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
35
+ }
36
+ const created = await AuditedExecute(cfg, scope, 'create_elwis_application', token, () => api.create('application', plan), (r) => ({ created: r.id, name: r.name }));
37
+ return Text({ status: 'ok', application: created, note: 'Build inside it with build_artifact_type, create_elwis_artifacts, and build_page.' });
38
+ }
39
+ catch (e) {
40
+ return ErrorResult(e);
41
+ }
42
+ });
43
+ }
44
+ //# sourceMappingURL=create-application.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-application.js","sourceRoot":"","sources":["../../src/tools/create-application.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { CreateArtifactsInput, BuildRecordsPlan } from '../builders/records-plan.js';
2
+ import { ExecuteRecordsPlan } from '../builders/records-execute.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ export function RegisterCreateArtifacts(server, api, cfg, scope) {
9
+ server.registerTool('create_elwis_artifacts', {
10
+ description: 'Create data records (artifacts) of an existing artifact type in one batch call (up to 50). Pass attribute values by attribute name; the server resolves names to ids and satisfies the backend contract that every attribute of the type must receive a value: the system Name attribute is filled from each record\'s name, the system Sequence attribute is auto-generated when not provided, and unspecified attributes default to an empty string. Values are coerced to strings (the backend stores all attribute values as strings). A value key that does not match an attribute assigned to the type is an error listing the assignable attribute names. Use dryRun to preview the resolved payloads without writing.',
11
+ inputSchema: CreateArtifactsInput.shape,
12
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
13
+ }, async (raw) => {
14
+ try {
15
+ const applicationId = await RequireApplicationId(api, raw);
16
+ await scope.assertAllowed(applicationId);
17
+ const plan = await BuildRecordsPlan(api, raw, applicationId);
18
+ const token = PlanToken(cfg, 'create_elwis_artifacts', plan);
19
+ if (raw.dryRun)
20
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
21
+ AssertWriteEnabled(cfg);
22
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
23
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
24
+ }
25
+ const report = await AuditedExecute(cfg, scope, 'create_elwis_artifacts', token, () => ExecuteRecordsPlan(api, plan), (r) => ({ artifactType: r.artifactType, created: r.created }));
26
+ return Text({ status: 'ok', ...report });
27
+ }
28
+ catch (e) {
29
+ return ErrorResult(e);
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=create-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-artifacts.js","sourceRoot":"","sources":["../../src/tools/create-artifacts.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,GAAa,EAAE,GAAgB,EAAE,KAAe;IACzG,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;QACE,WAAW,EAAE,+rBAA+rB;QAC5sB,WAAW,EAAE,oBAAoB,CAAC,KAAK;QACvC,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;KACzG,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;YAC7D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,wBAAwB,EAAE,IAAI,CAAC,CAAC;YAC7D,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3H,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7D,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;YAClH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACrL,OAAO,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ import { AppRootFolder, ResolveFolder, FolderFullPath } from '../builders/entity-lifecycle-plan.js';
3
+ import { AssertWriteEnabled, CheckConfirmation, CONFIRMATION_MESSAGE, DRY_RUN_MESSAGE } from '../write-gate.js';
4
+ import { PlanToken } from '../confirm.js';
5
+ import { AuditedExecute } from '../audit.js';
6
+ import { RequireApplicationId } from '../resolve.js';
7
+ import { Text, ErrorResult } from '../result.js';
8
+ const CreateFolderInput = z.object({
9
+ applicationId: z.string().optional(),
10
+ applicationName: z.string().optional(),
11
+ name: z.string().min(1).max(50),
12
+ parent: z.string().optional().describe('Parent folder name, full path (like "Projects/2026"), or id; defaults to the application root folder'),
13
+ dryRun: z.boolean().default(false).describe('Preview without creating anything'),
14
+ confirm: z.string().optional().describe('Confirmation token from the previous preview of this exact plan; required to execute when confirmation mode is on'),
15
+ });
16
+ export function RegisterCreateFolder(server, api, cfg, scope) {
17
+ server.registerTool('create_elwis_folder', {
18
+ description: 'Create a folder in an application\'s folder tree, for organizing records ("put invoices in their own folder"). The parent is a folder name, full path, or id; without it the folder lands directly under the application root. A sibling with the same name is an error suggesting reuse. Move records into it by updating them, and reorganize later with update_elwis_entity (rename, parentFolderId to move, folderSequence to reorder) or delete_elwis_entity.',
19
+ inputSchema: CreateFolderInput.shape,
20
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
21
+ }, async (raw) => {
22
+ try {
23
+ const applicationId = await RequireApplicationId(api, raw);
24
+ await scope.assertAllowed(applicationId);
25
+ const root = await AppRootFolder(api, applicationId);
26
+ const parent = raw.parent
27
+ ? await ResolveFolder(api, applicationId, raw.parent)
28
+ : await api.getOne('folder', root.id);
29
+ if (parent.deleted)
30
+ throw new Error('The parent folder is deleted; pick an active folder');
31
+ const parentFullPath = FolderFullPath(parent);
32
+ if (String(parent.id) !== root.id && !parentFullPath.startsWith(root.fullPath)) {
33
+ throw new Error(`The parent folder "${parentFullPath}" lives outside this application's folder tree (${root.fullPath})`);
34
+ }
35
+ const siblings = await api.list('folder', { parentFolderId: { $oid: String(parent.id) }, name: raw.name }, 1);
36
+ if (siblings.length) {
37
+ throw new Error(`A folder named "${raw.name}" already exists at ${parentFullPath} (${siblings[0].id}); use it instead of creating a duplicate`);
38
+ }
39
+ const plan = { name: raw.name, parentFolderId: String(parent.id), path: `${parentFullPath}${raw.name}/` };
40
+ const token = PlanToken(cfg, 'create_elwis_folder', plan);
41
+ if (raw.dryRun)
42
+ return Text({ status: 'dry-run', dryRun: true, confirmationToken: token, message: DRY_RUN_MESSAGE, plan });
43
+ AssertWriteEnabled(cfg);
44
+ if (CheckConfirmation(cfg, token, raw.confirm) === 'pending') {
45
+ return Text({ status: 'confirmation-required', confirmationToken: token, plan, message: CONFIRMATION_MESSAGE });
46
+ }
47
+ const created = await AuditedExecute(cfg, scope, 'create_elwis_folder', token, () => api.create('folder', { name: plan.name, parentFolderId: plan.parentFolderId }), (r) => ({ created: r.id, path: plan.path }));
48
+ return Text({ status: 'ok', folder: { id: created.id, path: plan.path } });
49
+ }
50
+ catch (e) {
51
+ return ErrorResult(e);
52
+ }
53
+ });
54
+ }
55
+ //# sourceMappingURL=create-folder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-folder.js","sourceRoot":"","sources":["../../src/tools/create-folder.ts"],"names":[],"mappings":"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"}